示例#1
0
void WriteTextInfoFrame(FILE *outf,const char *frameid,const char *string)
{
	size_t size=0;

//Validate input parameters
	assert_wrapper((outf != NULL) && (frameid != NULL) && (string != NULL));
	if(strlen(frameid) != 4)
	{
		printf("Error: Attempted export of invalid frame ID \"%s\"\nAborting",frameid);
		exit_wrapper(1);
	}

	if(Lyrics.verbose >= 2)	printf("\tWriting frame \"%s\"\n",frameid);

	size=strlen(string)+1;		//The frame payload size is the string and the encoding byte

//Write ID3 frame header
	fwrite_err(frameid,4,1,outf);			//Write frame ID
	WriteDWORDBE(outf,(unsigned long)size);	//Write frame size (total frame size-header size) in Big Endian format
	fputc_err(0xC0,outf);					//Write first flag byte (preserve frame for both tag and file alteration)
	fputc_err(0,outf);						//Write second flag byte (no compression, encryption or grouping identity)

//Write frame data
	fputc_err(0,outf);					//Write ASCII encoding
	fwrite_err(string,(size_t)size-1,1,outf);	//Write the string
}
示例#2
0
void *toasim_write_corrections(toasim_corrections_t* corr, toasim_header_t* header, FILE* file){
	char key[8];
	strcpy(key,"CORR");
	fwrite_err(key,4,1,file);
	fwrite_err(&corr->a0,8,1,file);
	fwrite_err(&corr->a1,8,1,file);
	fwrite_err(&corr->a2,8,1,file);
	fwrite_err(corr->offsets,sizeof(double), header->ntoa, file);
	if(header->rparam_len){
		fwrite_err(corr->params,1,header->rparam_len,file);
	}

}
示例#3
0
/**
 *
 * Takes a toasim header, and a filename.
 * Returns the newly created file as a filepointer.
 * Does not close the file
 */
