void WriteOutput(unsigned long Number) { char String[35]; _ultoa(Number, String, 10); WriteUnicodeString(_totchar(String)); }
void WriteOutput(float Number) { char String[35]; _gcvt(Number, 10, String); WriteUnicodeString(_totchar(String)); }
void WriteOutput(int Number) { char String[35]; _itoa(Number, String, 10); WriteUnicodeString(_totchar(String)); }
void WriteOutput(_TCHAR* String) { WriteUnicodeString(String); }
void WriteOutput(char* String) { WriteUnicodeString(_totchar(String)); }
void WriteOutput(char Char) { WriteUnicodeString(_totchar(&Char)); }
void Export_VL(FILE *outf) { struct _VLSTRUCT_ *OutVL=NULL; //The prepared VL structure to write to file struct VL_Text_entry *curtext=NULL; //Conductor for the text chunk list struct VL_Text_entry *textnext=NULL; //Used for OutVL deallocation struct VL_Sync_entry *cursync=NULL; //Conductor for the sync chunk list struct VL_Sync_entry *syncnext=NULL; //Used for OutVL deallocation unsigned long ctr=0; long filepos=0; assert_wrapper(outf != NULL); //This must not be NULL assert_wrapper(Lyrics.piececount != 0); //This function is not to be called with an empty Lyrics structure if(Lyrics.verbose) printf("\nExporting VL lyrics to file \"%s\"\n\n",Lyrics.outfilename); //Write VL header: 'V','L','2',0 fputc_err('V',outf); fputc_err('L',outf); fputc_err('2',outf); fputc_err(0,outf); //Pad the next four bytes, which are supposed to hold the size of the file, minus the size of the VL header (8 bytes) WriteDWORDLE(outf,0); if(Lyrics.verbose>=2) (void) puts("Writing text chunk"); //Write Text chunk header: 'T','E','X','T' fputc_err('T',outf); fputc_err('E',outf); fputc_err('X',outf); fputc_err('T',outf); //Pad the next four bytes, which are supposed to hold the size of the header chunk, minus the size of the chunk header (8 bytes) WriteDWORDLE(outf,0); //Convert the Offset string to centiseconds from milliseconds (as this is how the VL format interprets it) if((Lyrics.Offset != NULL)) //If there is an offset { if(strlen(Lyrics.Offset) < 2) //If the offset is 0 or 1 characters long, it will be lost, free the string { free(Lyrics.Offset); Lyrics.Offset=NULL; } else Lyrics.Offset[strlen(Lyrics.Offset)-1]='\0'; //Truncate last digit to effectively divide by ten } //Write 8 Unicode strings, for Title, Artist, Album, Editor, Offset and 3 empty strings WriteUnicodeString(outf,Lyrics.Title); WriteUnicodeString(outf,Lyrics.Artist); WriteUnicodeString(outf,Lyrics.Album); WriteUnicodeString(outf,Lyrics.Editor); WriteUnicodeString(outf,NULL); //The Offset tag should be 0 because all timestamps are written as being absolute WriteUnicodeString(outf,NULL); WriteUnicodeString(outf,NULL); WriteUnicodeString(outf,NULL); //Create sync and lyric structures OutVL=VL_PreWrite(); //Write lyric strings curtext=OutVL->Lyrics; if(Lyrics.verbose) (void) puts("Writing VL file"); while(curtext != NULL) //For each text chunk { assert_wrapper(curtext->text != NULL); if(Lyrics.verbose) printf("\tText chunk entry written: \"%s\"\n",curtext->text); WriteUnicodeString(outf,curtext->text); curtext=curtext->next; //Point to next text chunk entry } //Write padding if necessary ctr=ftell_err(outf)%4; //ctr=# of padding bytes needed to align output file position to a DWORD boundary while(ctr--) //For each byte of padding necessary fputc_err(0,outf); //Go back and write the text chunk size after the text chunk header filepos=ftell_err(outf); //Store file position OutVL->textsize=filepos-16; //File position - VL and Text header sizes = text chunk size fseek_err(outf,12,SEEK_SET); //File position 12 is where the text chunk size is to be stored WriteDWORDLE(outf,OutVL->textsize); //Write text chunk size to file fseek_err(outf,filepos,SEEK_SET); //Seek back to the end of the text chunk (where the Sync chunk will begin) if(Lyrics.verbose>=2) (void) puts("Writing Sync chunk"); //Write Sync chunk header: 'S','Y','N','C' fputc_err('S',outf); fputc_err('Y',outf); fputc_err('N',outf); fputc_err('C',outf); //Pad the next four bytes, which are supposed to hold the size of the sync chunk, minus the size of the chunk header (8 bytes) WriteDWORDLE(outf,0); //Write sync entries cursync=OutVL->Syncs; while(cursync != NULL) { WriteWORDLE(outf,cursync->lyric_number);//Write lyric line number this sync entry pertains to WriteWORDLE(outf,0); //Write reserved Word value WriteWORDLE(outf,cursync->start_char); //Write start offset WriteWORDLE(outf,cursync->end_char); //Write end offset WriteDWORDLE(outf,cursync->start_time); //Write start time WriteDWORDLE(outf,cursync->end_time); //Write end time cursync=cursync->next; } //Go back and write the sync chunk size after the sync chunk header filepos=ftell_err(outf); //Store file position OutVL->syncsize=filepos - OutVL->textsize - 24; //File position - Text chunk size - 3 header sizes = sync chunk size fseek_err(outf,OutVL->textsize+20,SEEK_SET); //File position for sync chunk size is text chunk size +2.5 headers WriteDWORDLE(outf,OutVL->syncsize); //Write sync chunk size to file //Go back and write the VL file size after the VL header, which completes the VL export filepos-=8; //Subtract the VL header size from the total file size fseek_err(outf,4,SEEK_SET); //File posistion for VL file size is after the "VL2\0" string WriteDWORDLE(outf,filepos); //Write the VL file size - header value //Destroy the OutVL structure if(Lyrics.verbose>=2) (void) puts("\tReleasing memory from export VL structure"); curtext=OutVL->Lyrics; //Point conductor at first text chunk entry while(curtext != NULL) //For each text chunk entry { textnext=curtext->next; if(curtext->text != NULL) free(curtext->text); //Free string free(curtext); //Free text chunk structure curtext=textnext; } cursync=OutVL->Syncs; //Point conductor at first sync chunk entry while(cursync != NULL) //For each sync chunk entry { syncnext=cursync->next; free(cursync); //Free sync chunk structure cursync=syncnext; } free(OutVL); if(Lyrics.verbose) printf("\nVL export complete. %lu lyrics written\n",Lyrics.piececount); }