FILE *toasim_write_header(toasim_header_t *toasim_header, char* filename){
	FILE *file;
	file = fopen(filename,"w");
	// If the file cannot be opened return null.
	// Caller should check error status.
	if (file==NULL) return NULL;

	toasim_header->version=TOASIM_VERSION;
	strcpy(toasim_header->writer,TOASIM_WRITER);

	fwrite_err("TOASIM",6,1,file);
	toasim_write_32("VERS",&toasim_header->version,file);
	toasim_write_str("WRTR",toasim_header->writer,file);
	toasim_write_str("T_NM",toasim_header->timfile_name,file);
	toasim_write_str("P_NM",toasim_header->parfile_name,file);
	toasim_write_str("INVK",toasim_header->invocation,file);
	toasim_write_str("SHRT",toasim_header->short_desc,file);
	toasim_write_str("DESC",toasim_header->description,file);
	toasim_write_str("TOAS",toasim_header->idealised_toas,file);
	toasim_write_str("OPAR",toasim_header->orig_parfile,file);
	toasim_write_str("GP_D",toasim_header->gparam_desc,file);
	toasim_write_str("GP_V",toasim_header->gparam_vals,file);
	toasim_write_str("RP_D",toasim_header->rparam_desc,file);
	toasim_write_32("RP_L",&toasim_header->rparam_len,file);
	toasim_write_64("SEED",&toasim_header->seed,file);
	toasim_write_32("NTOA",&toasim_header->ntoa,file);
	toasim_write_32("NREA",&toasim_header->nrealisations,file);

	toasim_header->d_start=ftell(file)+4*6;
	toasim_header->d_offset=
		4 + 		// Marker
		toasim_header->ntoa*8 +	// ntoas * double
		3*8 +		// three quadratic params
		toasim_header->rparam_len;	// parameters.
	toasim_write_32("DSTT",&toasim_header->d_start,file);
	toasim_write_32("DOFF",&toasim_header->d_offset,file);
	return file;
}
示例#4
0
void toasim_write_64(char* fname, void* val, FILE *file){
	uint32_t sz=8;
	fwrite_err(fname,4,1,file);
	fwrite_err(&sz,4,1,file);
	fwrite_err(val,sz,1,file);
}
示例#5
0
void toasim_write_str(char* fname, char* str,FILE *file){
	uint32_t sz=(uint32_t)strlen(str);
	fwrite_err(fname,4,1,file);
	fwrite_err(&sz,sizeof(uint32_t),1,file);
	fwrite_err(str,1,strlen(str),file);
}
示例#6
0
unsigned long BuildID3Tag(struct ID3Tag *ptr,FILE *outf)
{
	unsigned long tagpos=0;		//Records the position of the ID3 tag in the output file
	unsigned long framepos=0;	//Records the position of the SYLT frame in the output file
	unsigned long ctr=0;
	struct ID3Frame *temp=NULL;
	struct Lyric_Line *curline=NULL;	//Conductor of the lyric line linked list
	struct Lyric_Piece *curpiece=NULL;	//A conductor for the lyric pieces list
	unsigned long framesize=0;	//The calculated size of the written SYLT frame
	unsigned long tagsize=0;	//The calculated size of the modified ID3 tag
	unsigned char array[4]={0};	//Used to build the 28 bit ID3 tag size
	unsigned char defaultID3tag[10]={'I','D','3',3,0,0,0,0,0,0};
		//If the input file had no ID3 tag, this tag will be written
	unsigned long fileendpos=0;	//Used to store the size of the input file
	char newline=0;				//ID3 spec indicates that newline characters should be used at the beginning
								//of the new line instead of at the end of a line, use this to track for this

//Validate input parameters
	if((ptr == NULL) || (ptr->fp == NULL) || (outf == NULL))
		return 0;	//Return failure

	if(Lyrics.verbose)	printf("\nExporting ID3 lyrics to file \"%s\"\n",Lyrics.outfilename);

//Conditionally copy the existing ID3v2 tag from the source file, or create one from scratch
	if(ptr->frames == NULL)
	{	//If there was no ID3 tag in the input file
		if(Lyrics.verbose)	(void) puts("Writing new ID3v2 tag");
		tagpos=ftell_err(outf);	//Record this file position so the tag size can be rewritten later
		fwrite_err(defaultID3tag,10,1,outf);	//Write a pre-made ID3 tag
	//Write tag information obtained from input file
		if(Lyrics.Title != NULL)
			WriteTextInfoFrame(outf,"TIT2",Lyrics.Title);					//Write song title frame
		if(Lyrics.Artist != NULL)
			WriteTextInfoFrame(outf,"TPE1",Lyrics.Artist);					//Write song artist frame
		if(Lyrics.Album != NULL)
			WriteTextInfoFrame(outf,"TALB",Lyrics.Album);					//Write album frame
}
	else
	{	//If there was an ID3v2 tag in the source file
		rewind_err(ptr->fp);

//If the ID3v2 header isn't at the start of the source file, copy all data that precedes it to the output file
		BlockCopy(ptr->fp,outf,(size_t)(ptr->tagstart - ftell_err(ptr->fp)));

//Copy the original ID3v2 header from source file to output file (record the file position)
		if(Lyrics.verbose)	(void) puts("Copying ID3v2 tag header");
		tagpos=ftell_err(outf);	//Record this file position so the tag size can be rewritten later
		BlockCopy(ptr->fp,outf,(size_t)(ptr->framestart - ftell_err(ptr->fp)));

//Write tag information from input file if applicable, and ensure that equivalent ID3v2 frames from the source file are omitted
		if(Lyrics.Title != NULL)
		{
			WriteTextInfoFrame(outf,"TIT2",Lyrics.Title);					//Write song title frame
			Lyrics.nosrctag=AddOmitID3framelist(Lyrics.nosrctag,"TIT2");	//Linked list create/append to omit source song title frame
		}
		if(Lyrics.Artist != NULL)
		{
			WriteTextInfoFrame(outf,"TPE1",Lyrics.Artist);					//Write song artist frame
			Lyrics.nosrctag=AddOmitID3framelist(Lyrics.nosrctag,"TPE1");	//Linked list create/append to omit source song artist frame
		}
		if(Lyrics.Album != NULL)
		{
			WriteTextInfoFrame(outf,"TALB",Lyrics.Album);					//Write album frame
			Lyrics.nosrctag=AddOmitID3framelist(Lyrics.nosrctag,"TALB");	//Linked list create/append to omit source album frame
		}
		if(Lyrics.Year != NULL)
		{
			WriteTextInfoFrame(outf,"TYER",Lyrics.Year);					//Write year frame
			Lyrics.nosrctag=AddOmitID3framelist(Lyrics.nosrctag,"TYER");	//Linked list create/append to omit source year frame
		}

//Omit any existing SYLT frame from the source file
		Lyrics.nosrctag=AddOmitID3framelist(Lyrics.nosrctag,"SYLT");		//Linked list create/append with SYLT frame ID to ensure SYLT source frame is omitted

//Write all frames from source MP3 to export MP3 except for those in the omit list
		for(temp=ptr->frames;temp!=NULL;temp=temp->next)
		{	//For each ID3Frame in the list
			if(SearchOmitID3framelist(Lyrics.nosrctag,temp->frameid) == 0)	//If the source frame isn't to be omitted
			{
				if(Lyrics.verbose >= 2)	printf("\tCopying frame \"%s\"\n",temp->frameid);

				if((unsigned long)ftell_err(ptr->fp) != temp->pos)	//If the input file isn't already positioned at the frame
					fseek_err(ptr->fp,temp->pos,SEEK_SET);			//Seek to it now
				BlockCopy(ptr->fp,outf,(size_t)temp->length + 10);	//Copy frame body size + header size number of bytes
				ctr++;	//Increment counter
			}
			else if(Lyrics.verbose >= 2)	printf("\tOmitting \"%s\" frame from source file\n",temp->frameid);
		}
	}//If there was an ID3 tag in the input file

	if(Lyrics.verbose)	(void) puts("Writing SYLT frame header");

//Write SYLT frame header
	framepos=ftell_err(outf);	//Record this file position so the frame size can be rewritten later
	fputs_err("SYLTxxxx\xC0",outf);	//Write the Frame ID, 4 dummy bytes for the unknown frame size and the first flag byte (preserve frame for both tag and file alteration)
	fputc_err(0,outf);		//Write second flag byte (no compression, encryption or grouping identity)
	fputc_err(0,outf);		//ASCII encoding
	fputs_err("eng\x02\x01",outf);	//Write the language as "English", the timestamp format as milliseconds and the content type as "lyrics"
	fputs_err(PROGVERSION,outf);	//Embed the program version as the content descriptor
	fputc_err(0,outf);		//Write NULL terminator for content descriptor

//Write SYLT frame using the Lyrics structure
	curline=Lyrics.lines;	//Point lyric line conductor to first line of lyrics

	if(Lyrics.verbose)	(void) puts("Writing SYLT lyrics");

	while(curline != NULL)	//For each line of lyrics
	{
		curpiece=curline->pieces;	//Starting with the first piece of lyric in this line
		while(curpiece != NULL)		//For each piece of lyric in this line
		{
			if(newline)					//If the previous lyric was the last in its line
			{
				fputc_err('\n',outf);	//Append a newline character in front of this lyric entry
				newline=0;				//Reset this status
			}
			fputs_err(curpiece->lyric,outf);	//Write the lyric
			if(Lyrics.verbose >= 2)	printf("\t\"%s\"\tstart=%lu\t",curpiece->lyric,curpiece->start);

//Line/word grouping logic
			if(curpiece->next == NULL)		//If this is the last lyric in the line
			{
				newline=1;
				if(Lyrics.verbose >= 2) printf("(newline)");
			}
			else if(!curpiece->groupswithnext)	//Otherwise, if this lyric does not group with the next
			{
				fputc_err(' ',outf);			//Append a space
				if(Lyrics.verbose >= 2)	printf("(whitespace)");
			}
			if(Lyrics.verbose >= 2)	(void) putchar('\n');

			fputc_err(0,outf);					//Write a NULL terminator
			WriteDWORDBE(outf,curpiece->start);	//Write the lyric's timestamp as a big endian value
			curpiece=curpiece->next;			//Point to next lyric in the line
		}
		curline=curline->next;				//Point to next line of lyrics
	}

	framesize=ftell_err(outf)-framepos-10;	//Find the length of the SYLT frame that was written (minus frame header size)
	ctr++;	//Increment counter

	if(ptr->frames != NULL)
	{	//If the input MP3 had an ID3 tag
//Copy any unidentified data (ie. padding) that occurs between the end of the last ID3 frame in the list and the defined end of the ID3 tag
		for(temp=ptr->frames;temp->next!=NULL;temp=temp->next);		//Seek to last frame link
		fseek_err(ptr->fp,temp->pos + temp->length + 10,SEEK_SET);	//Seek to one byte past the end of the frame
		BlockCopy(ptr->fp,outf,(size_t)(ptr->tagend - ftell_err(ptr->fp)));
	}

	tagsize=ftell_err(outf)-tagpos-10;	//Find the length of the ID3 tag that has been written (minus tag header size)

	if(Lyrics.verbose)	(void) puts("Copying audio data");
	fileendpos=GetFileEndPos(ptr->fp);	//Find the position of the last byte in the input MP3 file (the filesize)

	if(ptr->id3v1present && SearchOmitID3framelist(Lyrics.nosrctag,"*"))	//If the user specified to leave off the ID3v1 tag, and the source MP3 has an ID3 tag
	{
		BlockCopy(ptr->fp,outf,(size_t)(fileendpos - ftell_err(ptr->fp) - 128));			//Copy rest of source file to output file (minus 128 bytes, the size of the ID3v1 tag)
		ptr->id3v1present=0;												//Consider the tag as being removed, so a new ID3v1 tag is written below
	}
	else
		BlockCopy(ptr->fp,outf,(size_t)(fileendpos - ftell_err(ptr->fp)));				//Copy rest of source file to output file

//Write/Overwrite ID3v1 tag
	if(ptr->id3v1present)			//If an ID3v1 tag existed in the source MP3
	{	//Overwrite it with tags from the input file
		if(Lyrics.verbose)	(void) puts("Editing ID3v1 tag");
		fseek_err(outf,-125,SEEK_CUR);		//Seek 125 bytes back, where the first field of this tag should exist
		if(Lyrics.Title != NULL)						//If the input file defined a Title
			WritePaddedString(outf,Lyrics.Title,30,0);	//Overwrite the Title field (30 bytes)
		else
			fseek_err(outf,30,SEEK_CUR);				//Otherwise seek 30 bytes ahead to the next field

		if(Lyrics.Artist != NULL)						//If the input file defined an Artist
			WritePaddedString(outf,Lyrics.Artist,30,0);	//Overwrite the Artist field (30 bytes)
		else
			fseek_err(outf,30,SEEK_CUR);				//Otherwise seek 30 bytes ahead to the next field

		if(Lyrics.Album != NULL)						//If the input file defined an Album
			WritePaddedString(outf,Lyrics.Album,30,0);	//Overwrite the Album field (30 bytes)
		else
			fseek_err(outf,30,SEEK_CUR);				//Otherwise seek 30 bytes ahead to the next field

		if(Lyrics.Year != NULL)							//If the input file defined a Year
			WritePaddedString(outf,Lyrics.Year,4,0);	//Overwrite the Year field (4 bytes)
	}
	else
	{	//Write a new ID3v1 tag
		if(Lyrics.verbose)	(void) puts("Writing new ID3v1 tag");
		fseek_err(outf,0,SEEK_END);	//Seek to end of file
		fputs_err("TAG",outf);		//Write ID3v1 header
		WritePaddedString(outf,Lyrics.Title,30,0);	//Write the Title field (30 bytes)
		WritePaddedString(outf,Lyrics.Artist,30,0);	//Write the Artist field (30 bytes)
		WritePaddedString(outf,Lyrics.Album,30,0);	//Write the Album field (30 bytes)
		WritePaddedString(outf,ptr->id3v1year,4,0);	//Write the Year field (4 bytes)
		WritePaddedString(outf,NULL,30,0);			//Write a blank Comment field (30 bytes)
		fputc_err(255,outf);						//Write unknown genre (1 byte)
	}

	if(Lyrics.verbose)	(void) puts("Correcting ID3 headers");

//Rewind to the SYLT header in the output file and write the correct frame length
	fseek_err(outf,framepos+4,SEEK_SET);	//Seek to where the SYLT frame size is to be written
	WriteDWORDBE(outf,framesize);			//Write the SYLT frame size

//Rewind to the ID3 header in the output file and write the correct ID3 tag length
	fseek_err(outf,ptr->tagstart+6,SEEK_SET);	//Seek to where the ID3 tag size is to be written
	if(tagsize > 0x0FFFFFFF)
	{
		(void) puts("\aError:  Tag size is larger than the ID3 specification allows");
		exit_wrapper(2);
	}
	array[3]=tagsize & 127;			//Mask out everything except the lowest 7 bits
	array[2]=(tagsize>>7) & 127;	//Mask out everything except the 2nd set of 7 bits
	array[1]=(tagsize>>14) & 127;	//Mask out everything except the 3rd set of 7 bits
	array[0]=(tagsize>>21) & 127;	//Mask out everything except the 4th set of 7 bits
	fwrite_err(array,4,1,outf);		//Write the ID3 tag size

	if(Lyrics.verbose)	printf("\nID3 export complete.  %lu lyrics written\n",Lyrics.piececount);

	return ctr;	//Return counter
}