Mercurial > hg > sonic-visualiser
changeset 634:ba338234c001 imaf_enc
IMAF load code from Jesus Corral Garcia
author | Chris Cannam |
---|---|
date | Mon, 04 Nov 2013 17:15:52 +0000 |
parents | a8da6db5a2c9 |
children | 8e64cebd38c0 |
files | main/IMAFencoder.c main/IMAFencoder.h main/MainWindow.cpp main/MainWindow.h main/OSCHandler.cpp main/PreferencesDialog.cpp main/PreferencesDialog.h main/checkbox.h main/imafdecoder.cpp sv.pro |
diffstat | 10 files changed, 5093 insertions(+), 442 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/IMAFencoder.c Mon Nov 04 17:15:52 2013 +0000 @@ -0,0 +1,2976 @@ +//***********************************************************// +// Interactive Music Audio Format (IMAF) ENCODER // +// Version 2.0 // +// // +// Eugenio Oñate Hospital // +// Jesús Corral García & Costantino Taglialatela // +// // +// Copyright (c) 2013 Centre for Digital Music (C4DM) // +// Queen Mary University of London. All rights reserved. // +//***********************************************************// +// main.c // +//***********************************************************// + +//File input/output +#include <stdio.h> +//Standard library: numeric conversion, memory allocation... +#include <stdlib.h> +//Operations with strings +#include <string.h> +//Get the creation time: clock +#include <time.h> +#include "IMAFencoder.h" +//Qt libraries +#include <QTextStream> +#include <QMessageBox> +#include <QByteArray> + + +/*Prototype*/ +void filetypebx(FileTypeBox *ftyp); +int mdatbox(MediaDataBox *mdat, int, FILE *imf, FILE *song, FILE *text, int, int, u32); +void moovheaderbox(MovieBox *moov, int, int, int, int, int, int, int); +int trackstructure(MovieBox *moov, int, int, int, int,const char *name); +int samplecontainer(MovieBox *moov, int, int, const char *name); +int sampledescription(MovieBox *moov, int); +int presetcontainer(MovieBox *moov, int, int *vol_values, int type, int fade_in); +int rulescontainer(MovieBox *moov, int SelRuleType, int SelRule_PAR1, int SelRule_PAR2, + int MixRuleType, int MixRule_PAR1, int MixRule_PAR2, int MixRule_PAR3, int MixRule_PAR4); +void writemoovbox(MovieBox moov, int numtrack,int totaltracks, FILE *imf, FILE *text); +int readTrack(MovieBox *moov, int,const char *name); + +// Timed Text Functions +int trackstructure_text (MovieBox *moov, int numtrack, int clock, int durationTrack, int sizemdat,const char *textfile,FILE *text,int totaltracks); +int samplecontainer_text(MovieBox *moov, int numtrack, int sizemdat, const char *textfiles,int totaltracks); +int aux (FILE *text,int num,int num1,int num2,int num3,int *sal); +int getTextSize (FILE *text); +// Group and Preset functions +int groupcontainer(MovieBox *moov, int *group_tracks, int grp_vol, QString grp_name, + QString grp_description, int totaltracks); +void writepresets(MovieBox moov, int numtrack,int totaltracks, FILE *imf); // NOT YET USED + +// MetaData and JPEG Image functions +int metacontainer (MetaBox *meta); +u32 getImageSize(const char *imag); +void insertImage (MetaBox *meta, FILE **imf, u32 imagesize, const char *imagedir); +void writemetabox(MetaBox meta, FILE *imf); + +int bytereverse(int num); +int bytereverse16(int num); +int size_phrase[1000];//the total number of bytes in a phrase including modifiers +int phrases;//the number of phrases in the whole text + + +// Qt Widget for the "Exit Window" +class ExitWindow : public QWidget +{ + public: + ExitWindow(); + private: + QMessageBox *file_created; +}; + +ExitWindow::ExitWindow() +{ + file_created = new QMessageBox(); + file_created->setFixedSize(400,200); // doesn't seem to work + file_created->setWindowTitle("IM AF Encoder"); + file_created->setText("IM AF file successfully created!"); + file_created->show(); +} + +int mainIMAFencoder (int totaltracks, QString files_path[maxtracks],QString outimaf, + QString picturefile, QString textfile, int vol_values[maxtracks], bool HasImageFile, + int SelRuleType, int SelRule_PAR1, int SelRule_PAR2, + int MixRuleType, int MixRule_PAR1, int MixRule_PAR2, int MixRule_PAR3, int MixRule_PAR4, + int group_tracks[maxtracks], int group_volume, QString group_name, QString group_description, + int pres_type, int fade_in) +{ + //Variables + FileTypeBox ftyp; + MediaDataBox mdat; + MovieBox moov; + MetaBox meta; + + //Media Data Box - Contains the audio + FILE *song; //MP3 + u32 sizeTRAK = 0; + int numtr; + //Output File + FILE *imf; //IMA + int numtrack, sizemdat, durationTrack; + //Image + u32 imagesize; + QTextStream out (stdout); + //Timed-Text + FILE *text; + int sizetext; + const char *c_str1[8];//change this value to support more than 8 audio tracks + const char *c_str2; + + //Groups, Presets, Rules and Metadata boxes sizes + u32 sizeGRCO, sizePRCO, sizeRUCO, sizeMETA; + + /* Obtain current time as seconds elapsed since the Epoch. */ + time_t clock = time(NULL); + + + //INPUT: Image + if (HasImageFile){ + c_str2= picturefile.toStdString().c_str(); //convert QString to const char + imagesize = getImageSize(c_str2);//calculate the size of the jpeg + } else { //if there is no image, the size is 0 + imagesize = 0; + } + + //INPUT: Timed-Text + c_str2= textfile.toStdString().c_str(); //convert Qstring to const char + text = fopen(c_str2, "rb"); + sizetext= getTextSize (text); //calculate the size of the text + if((text)==NULL) { + // do something + } + + //Create OUTPUT file (.ima) + imf = fopen (outimaf.toStdString().c_str(),"wb"); + + //Define the File Type Box + filetypebx(&ftyp); + fwrite(&ftyp, sizeof(FileTypeBox),1, imf); + //AUDIO + //Put the tracks in Media Data Box + for (numtr=0; numtr<totaltracks; numtr++) { + c_str1[numtr]= files_path[numtr].toStdString().c_str(); //convert Qstring to const char + song = fopen(c_str1[numtr], "rb"); + + //Extract the samples from the audio file and the text + sizemdat = mdatbox(&mdat, totaltracks, imf, song, text, numtr, sizetext, imagesize);//sizemdat is the size of one audio track + + fclose(song); //Close the audio file + }//close for + + //For each track write track information + durationTrack = (sizemdat*8)/128; + + for (numtrack = 0; numtrack < totaltracks; numtrack++) { + c_str1[numtrack]= files_path[numtrack].toStdString().c_str(); //convert QString to const char + sizeTRAK = trackstructure(&moov, numtrack, clock, durationTrack,sizemdat,c_str1[numtrack])+ sizeTRAK; + } +//At this point, the variable sizeTRAK will be the sum of the size of the box ´trak´ in all the audio tracks. +//The size of the box trak of the text track will be added after. + + if (HasImageFile){ + //Meta + sizeMETA = metacontainer(&meta); + + //Read the image from the JPEG file and write it in the IMAF file + c_str2= picturefile.toStdString().c_str(); //convert Qstring to const char + insertImage(&meta, &imf, imagesize,c_str2); + } + + //Groups + sizeGRCO = groupcontainer(&moov, group_tracks, group_volume, group_name, group_description, totaltracks); //Creates the group, returns the size of the box + + //Presets + sizePRCO = presetcontainer(&moov, totaltracks, vol_values, pres_type, fade_in); // Creates the preset, returns the size of the box. + + //Rules + sizeRUCO = rulescontainer(&moov, SelRuleType, SelRule_PAR1, SelRule_PAR2, + MixRuleType, MixRule_PAR1, MixRule_PAR2, MixRule_PAR3, MixRule_PAR4); // Creates the rules, returns the size of the box. + + //Text track + c_str2= textfile.toStdString().c_str(); //convert Qstring to const char + sizeTRAK = trackstructure_text (&moov, numtrack, clock, durationTrack, sizemdat, c_str2, text, totaltracks) + sizeTRAK; + + //Movie Header - Overall declarations + moovheaderbox(&moov, clock, sizeTRAK, sizePRCO, totaltracks, durationTrack, sizeRUCO, sizeGRCO); // -> enter sizeGRCO instead of 0 + + //Writes the movie box into the file + writemoovbox(moov, numtrack, totaltracks, imf, text); + + //Writes the meta box into the IMAF file + if (HasImageFile){ + writemetabox(meta,imf); + } + + //Close Files and show exit dialog window + fclose(imf); + fclose (text); + ExitWindow *window = new ExitWindow(); +} + + + +void filetypebx(FileTypeBox *ftyp){ + int swap; + + swap = bytereverse(24);// 24 is the size of the box "ftyp" + ftyp->size = swap; + swap = bytereverse('ftyp'); + ftyp->type = swap; + swap = bytereverse('im02'); // Conformance point 3 (see ISO/IEC 23000-12:2010/FDAM 1:2011(E)) + ftyp->major_brand = swap; + ftyp->minor_version = 0; + swap = bytereverse('im02'); // Conformance point 3 (see ISO/IEC 23000-12:2010/FDAM 1:2011(E)) + ftyp->compatible_brands[0] = swap; + swap = bytereverse('isom'); + ftyp->compatible_brands[1] = swap; +} + +int mdatbox(MediaDataBox *mdat, int totaltracks, FILE *imf, FILE *song, FILE *text, int numtr, int sizetext, u32 imagesize){ + + int d=0, cnt=0, j, find = 0, sizestring = 0, i = 0,cnt2=0,highlight_end_time=0; + int dat = 0, dat1 = 0, dat2 = 0, dat3 = 0,k=0; + u32 size = 0, swap, sizeMDAT = 0; + unsigned char c1=0,c2=0,numwords=0,initposition[3000],endposition[3000]; + + //Positionate the pointer at the end of the file to know the size of it + fseek(song, 0, SEEK_END); + size = ftell(song); + //Positionate the pointer at first + fseek(song, 0, SEEK_SET); + + initposition[0]=0; // this array saves the position of the first letter of a word in a phrase + phrases=0;// this variable saves the number of phrases in the whole text + + //Find the header of the first frame (the beginning), when find it d=1 and jump out the loop. + // The header is 32 bytes. We find in groups of 8 bytes + // Contemplate all possible options of headers + while (d == 0) { + find = 0; + fread(&dat, sizeof(unsigned char), 1, song); + cnt++; + + if (dat == 0xFF) { + cnt++; // cnt : stores the position of the pointer. + fread(&dat1, sizeof(unsigned char), 1, song); + cnt++; + fread(&dat2, sizeof(unsigned char), 1, song); + cnt++; + fread(&dat3, sizeof(unsigned char), 1, song); + if (dat1 == 0xFB && dat2 == 146 && dat3 == 64 ) { + find = 1; // find: if the header is found + d=1; // d: jump out the loop + } + if (dat1 == 0xFB && dat2 == 146 && dat3 == 96 ) { + d=1; + find = 1; + } + if (dat1 == 0xFB && dat2 == 144 && dat3 == 64 ) { + find = 1; + d=1; + } + if (dat1 == 0xFB && dat2 == 144 && dat3 == 96 ) { + find = 1; + d=1; + } + if (dat1 == 0xFB && dat2 == 146 && dat3 == 100 ) { + d=1; + find = 1; + } + if (dat1 == 0xFB && dat2 == 144 && dat3 == 100 ) { + find = 1; + d=1; + } + if (dat1 == 0xFA && dat2 == 146 && dat3 == 64 ) { + find = 1; + d=1; + } + if (dat1 == 0xFA && dat2 == 146 && dat3 == 96 ) { + d=1; + find = 1; + } + if (dat1 == 0xFA && dat2 == 144 && dat3 == 64 ) { + find = 1; + d=1; + } + if (dat1 == 0xFA && dat2 == 144 && dat3 == 96 ) { + find = 1; + d=1; + } + if (dat1 == 0xFA && dat2 == 146 && dat3 == 100 ) { + d=1; + find = 1; + } + if (dat1 == 0xFA && dat2 == 144 && dat3 == 100 ) { + find = 1; + d=1; + } + if (find == 0) { + fseek(song, -3, SEEK_CUR); // if 3 last bytes in the header are not correct + cnt = cnt - 3; + } + } // close if + if (cnt == size) { //if we have readen all the bytes in the audio file + d = 1; + } + }//close while + size = size - (cnt - 4); // Calculate the size of the samples. size = pos. end of file - pos. first header. + if (numtr == 0) { //if it is the first audio track the code writes the mdat size + sizeMDAT = size*totaltracks + 8 + sizetext + imagesize; // size of the whole media box -> INCLUDING IMAGE and TEXT SIZE.The text size does not include modifiers + swap = bytereverse(sizeMDAT); + fwrite(&swap, sizeof(u32), 1, imf); + swap = bytereverse('mdat'); + mdat->type = swap; + fwrite(&mdat->type, sizeof(u32), 1, imf); + } + fseek(song, cnt - 4, SEEK_SET); + for (j=0; j<size; j++) { //read all the samples of one track and writes them in the IM AF file + fread(&mdat->data, sizeof(char), 1, song); + fwrite(&mdat->data, sizeof(char), 1, imf); + } + + // copy the text in the 3gp to the ima and add the text modifiers + + cnt=0;// the total number of bytes of the whole text including modifiers + fseek(text,0,SEEK_CUR); + sizestring=0;//number of bytes of a phrase (without modifiers) + initposition[0]=0;// this array saves the initial position of a word + if(numtr==totaltracks-1){ // writes the text after the samples of all the audio tracks + j=0;cnt=0; + while(j<sizetext){ //this loop reads the whole text + cnt2=0;//the total number of bytes of a phrase including the modifiers + fread(&c1,sizeof(char),1,text); + fread(&c2,sizeof(char),1,text); + fwrite(&c1,sizeof(char),1,imf);//two bytes of sizestring + fwrite(&c2,sizeof(char),1,imf); + sizestring = (c1<<8) | (c2);//sizestring is the size of one phrase contained in 3gp + j=j+2; + cnt=cnt+2; + cnt2=cnt2+2; + phrases++;//the number of phrases in the whole text + numwords=0;// the number of words in a phrase + initposition[0]=0;//this array saves the first position of a word in a phrase + endposition[0]=0;// this array saves the last position of a word in a phrase + k=0;//the index for endposition array and initposition array + for(i=0;i< sizestring;i++){ + fread(&mdat->data,sizeof(char),1,text); + fwrite(&mdat->data,sizeof(char),1,imf); + j++; + cnt=cnt+1; + cnt2=cnt2+1; + if(mdat->data==0x20){ //a blank space separates two words. 0x20 = blank space + + numwords++; + endposition[k]=i; + initposition[k+1]=i+1; + k++; + } + + + } //close for + endposition[k]=sizestring-1;//saves the last position of the last word in a phrase + numwords++; + + + mdat->data=0x00; + fwrite(&mdat->data,sizeof(char),1,imf);//hclr size + fwrite(&mdat->data,sizeof(char),1,imf);//hclr size + fwrite(&mdat->data,sizeof(char),1,imf);//hclr size + mdat->data=0x0C; + fwrite(&mdat->data,sizeof(char),1,imf); //hclr size + fwrite("h",sizeof(char),1,imf); + fwrite("c",sizeof(char),1,imf); + fwrite("l",sizeof(char),1,imf); + fwrite("r",sizeof(char),1,imf); + mdat->data=0xFF; + fwrite(&mdat->data,sizeof(char),1,imf);//highlight color rgba + mdat->data=0x62; + fwrite(&mdat->data,sizeof(char),1,imf);//highlight color rgba + mdat->data=0x04; + fwrite(&mdat->data,sizeof(char),1,imf);//highlight color rgba + mdat->data=0xFF; + fwrite(&mdat->data,sizeof(char),1,imf);//highlight color rgba + mdat->data=0x00; + fwrite(&mdat->data,sizeof(char),1,imf); //krok size + mdat->data=0x00; + fwrite(&mdat->data,sizeof(char),1,imf);//krok size + mdat->data=0x00; + fwrite(&mdat->data,sizeof(char),1,imf);//krok size + mdat->data=14+(8*numwords); + fwrite(&mdat->data,sizeof(char),1,imf); //krok size + fwrite("k",sizeof(char),1,imf); + fwrite("r",sizeof(char),1,imf); + fwrite("o",sizeof(char),1,imf); + fwrite("k",sizeof(char),1,imf); + mdat->data=0x00; + fwrite(&mdat->data,sizeof(char),1,imf);//highlight-start-time + mdat->data=0x00; + fwrite(&mdat->data,sizeof(char),1,imf);//highlight-start-time + mdat->data=0x00; + fwrite(&mdat->data,sizeof(char),1,imf);//highlight-start-time + mdat->data=0x00; + fwrite(&mdat->data,sizeof(char),1,imf);//highlight-start-time + mdat->data=0x00; + fwrite(&mdat->data,sizeof(char),1,imf);//entry-count + mdat->data=numwords; + fwrite(&mdat->data,sizeof(char),1,imf);//entry-count + + for(i=0;i<numwords;i++){ + + mdat->data=0x00; + fwrite(&mdat->data,sizeof(char),1,imf);//highlight-end-time + mdat->data=0x00; + fwrite(&mdat->data,sizeof(char),1,imf);//highlight-end-time + + + if(i==numwords-1){ //if it is the last word in a phrase we put this value + mdat->data=0xFF; + fwrite(&mdat->data,sizeof(char),1,imf);//highlight-end-time + mdat->data=0xFF; + fwrite(&mdat->data,sizeof(char),1,imf);//highlight-end-time + + } + + else{ //if it is not the last word in a phrase + + highlight_end_time = (i+1)*(11/numwords);//change the value '11' in order to increase o decrease the speed of highlight + mdat->data= highlight_end_time; + fwrite(&mdat->data,sizeof(char),1,imf);//highlight-end-time + mdat->data=0xFF; + fwrite(&mdat->data,sizeof(char),1,imf);//highlight-end-time + + + } + + mdat->data=0x00; + fwrite(&mdat->data,sizeof(char),1,imf);//startcharoffset + mdat->data=initposition[i]; + fwrite(&mdat->data,sizeof(char),1,imf);//startcharoffset + mdat->data=0x00; + fwrite(&mdat->data,sizeof(char),1,imf);//endcharoffset + mdat->data=endposition[i]+1; + fwrite(&mdat->data,sizeof(char),1,imf);//endcharoffset + + }//close for + + cnt=cnt+26+(numwords*8);//cnt is the number of bytes of the whole text including modifiers + cnt2=cnt2+26+(numwords*8); //cnt2 is the number of bytes of a phrase including the modifiers + + size_phrase[phrases-1]=cnt2 ; + + } //close while + + sizeMDAT = size*totaltracks + 8 + cnt + imagesize; // size value must include image and text sizes + swap = bytereverse(sizeMDAT); + fseek(imf,-(sizeMDAT-imagesize),SEEK_CUR); //overwrittes sizeMDAT with the total size (Image is yet to be written in the file at this point) + fwrite(&swap, sizeof(u32), 1, imf); + fseek(imf,(sizeMDAT-imagesize)-4,SEEK_CUR); // (Image is yet to be written in the file at this point) + } // close if (numtr==totaltracks-1) + + fclose(song); + + return size; +} + +int samplecontainer(MovieBox *moov, int numtrack, int sizemdat, const char *name){ + + u32 sizeSTSD, sizeSTSZ, swap, num_samples, dat=0; + u32 sizetime, sizeSTTS; //Time to Sample Box + u32 sizeSTSC = 28; //Sample to Chunck + u32 sizeSTCO = 20; //Chunck offset + u32 sizeSTBL; //Sample Table Box // + + //Sample Description Box// + sizeSTSD = sampledescription(moov, numtrack); + + //Sample size box// + swap = bytereverse('stsz'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.type = swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.version = 0; + //Read Track: Frame size and Decoder Times + num_samples = readTrack(moov, numtrack, name); + sizeSTSZ = num_samples*4 + 20; + swap = bytereverse(sizeSTSZ); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.size = swap; + + //Time To Sample Box// + sizetime = bytereverse(moov->TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.TimeToSampleBox.entry_count); + sizeSTTS = 16 + sizetime*4*2; + swap = bytereverse(sizeSTTS); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.size = swap; + swap = bytereverse('stts'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.type = swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.version = 0; + + //Sample To Chunk// + swap = bytereverse(sizeSTSC); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.size = swap; + swap = bytereverse('stsc'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.type = swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.version = 0; + swap = bytereverse(1); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.entry_count = swap; + swap = bytereverse(1); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.first_chunk = swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.samples_per_chunk = moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleSizeBox.sample_count; + swap = bytereverse(1); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.sample_description_index = swap; + + //Chunk Offset Box// + swap = bytereverse(sizeSTCO); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + ChunkOffsetBox.size = swap; + swap = bytereverse('stco'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + ChunkOffsetBox.type = swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + ChunkOffsetBox.version = 0; + swap = bytereverse(1); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + ChunkOffsetBox.entry_count = swap; + dat = 32 + sizemdat*numtrack; + swap = bytereverse(dat); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + ChunkOffsetBox.chunk_offset[numtrack] = swap; + + //Sample Table Box // + sizeSTBL = 8 + sizeSTSD + sizeSTSZ + sizeSTSC + sizeSTCO + sizeSTTS; + swap = bytereverse(sizeSTBL); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.size = swap; + swap = bytereverse('stbl'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.type =swap; + + return sizeSTBL; +} + +int sampledescription(MovieBox *moov, int numtrack){ + + u32 swap, sizeESD = 35; + + u32 sizeMP4a; //Audio Sample Entry// + u32 sizeSTSD; //Sample description box // + + + swap = bytereverse(sizeESD); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.size = swap; + swap = bytereverse('esds'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.type = swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.version = 0; + + //ES Descriptor// + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.tag = 3; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.length = 21; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.ES_ID = 0; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.mix = 0; + + //Decoder config descriptor// + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor. + DecoderConfigDescriptor.tag = 4; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor. + DecoderConfigDescriptor.length = 13; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor. + DecoderConfigDescriptor.objectProfileInd = 0x6B; + swap = bytereverse(0x150036B0); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor. + DecoderConfigDescriptor.mix = swap; + swap = bytereverse(128); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor. + DecoderConfigDescriptor.maxBitRate = swap; + swap = bytereverse(128); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor. + DecoderConfigDescriptor.avgBitrate = swap; + + //SLConfig Descriptor// + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor. + SLConfigDescriptor.tag = 6; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor. + SLConfigDescriptor.length = 1; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor. + SLConfigDescriptor.predifined = 2; + + //Audio Sample Entry// + sizeMP4a = 36 + sizeESD; + swap = bytereverse(sizeMP4a); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.size = swap; + swap = bytereverse('mp4a'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.type =swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.reserved[0] = 0; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.reserved[1] = 0; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.reserved[2] = 0; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.reserved[3] = 0; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.reserved[4] = 0; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.reserved[5] = 0; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.data_reference_index = bytereverse16(1); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.reserved2[0] = 0; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.reserved2[1] = 0; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.channelcount = 512; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.samplesize = 4096; // 16 bits + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.reserved3 = 0; + swap = 44100 << 16; + swap = bytereverse(swap); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.samplerate = swap; + + //Sample description box // + sizeSTSD = 16 + sizeMP4a; + swap = bytereverse(sizeSTSD); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.size = swap; + swap = bytereverse('stsd'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.type = swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.version = 0; + swap = bytereverse(1); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.entry_count = swap; + + return sizeSTSD; +} + +int readTrack (MovieBox *moov, int numtrack,const char *name){ + + int t=0,k=1, l =0; + + FILE *song; + int d=0, cnt = 0, i=0, j=0, cnt2 = 0, find = 0, swap, num_entr = 0; + int dat = 0, dat1 = 0, dat2 = 0, dat3 = 0, num_frame = 0, end =0, pos = 0; + u32 size[9000]; + + //Open the audio file with the name introduced by the user + song = fopen (name,"rb"); + if (song == NULL) { + printf("Error opening input file\n"); + system("pause"); + exit(1); + } + //Calculate the size of the track + fseek(song, 0, SEEK_END); + end = ftell(song); + fseek(song, 0, SEEK_SET); + d=0, i=0; + //Search for each frame one by one, and extratcs the information + while (d == 0) { + find = 0; + fread(&dat, sizeof(unsigned char), 1, song); + cnt++; + + if (dat == 0xFF) { + cnt++; + fread(&dat1, sizeof(unsigned char), 1, song); + cnt++; + fread(&dat2, sizeof(unsigned char), 1, song); + cnt++; + fread(&dat3, sizeof(unsigned char), 1, song); + if (dat1 == 0xFB && dat2 == 146 && dat3 == 64 ) { + pos = cnt - 4; //Pos of the beginning of the frame + size[num_frame] = pos - cnt2; //Size of one frame + cnt2 = pos; //Pos of the next frame + find = 1; + num_frame ++; //Number of frames + } + if (dat1 == 0xFB && dat2 == 146 && dat3 == 96 ) { + pos = cnt - 4; + size[num_frame] = pos - cnt2; + cnt2 = pos; + find = 1; + num_frame ++; + } + if (dat1 == 0xFB && dat2 == 144 && dat3 == 64 ) { + pos = cnt - 4; + size[num_frame] = pos - cnt2; + cnt2 = pos; + find = 1; + num_frame ++; + } + if (dat1 == 0xFB && dat2 == 144 && dat3 == 96 ) { + pos = cnt - 4; + size[num_frame] = pos - cnt2; + cnt2 = pos; + find = 1; + num_frame ++; + } + if (dat1 == 0xFB && dat2 == 146 && dat3 == 100 ) { + pos = cnt - 4; + size[num_frame] = pos - cnt2; + cnt2 = pos; + find = 1; + num_frame ++; + } + if (dat1 == 0xFB && dat2 == 144 && dat3 == 100 ) { + pos = cnt - 4; + size[num_frame] = pos - cnt2; + cnt2 = pos; + find = 1; + num_frame ++; + } + if (dat1 == 0xFA && dat2 == 146 && dat3 == 64 ) { + pos = cnt - 4; + size[num_frame] = pos - cnt2; + cnt2 = pos; + find = 1; + num_frame ++; + } + if (dat1 == 0xFA && dat2 == 146 && dat3 == 96 ) { + pos = cnt - 4; + size[num_frame] = pos - cnt2; + cnt2 = pos; + find = 1; + num_frame ++; + } + if (dat1 == 0xFA && dat2 == 144 && dat3 == 64 ) { + pos = cnt - 4; + size[num_frame] = pos - cnt2; + cnt2 = pos; + find = 1; + num_frame ++; + } + if (dat1 == 0xFA && dat2 == 144 && dat3 == 96 ) { + pos = cnt - 4; + size[num_frame] = pos - cnt2; + cnt2 = pos; + find = 1; + num_frame ++; + } + if (dat1 == 0xFA && dat2 == 146 && dat3 == 100 ) { + pos = cnt - 4; + size[num_frame] = pos - cnt2; + cnt2 = pos; + find = 1; + num_frame ++; + } + if (dat1 == 0xFA && dat2 == 144 && dat3 == 100 ) { + pos = cnt - 4; + size[num_frame] = pos - cnt2; + cnt2 = pos; + find = 1; + num_frame ++; + } + if (find == 0) { //In case it does not find the header. + //It keeps reading next data without jump any position + fseek(song, -3, SEEK_CUR); + cnt = cnt - 3; + } + } + + if (cnt == end) { + pos = cnt; + size[num_frame] = pos - cnt2; + d = 1; + } + } + + //Save Samples size// + swap = bytereverse(num_frame); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.sample_count = swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.sample_size = 0; + + for (i=0; i< num_frame; i++) { + swap = bytereverse(size[i+1]); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.entry_size[i] = swap; + } + + //Save Decoding Times// + //Writes manually the duration of each frame. + //Follows the following structure: + // 7 frames of 26 ms + // 1 frame of 27 ms + // ... + // And each 13 rows it writes + // 8 frames of 26 ms + // 1 frame of 27 ms + //It is done for adjusting the different durations of each frame. + // as they vary between 26.125 ms and 26.075 ms + + swap = bytereverse(1); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.sample_count[0] = swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.sample_delta[0] =0; + // int t=0,k=1, l =0; + num_entr = 1; + j = 0; + for (i = 1; i< num_frame; i++) { + if (j == 8 && l == 0) { + swap = bytereverse(7); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.sample_count[num_entr] = swap; + swap = bytereverse(26); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.sample_delta[num_entr] =swap; + num_entr ++; + + swap = bytereverse(1); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.sample_count[num_entr] = swap; + swap = bytereverse(27); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.sample_delta[num_entr] =swap; + num_entr++; + j=0; + dat = i; + if (k == 6 && t == 0) { + l = 1; + t = 1; + k = 1; + } + if (k == 6 && t ==1) { + l = 1; + k = 1; + } + k++; + } + + if (j == 9 && l == 1) { + + swap = bytereverse(8); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.sample_count[num_entr] = swap; + swap = bytereverse(26); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.sample_delta[num_entr] =swap; + num_entr ++; + + swap = bytereverse(1); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.sample_count[num_entr] = swap; + swap = bytereverse(27); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.sample_delta[num_entr] =swap; + num_entr++; + j=0; + dat = i; + l = 0; + } + j++; + } + + dat = num_frame - dat; + + swap = bytereverse(dat); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.sample_count[num_entr] = swap; + swap = bytereverse(26); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.sample_delta[num_entr] =swap; + num_entr++; + swap = bytereverse(num_entr); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.entry_count = swap; + + fclose(song); + return num_frame; + +} + +int trackstructure (MovieBox *moov, int numtrack, int clock, + int durationTrack, int sizemdat,const char *name){ + int swap; + + int sizeSTBL; //Sample Table Box + u32 sizeURL; //Data Entry Url Box + u32 sizeDREF; //Data Reference + u32 sizeSMHD; //Sound Header Box + u32 sizeDINF; //Data information Box + u32 sizeMINF; //Media Information Box// + u32 sizeHDLR; //Handler Box// + u32 sizeMDHD; //Media Header Box// + u32 sizeMDIA; //Media Box// + u32 sizeTKHD; //Track Header// + u32 sizeTRAK; //Track container + + //Sample Table Box + sizeSTBL = 0; + sizeSTBL = samplecontainer(moov, numtrack,sizemdat, name); + + //Data Entry Url Box + sizeURL = 12; + swap = bytereverse(sizeURL); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox. + DataReferenceBox.DataEntryUrlBox.size = swap; + swap = bytereverse('url '); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox. + DataReferenceBox.DataEntryUrlBox.type = swap; + swap = bytereverse(1); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox. + DataReferenceBox.DataEntryUrlBox.flags = swap; // =1 Track in same file as movie atom. + + //Data Reference + sizeDREF = sizeURL+ 16; + swap = bytereverse(sizeDREF); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox. + DataReferenceBox.size = swap; + swap = bytereverse('dref'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox. + DataReferenceBox.type = swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox. + DataReferenceBox.flags = 0; + swap = bytereverse(1); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox. + DataReferenceBox.entry_count = swap; + + //Data information Box// + sizeDINF = sizeDREF + 8; + swap = bytereverse(sizeDINF); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.size = swap; + swap = bytereverse('dinf'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.type = swap; + + //Sound Header Box // + sizeSMHD = 16; + swap = bytereverse(sizeSMHD); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SoundMediaHeaderBox.size = swap; + swap = bytereverse('smhd'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SoundMediaHeaderBox.type = swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SoundMediaHeaderBox.version = 0; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SoundMediaHeaderBox.balance = 0; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SoundMediaHeaderBox.reserved = 0; + + //Media Information Box// + sizeMINF = sizeDINF + sizeSMHD + sizeSTBL + 8; + swap = bytereverse(sizeMINF); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.size = swap; + swap = bytereverse('minf'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.type = swap; + + //Handler Box// + sizeHDLR = 37; + swap = bytereverse(sizeHDLR); + moov->TrackBox[numtrack].MediaBox.HandlerBox.size = swap; + swap = bytereverse('hdlr'); + moov->TrackBox[numtrack].MediaBox.HandlerBox.type = swap; + moov->TrackBox[numtrack].MediaBox.HandlerBox.version = 0; + moov->TrackBox[numtrack].MediaBox.HandlerBox.pre_defined = 0; + swap = bytereverse('soun'); + moov->TrackBox[numtrack].MediaBox.HandlerBox.handler_type = swap; + moov->TrackBox[numtrack].MediaBox.HandlerBox.reserved[0] = 0; + moov->TrackBox[numtrack].MediaBox.HandlerBox.reserved[1] = 0; + moov->TrackBox[numtrack].MediaBox.HandlerBox.reserved[2] = 0; + //swap = bytereverse('soun'); + //moov->TrackBox[numtrack].MediaBox.HandlerBox.data = swap; + moov->TrackBox[numtrack].MediaBox.HandlerBox.data[0] = 's'; + moov->TrackBox[numtrack].MediaBox.HandlerBox.data[1] = 'o'; + moov->TrackBox[numtrack].MediaBox.HandlerBox.data[2] = 'u'; + moov->TrackBox[numtrack].MediaBox.HandlerBox.data[3] = 'n'; + moov->TrackBox[numtrack].MediaBox.HandlerBox.data[4] = '\0'; + + //Media Header Box// + sizeMDHD = 32; + swap = bytereverse(sizeMDHD); + moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.size = swap; + swap = bytereverse('mdhd'); + moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.type = swap; + moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.version = 0; + swap = bytereverse(clock); + moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.creation_time = swap; + moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.modification_time = swap; + swap = bytereverse(1000); + moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.timescale = swap; + swap = bytereverse(durationTrack); + moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.duration = swap; + moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.language = 0xC455; + moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.pre_defined = 0; + + //Media Box// + sizeMDIA = sizeMDHD + sizeHDLR + sizeMINF + 8; + swap = bytereverse(sizeMDIA); + moov->TrackBox[numtrack].MediaBox.size = swap; + swap = bytereverse('mdia'); + moov->TrackBox[numtrack].MediaBox.type = swap; + + //Track Header// + sizeTKHD = 92; + swap = bytereverse (sizeTKHD); + moov->TrackBox[numtrack].TrackHeaderBox.size = swap; + swap = bytereverse ('tkhd'); + moov->TrackBox[numtrack].TrackHeaderBox.type = swap ; + swap = bytereverse (0x00000006); + moov->TrackBox[numtrack].TrackHeaderBox.version = swap; + swap = bytereverse (clock); + moov->TrackBox[numtrack].TrackHeaderBox.creation_time = swap; + moov->TrackBox[numtrack].TrackHeaderBox.modification_time = swap; + swap = bytereverse (numtrack+1); + moov->TrackBox[numtrack].TrackHeaderBox.track_ID = swap; //From 0x00000001 - 0x7FFFFFFF (dec 2147483647) + moov->TrackBox[numtrack].TrackHeaderBox.reserved = 0; + swap = bytereverse (durationTrack); + moov->TrackBox[numtrack].TrackHeaderBox.duration = swap; + moov->TrackBox[numtrack].TrackHeaderBox.reserved2[0] = 0; + moov->TrackBox[numtrack].TrackHeaderBox.reserved2[1] = 0; + moov->TrackBox[numtrack].TrackHeaderBox.layer = 0; + moov->TrackBox[numtrack].TrackHeaderBox.alternate_group = 0; + moov->TrackBox[numtrack].TrackHeaderBox.volume = 0x1; + moov->TrackBox[numtrack].TrackHeaderBox.reserved3 = 0; + swap = bytereverse (0x00010000); + moov->TrackBox[numtrack].TrackHeaderBox.matrix[0] = swap; + moov->TrackBox[numtrack].TrackHeaderBox.matrix[1] = 0; + moov->TrackBox[numtrack].TrackHeaderBox.matrix[2] = 0; + moov->TrackBox[numtrack].TrackHeaderBox.matrix[3] = 0; + moov->TrackBox[numtrack].TrackHeaderBox.matrix[4] = swap; + moov->TrackBox[numtrack].TrackHeaderBox.matrix[5] = 0; + moov->TrackBox[numtrack].TrackHeaderBox.matrix[6] = 0; + moov->TrackBox[numtrack].TrackHeaderBox.matrix[7] = 0; + swap = bytereverse(0x40000000); + moov->TrackBox[numtrack].TrackHeaderBox.matrix[8] = swap; + moov->TrackBox[numtrack].TrackHeaderBox.width = 0; //just for video + moov->TrackBox[numtrack].TrackHeaderBox.height = 0; //just for video + + //Track container + sizeTRAK = sizeTKHD + sizeMDIA + 8; + swap = bytereverse (sizeTRAK); // Size of one track + moov->TrackBox[numtrack].size = swap; + swap = bytereverse ('trak'); + moov->TrackBox[numtrack].type = swap; + return sizeTRAK; + +} + +int groupcontainer(MovieBox *moov, int *group_tracks, int grp_vol, QString grp_name, + QString grp_description, int totaltracks) { + + int i, j, k, numgroups, sizeCont; + int numel = 0; + int sizeBox = 0; + int tempsize = 0; + int active, activenum, addsize; + +// ADDED FOR SV + for (j=0; j<totaltracks; j++){ + if (group_tracks[j]==1){ + numel++; + } + } + + if (numel==0){ + numgroups = 0; + }else{ + numgroups = 1; + } +// + + moov->GroupContainerBox.num_groups = bytereverse16(numgroups); + + for (i=0; i<numgroups; i++){ + addsize = 0; + tempsize = 0; + moov->GroupContainerBox.GroupBox[i].group_ID = bytereverse(2147483649+i+1); // group_ID shall be represented from 0x80000000 to 0xFFFFFFFF + strcpy(moov->GroupContainerBox.GroupBox[i].group_name, grp_name.toStdString().c_str()); + strcpy(moov->GroupContainerBox.GroupBox[i].group_description, grp_description.toStdString().c_str()); + +// numel = 0; // uncomment for more than one group and remove initial "for" with numel + k = 0; + for (j=0; j<totaltracks; j++){ + if (group_tracks[j]==1){ + moov->GroupContainerBox.GroupBox[i].groupElemId[k].element_ID = bytereverse(j+1); +// numel++; // uncomment for more than one group and remove initial "for" with numel + addsize += 4; + k++; + } + } + moov->GroupContainerBox.GroupBox[i].num_elements = bytereverse16(numel); + +// printf("Choose the activation mode: "); +// printf("Activation mode\n"); +// printf(" - Switch on the MINIMUN number of elements (0, if no Min/Max rule) [0]\n"); +// printf(" - Switch on the MAXIMUM number of elements (All tracks, if no Min/Max rule) [1]\n"); +// printf(" - Switch on the defined number of elements (ONLY IF there is Min/Max rule) [2]\n"); +// scanf("%d",&active); +// fflush(stdin); + + active = 1; // ADDED FOR SV, All tracks enabled + + moov->GroupContainerBox.GroupBox[i].group_activation_mode = active; + activenum = 0; + moov->GroupContainerBox.GroupBox[i].group_activation_elements_number = activenum; + if (active==2){ + printf("Activation elements number: "); + scanf("%d",&activenum); + moov->GroupContainerBox.GroupBox[i].group_activation_elements_number = bytereverse16(activenum); + addsize += 2; + } + + moov->GroupContainerBox.GroupBox[i].group_reference_volume = bytereverse16(grp_vol*256/100); // define 8.8 fixed point + + tempsize = 75 + addsize; // ---> before was 66 + addsize; + moov->GroupContainerBox.GroupBox[i].size = bytereverse(tempsize); + moov->GroupContainerBox.GroupBox[i].type = bytereverse('grup'); + moov->GroupContainerBox.GroupBox[i].version = bytereverse(0x02); // flags = Display enable, Edit disable + + sizeBox += tempsize; + + } // close for (numgroups) + + sizeCont = sizeBox + 10; + + moov->GroupContainerBox.size = bytereverse(sizeCont); + moov->GroupContainerBox.type = bytereverse('grco'); + + return sizeCont; +} + +int presetcontainer(MovieBox *moov, int totaltracks, int *vol_values, int prestype, int fade_in){ + + int temp, i, j, k, m, t, vol; + int numpres, eq; + //char name[50]; + u32 sizePRST = 0; + u32 sizePRCO = 0; + u32 sizeEQ; + u32 addsize = 0; + int updates = 0; + + numpres = 1; // ADDED FOR SV + + //Preset Box// + for (i=0; i<numpres; i++) { +// printf("\nPRESET LIST:\n"); +// printf(" - Static track volume [0]\n"); +// printf(" - Static object volume [1]\n"); +// printf(" - Dynamic track volume [2]\n"); +// printf(" - Dynamic object volume [3]\n"); +// printf(" - Dynamic track approximated volume [4]\n"); +// printf(" - Dynamic object approximated volume [5]\n"); +// printf(" - Static track volume with Equalization [6]\n"); // count preset_type from 8 +// printf(" - Static object volume with Equalization [7]\n"); +// printf(" - Dynamic track volume with Equalization [8]\n"); +// printf(" - Dynamic object volume with Equalization [9]\n"); +// printf(" - Dynamic track approximated with Equalization [10]\n"); +// printf(" - Dynamic object approximated with Equalization [11]\n"); +// printf("\nPlease make your choice: "); +// scanf("%d", &prestype); +// fflush(stdin); + + //PresetBOX + // Box size specified in respective case + moov->PresetContainerBox.PresetBox[i].type = bytereverse('prst'); + moov->PresetContainerBox.PresetBox[i].flags = bytereverse(0x02); // Display Enable Edit Disable + moov->PresetContainerBox.PresetBox[i].preset_ID = i+1; + moov->PresetContainerBox.PresetBox[i].num_preset_elements = totaltracks; // All the tracks are involved in the preset + for (j=0; j<totaltracks; j++) { + moov->PresetContainerBox.PresetBox[i].presElemId[j].preset_element_ID = bytereverse(j+1); + } + moov->PresetContainerBox.PresetBox[i].preset_global_volume = 100; + +// prestype = 0; // ADDED FOR SV + + switch (prestype) { + case 0: moov->PresetContainerBox.PresetBox[i].preset_type = 0; + strcpy(moov->PresetContainerBox.PresetBox[i].preset_name, "Static track volume preset"); + + for (j=0; j<totaltracks; j++) { + vol = vol_values[j]*2; + moov->PresetContainerBox.PresetBox[i].StaticTrackVolume.presVolumElem[j].preset_volume_element = vol/2; //*0.02 + } + + addsize = totaltracks; + break; + case 1: moov->PresetContainerBox.PresetBox[i].preset_type = 1; + strcpy(moov->PresetContainerBox.PresetBox[i].preset_name, "Static object volume preset"); + + for (j=0; j<totaltracks; j++) { + moov->PresetContainerBox.PresetBox[i].StaticObjectVolume.InputCH[j].num_input_channel = num_ch; + } + moov->PresetContainerBox.PresetBox[i].StaticObjectVolume.output_channel_type = 1; // STEREO (2 output channels) + for (j=0; j<totaltracks; j++){ + for (k=0; k<num_ch; k++){ + for (m=0; m<num_ch; m++){ + moov->PresetContainerBox.PresetBox[i].StaticObjectVolume.presElVol[j]. + Input[k].Output[m].preset_volume_element = (100-(20*m))/2; // INPUT BY USER + } + } + } + + addsize = totaltracks + 1+ totaltracks*num_ch*num_ch; + break; + case 2: moov->PresetContainerBox.PresetBox[i].preset_type = 2; + strcpy(moov->PresetContainerBox.PresetBox[i].preset_name, "Dynamic track volume preset"); + + updates = 2; // volume changes + moov->PresetContainerBox.PresetBox[i].DynamicTrackVolume.num_updates = bytereverse16(updates); + for (j=0; j<updates; j++){ // INPUT BY USER + moov->PresetContainerBox.PresetBox[i].DynamicTrackVolume. + DynamicChange[j].updated_sample_number = bytereverse16(100+(j*100)); // *0.026 = time in seconds + for (k=0; k<totaltracks; k++){ + moov->PresetContainerBox.PresetBox[i].DynamicTrackVolume. + DynamicChange[j].presVolumElem[k].preset_volume_element = (50*j)/2; // INPUT BY USER + } + } + + addsize = 2 + updates*(2 + totaltracks); + break; + case 3: moov->PresetContainerBox.PresetBox[i].preset_type = 3; + strcpy(moov->PresetContainerBox.PresetBox[i].preset_name, "Dynamic object volume preset"); + + updates = 2; // volume changes + moov->PresetContainerBox.PresetBox[i].DynamicObjectVolume.num_updates = bytereverse16(updates); // INPUT BY USER (maybe...) + for (j=0; j<totaltracks; j++) { + moov->PresetContainerBox.PresetBox[i].DynamicObjectVolume.InputCH[j].num_input_channel = 2; + } + moov->PresetContainerBox.PresetBox[i].DynamicObjectVolume.output_channel_type = 1; // STEREO (2 output channels) + for (j=0; j<updates; j++){ // INPUT BY USER + moov->PresetContainerBox.PresetBox[i].DynamicObjectVolume. + DynamicChange[j].updated_sample_number = bytereverse16(0+(j*500)); // *0.026 = time in seconds + for (k=0; k<totaltracks; k++){ + for (m=0; m<num_ch; m++){ + for (t=0; t<num_ch; t++){ + moov->PresetContainerBox.PresetBox[i].DynamicObjectVolume.DynamicChange[j]. + presElVol[k].Input[m].Output[t].preset_volume_element = (25*(j+1)); // INPUT BY USER + } + } + } + } + + addsize = 2 + totaltracks + 1 + updates*(2 + totaltracks*num_ch*num_ch); + break; + case 4: moov->PresetContainerBox.PresetBox[i].preset_type = 4; + strcpy(moov->PresetContainerBox.PresetBox[i].preset_name, "Dynamic track approximated volume"); + + updates = 2; // volume changes + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume.num_updates = bytereverse16(updates); + for (j=0; j<updates; j++){ + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].start_sample_number = bytereverse16(100); // *0.026 = time in seconds - INPUT BY USER + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].duration_update = bytereverse16(500); // *0.026 = time in seconds -INPUT BY USER + for (k=0; k<totaltracks; k++){ + if (fade_in){ + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume.DynamicChange[j]. + presElVol[k].end_preset_volume_element = (50*j); // Fade IN + } else { + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume.DynamicChange[j]. + presElVol[k].end_preset_volume_element = (100-(100*j))/2; // Fade OUT + } + } + } + + /* // some code for test + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume.DynamicChange[2].start_sample_number = bytereverse16(1100); + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume.DynamicChange[2].duration_update = bytereverse16(250); + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume.DynamicChange[2].presElVol[0].end_preset_volume_element = 50; + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume.DynamicChange[2].presElVol[1].end_preset_volume_element = 50; + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume.DynamicChange[3].start_sample_number = bytereverse16(1100); + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume.DynamicChange[3].duration_update = bytereverse16(250); + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume.DynamicChange[3].presElVol[0].end_preset_volume_element = 1; + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume.DynamicChange[3].presElVol[1].end_preset_volume_element = 1; + */ + + addsize = 2 + updates*(2 + 2 + totaltracks); + break; + case 5: moov->PresetContainerBox.PresetBox[i].preset_type = 5; // NOT YET IMPLEMENTED INTO THE PLAYER! + strcpy(moov->PresetContainerBox.PresetBox[i].preset_name, "Dynamic object approximated volume"); + + printf("\n\nTHIS PRESET IS NOT YET IMPLEMENTED INTO THE PLAYER!!! PLAYER MAY CRASH WITH THIS FILE!!!\n\n"); + + updates = 2; // volume changes + moov->PresetContainerBox.PresetBox[i].DynamicObjectApproxVolume.num_updates = bytereverse16(updates); + for (j=0; j<totaltracks; j++) { + moov->PresetContainerBox.PresetBox[i].DynamicObjectApproxVolume.InputCH[j].num_input_channel = 2; + } + moov->PresetContainerBox.PresetBox[i].DynamicObjectApproxVolume.output_channel_type = 1; // STEREO (2 output channels) + for (j=0; j<updates; j++){ + moov->PresetContainerBox.PresetBox[i].DynamicObjectApproxVolume. + DynamicChange[j].start_sample_number = bytereverse16(100); // *0.026 = time in seconds - INPUT BY USER + moov->PresetContainerBox.PresetBox[i].DynamicObjectApproxVolume. + DynamicChange[j].duration_update = bytereverse16(250); // *0.026 = time in seconds - INPUT BY USER + for (k=0; k<totaltracks; k++){ + for (m=0; m<num_ch; m++){ + for (t=0; t<num_ch; t++){ + moov->PresetContainerBox.PresetBox[i].DynamicObjectApproxVolume.DynamicChange[j]. + presElVol[k].Input[m].Output[t].preset_volume_element = (100*j)/2; // INPUT BY USER + } + } + } + } + + addsize = 2 + totaltracks + 1 + updates*( 2 + 2 + totaltracks*num_ch*num_ch); + break; + case 6: moov->PresetContainerBox.PresetBox[i].preset_type = 8; + strcpy(moov->PresetContainerBox.PresetBox[i].preset_name, "Static track volume with Equalization"); + + eq = 0; addsize = 0; + for (j=0; j<totaltracks; j++) { + //printf("Enter volume for %s : ",namet[j].title); + scanf("%d",&vol); + fflush(stdin); + moov->PresetContainerBox.PresetBox[i].StaticTrackVolume.presVolumElem[j].preset_volume_element = vol/2; //*0.02 + + // Equalization + printf("EQ Filter on this element? [1] Yes - [0] No : "); + scanf("%d",&eq); + fflush(stdin); + + if (eq == 1){ + moov->PresetContainerBox.PresetBox[i].StaticTrackVolume.presVolumElem[j].EQ.num_eq_filters = 1; + for (k=0; k<moov->PresetContainerBox.PresetBox[i].StaticTrackVolume.presVolumElem[j].EQ.num_eq_filters; k++){ + moov->PresetContainerBox.PresetBox[i].StaticTrackVolume.presVolumElem[j].EQ.Filter[k].filter_type = 4; // HPF + moov->PresetContainerBox.PresetBox[i].StaticTrackVolume.presVolumElem[j].EQ.Filter[k]. + filter_reference_frequency = bytereverse16(5000); // 10kHz + moov->PresetContainerBox.PresetBox[i].StaticTrackVolume.presVolumElem[j].EQ.Filter[k].filter_gain = -10; + moov->PresetContainerBox.PresetBox[i].StaticTrackVolume.presVolumElem[j].EQ.Filter[k].filter_bandwidth = 4; + addsize += 5; + } //close for + }else{ + moov->PresetContainerBox.PresetBox[i].StaticTrackVolume.presVolumElem[j].EQ.num_eq_filters = 0; + } //close if/else + } //close for + + addsize += totaltracks + totaltracks; //add preset_volume and num_eq_filters size + break; + case 7: moov->PresetContainerBox.PresetBox[i].preset_type = 9; // NOT YET IMPLEMENTED INTO THE PLAYER! + strcpy(moov->PresetContainerBox.PresetBox[i].preset_name, "Static object volume with Equalization"); + printf("\n\nTHIS PRESET IS NOT YET IMPLEMENTED INTO THE PLAYER!!! PLAYER MAY CRASH WITH THIS FILE!!!\n\n"); + break; + case 8: moov->PresetContainerBox.PresetBox[i].preset_type = 10; // NOT YET IMPLEMENTED INTO THE PLAYER! + strcpy(moov->PresetContainerBox.PresetBox[i].preset_name, "Dynamic track volume with Equalization"); + printf("\n\nTHIS PRESET IS NOT YET IMPLEMENTED INTO THE PLAYER!!! PLAYER MAY CRASH WITH THIS FILE!!!\n\n"); + break; + case 9: moov->PresetContainerBox.PresetBox[i].preset_type = 11; // NOT YET IMPLEMENTED INTO THE PLAYER! + strcpy(moov->PresetContainerBox.PresetBox[i].preset_name, "Dynamic object volume with Equalization"); + break; + case 10: moov->PresetContainerBox.PresetBox[i].preset_type = 12; // NOT YET IMPLEMENTED INTO THE PLAYER! + strcpy(moov->PresetContainerBox.PresetBox[i].preset_name, "Dynamic track approximated with Equalization"); + printf("\n\nTHIS PRESET IS NOT YET IMPLEMENTED INTO THE PLAYER!!! PLAYER MAY CRASH WITH THIS FILE!!!\n\n"); + + eq = 0; addsize = 0; + updates = 2; // volume changes + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume.num_updates = bytereverse16(updates); + for (j=0; j<updates; j++){ + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].start_sample_number = bytereverse16(100); // *0.026 = time in seconds - INPUT BY USER + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].duration_update = bytereverse16(500); // *0.026 = time in seconds -INPUT BY USER + for (k=0; k<totaltracks; k++){ + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume.DynamicChange[j]. + presElVol[k].end_preset_volume_element = (50*j); // Fade IN, change in (100-(100*j))/2 for Fade OUT -INPUT BY USER + + // Equalization + //printf("EQ Filter on %s ? [1] Yes - [0] No : ",namet[k].title); + scanf("%d",&eq); + fflush(stdin); + + if (eq == 1){ + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].presElVol[k].EQ.num_eq_filters = 1; + for (t=0; t<moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].presElVol[k].EQ.num_eq_filters; t++){ + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].presElVol[k].EQ.Filter[t].filter_type = 4; // HPF + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].presElVol[k].EQ.Filter[t].filter_reference_frequency = bytereverse16(5000); // 10kHz + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].presElVol[k].EQ.Filter[t].end_filter_gain = -10; + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].presElVol[k].EQ.Filter[t].filter_bandwidth = 4; + addsize += 5; + } //close for + }else{ + moov->PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].presElVol[k].EQ.num_eq_filters = 0; + } //close if/else + } //close for (k) + } //close for (j) + + addsize += 2 + updates*(2 + 2 + totaltracks*(1+1)); + break; + case 11: moov->PresetContainerBox.PresetBox[i].preset_type = 13; // NOT YET IMPLEMENTED INTO THE PLAYER! + strcpy(moov->PresetContainerBox.PresetBox[i].preset_name, "Dynamic object approximated with Equalization"); + printf("\n\nTHIS PRESET IS NOT YET IMPLEMENTED INTO THE PLAYER!!! PLAYER MAY CRASH WITH THIS FILE!!!\n\n"); + break; + default: printf("ERROR in PRESET CONTAINER"); + system("pause"); + exit(1); + break; + + } //close switch + + temp = 16 + 50 + 4*totaltracks + addsize; // size PresetBox[i] + moov->PresetContainerBox.PresetBox[i].size = bytereverse(temp); + + sizePRST += temp; // size of all Preset Boxes + + } //close for + + //Preset Container// + sizePRCO += sizePRST + 10; + moov->PresetContainerBox.size = bytereverse(sizePRCO); + moov->PresetContainerBox.type = bytereverse('prco'); + moov->PresetContainerBox.default_preset_ID = 1; // Indicates initial preset activated. + moov->PresetContainerBox.num_preset = numpres; + + return sizePRCO; + +} //close function + +int rulescontainer(MovieBox *moov, int SelRuleType, int SelRule_PAR1, int SelRule_PAR2, + int MixRuleType, int MixRule_PAR1, int MixRule_PAR2, + int MixRule_PAR3, int MixRule_PAR4) { + + int swap; + u32 add_size = 0; //for SelectionRulesBox + u32 sizeRUSC, sizeRUCO, sizeRUMX; + + + //Selection Rules + moov->RulesContainer.num_selection_rules = bytereverse16(1); + moov->RulesContainer.SelectionRules.selection_rule_ID = bytereverse16(1); + + switch (SelRuleType) { + + case 0: moov->RulesContainer.SelectionRules.selection_rule_type = 0; + moov->RulesContainer.SelectionRules.element_ID = bytereverse(2147483649+1); // Must be the same ID of the group + moov->RulesContainer.SelectionRules.min_num_elements = bytereverse16(SelRule_PAR1); + moov->RulesContainer.SelectionRules.max_num_elements = bytereverse16(SelRule_PAR2); + strcpy(moov->RulesContainer.SelectionRules.rule_description,"Min/Max Rule"); + add_size = 4; + break; + case 1: moov->RulesContainer.SelectionRules.selection_rule_type = 1; + moov->RulesContainer.SelectionRules.element_ID = bytereverse(SelRule_PAR1); + moov->RulesContainer.SelectionRules.key_element_ID =bytereverse(SelRule_PAR2); + strcpy(moov->RulesContainer.SelectionRules.rule_description,"Exclusion Rule"); + add_size = 4; + break; + case 2: moov->RulesContainer.SelectionRules.selection_rule_type = 2; + moov->RulesContainer.SelectionRules.element_ID = bytereverse(SelRule_PAR1); + strcpy(moov->RulesContainer.SelectionRules.rule_description,"Not mute Rule"); + add_size = 0; + break; + case 3: moov->RulesContainer.SelectionRules.selection_rule_type = 3; + moov->RulesContainer.SelectionRules.element_ID = bytereverse(SelRule_PAR1); + moov->RulesContainer.SelectionRules.key_element_ID =bytereverse(SelRule_PAR2); + strcpy(moov->RulesContainer.SelectionRules.rule_description,"Implication Rule"); + add_size = 4; + break; + default: printf("ERROR in RULES CONTAINER/Selection Rules"); + system("pause"); + break; + } + + sizeRUSC = 19 + 20 + add_size; + moov->RulesContainer.SelectionRules.size = bytereverse(sizeRUSC); + moov->RulesContainer.SelectionRules.type = bytereverse('rusc'); + moov->RulesContainer.SelectionRules.version = 0; + + //Mixing Rule + moov->RulesContainer.num_mixing_rules = bytereverse16(1); + moov->RulesContainer.MixingRules.mixing_rule_ID = bytereverse16(1); + + switch (MixRuleType) { + + case 0: moov->RulesContainer.MixingRules.mixing_type = 0; + moov->RulesContainer.MixingRules.element_ID = bytereverse(MixRule_PAR1); + moov->RulesContainer.MixingRules.key_elem_ID = bytereverse(MixRule_PAR2); + strcpy(moov->RulesContainer.MixingRules.mix_description, "Equivalence rule"); + break; + case 1: moov->RulesContainer.MixingRules.mixing_type = 1; + moov->RulesContainer.MixingRules.element_ID = bytereverse(MixRule_PAR2); + moov->RulesContainer.MixingRules.key_elem_ID = bytereverse(MixRule_PAR1); + strcpy(moov->RulesContainer.MixingRules.mix_description, "Upper rule"); + break; + case 2: moov->RulesContainer.MixingRules.mixing_type = 2; + moov->RulesContainer.MixingRules.element_ID = bytereverse(MixRule_PAR2); + moov->RulesContainer.MixingRules.key_elem_ID = bytereverse(MixRule_PAR1); + strcpy(moov->RulesContainer.MixingRules.mix_description, "Lower rule"); + break; + case 3: moov->RulesContainer.MixingRules.mixing_type = 3; + moov->RulesContainer.MixingRules.element_ID = bytereverse(MixRule_PAR1); + moov->RulesContainer.MixingRules.min_volume = bytereverse16(1 + MixRule_PAR3*2.5); // 8.8 fixed point + moov->RulesContainer.MixingRules.max_volume = bytereverse16(1 + MixRule_PAR4*2.5); // 8.8 fixed point + strcpy(moov->RulesContainer.MixingRules.mix_description, "Limit rule"); + break; + default: printf("ERROR in RULES CONTAINER/Mixing Rules"); + system("pause"); + exit(1); + break; + } + + sizeRUMX = 23 + 17; + moov->RulesContainer.MixingRules.size = bytereverse(sizeRUMX); + moov->RulesContainer.MixingRules.type = bytereverse('rumx'); + moov->RulesContainer.MixingRules.version = 0; + + //Rule container + sizeRUCO = 12 + sizeRUSC + sizeRUMX; + swap = bytereverse(sizeRUCO); + moov->RulesContainer.size = swap; + swap = bytereverse('ruco'); + moov->RulesContainer.type = swap; + + return sizeRUCO; + +} // close function + +void moovheaderbox (MovieBox *moov, int clock, int sizeTRAK, int sizePRCO, int totaltracks, + int durationTrack, int sizeRUCO, int sizeGRCO) { + int swap; + u32 sizeMOOV; //MovieBox + + //MovieHeader + u32 sizeMVHD = 108; + swap = bytereverse (sizeMVHD); + moov->MovieHeaderBox.size = swap; + swap = bytereverse ('mvhd'); + moov->MovieHeaderBox.type = swap; + moov->MovieHeaderBox.version = 0; + swap = bytereverse (clock); + moov->MovieHeaderBox.creation_time = swap; + moov->MovieHeaderBox.modification_time = swap; + swap = bytereverse (1000); + moov->MovieHeaderBox.timescale = swap; + swap = bytereverse (durationTrack); + moov->MovieHeaderBox.duration = swap; + swap = bytereverse (0x00010000); + moov->MovieHeaderBox.rate = swap; + swap = bytereverse (1); + moov->MovieHeaderBox.volume = 1; + moov->MovieHeaderBox.reserved=0; + moov->MovieHeaderBox.reserved2[0] = 0; + moov->MovieHeaderBox.reserved2[1] = 0; + swap = bytereverse (0x00010000); + moov->MovieHeaderBox.matrix[0] = swap; + moov->MovieHeaderBox.matrix[1] = 0; + moov->MovieHeaderBox.matrix[2] = 0; + moov->MovieHeaderBox.matrix[3] = 0; + moov->MovieHeaderBox.matrix[4] = swap; + moov->MovieHeaderBox.matrix[5] = 0; + moov->MovieHeaderBox.matrix[6] = 0; + moov->MovieHeaderBox.matrix[7] = 0; + swap = bytereverse (0x40000000); + moov->MovieHeaderBox.matrix[8] = 0x40000000; + moov->MovieHeaderBox.pre_defined[0] = 0; + moov->MovieHeaderBox.pre_defined[1] = 0; + moov->MovieHeaderBox.pre_defined[2] = 0; + moov->MovieHeaderBox.pre_defined[3] = 0; + moov->MovieHeaderBox.pre_defined[4] = 0; + moov->MovieHeaderBox.pre_defined[5] = 0; + swap = bytereverse (totaltracks + 1); + moov->MovieHeaderBox.next_track_ID = swap; + + //MovieBox + sizeMOOV = sizeMVHD + sizeTRAK + sizePRCO + sizeRUCO + sizeGRCO + 8; + swap = bytereverse (sizeMOOV); //Size movie: Taking into account number tracks + moov->size = swap; + swap = bytereverse ('moov'); + moov->type = swap; +} + + +void writemoovbox(MovieBox moov, int numtrack,int totaltracks, FILE *imf, FILE *text) +{ + int i, j, k, m, t, swap, pos, temp, type; + int cnt = 0, cnt2 = 0, d = 0, dat = 0, dat1 = 0, dat2 = 0, dat3 = 0, size = 0; + u16 numgroups, numel; + + + //Write movie box// + fwrite(&moov.size, sizeof(u32), 1, imf); + fwrite(&moov.type, sizeof(u32), 1, imf); + //Movie header// + fwrite(&moov.MovieHeaderBox, sizeof(moov.MovieHeaderBox), 1, imf); + //Track container// + for (numtrack = 0; numtrack < totaltracks; numtrack++) { + fwrite(&moov.TrackBox[numtrack].size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].type, sizeof(u32), 1, imf); + //Trck header// + fwrite(&moov.TrackBox[numtrack].TrackHeaderBox, sizeof(moov.TrackBox[numtrack].TrackHeaderBox), 1, imf); + //Media Box// + fwrite(&moov.TrackBox[numtrack].MediaBox.size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.type, sizeof(u32), 1, imf); + //Media Header// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaHeaderBox, + sizeof(moov.TrackBox[numtrack].MediaBox.MediaHeaderBox), 1, imf); + //Handler Box// + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.type, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.version, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.pre_defined, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.handler_type, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.reserved[0], sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.reserved[1], sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.reserved[2], sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.data[0], sizeof(unsigned char), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.data[1], sizeof(unsigned char), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.data[2], sizeof(unsigned char), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.data[3], sizeof(unsigned char), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.data[4], sizeof(unsigned char), 1, imf); + //Media inforamtion box// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.type, sizeof(u32), 1, imf); + //Sound media header// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SoundMediaHeaderBox, + sizeof(moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SoundMediaHeaderBox), 1, imf); + //Data reference// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox, + sizeof(moov.TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox), 1, imf); + //Sample table box// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.type, sizeof(u32), 1, imf); + + //Time to sample box// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.type, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.version, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.entry_count, sizeof(u32), 1, imf); + + swap = bytereverse(moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.entry_count); + pos = swap; + + for (i=0; i<pos; i++) { + + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.sample_count[i], sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.sample_delta[i], sizeof(u32), 1, imf); + } + + //Sample description box// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.type, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.version, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.entry_count, sizeof(u32), 1, imf); + //Audio Sample entry// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.type, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.reserved[0], sizeof(unsigned char), 6, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.data_reference_index, sizeof(u16), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.reserved2[0], sizeof(u32), 2, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.channelcount, sizeof(u16), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.samplesize, sizeof(u16), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.reserved3, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.samplerate, sizeof(u32), 1, imf); + //ESDBox// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.type, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.version, sizeof(u32), 1, imf); + //ES Descriptor// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.tag + , sizeof(unsigned char), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.length + , sizeof(unsigned char), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.ES_ID + , sizeof(u16), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.mix + , sizeof(unsigned char), 1, imf); + //Decoder Config// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.DecoderConfigDescriptor. + tag, sizeof(unsigned char), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.DecoderConfigDescriptor. + length, sizeof(unsigned char), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.DecoderConfigDescriptor. + objectProfileInd, sizeof(unsigned char), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.DecoderConfigDescriptor. + mix, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.DecoderConfigDescriptor. + maxBitRate, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.DecoderConfigDescriptor. + avgBitrate, sizeof(u32), 1, imf); +/* //DecoderSpecificInfo// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.DecoderConfigDescriptor. + DecoderSpecificInfo.tag, sizeof(unsigned char), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.DecoderConfigDescriptor. + DecoderSpecificInfo.length, sizeof(unsigned char), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.DecoderConfigDescriptor. + DecoderSpecificInfo.decSpecificInfoData[0], sizeof(unsigned char), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.DecoderConfigDescriptor. + DecoderSpecificInfo.decSpecificInfoData[1], sizeof(unsigned char), 1, imf); + */ //SLConfig// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.SLConfigDescriptor. + tag, sizeof(unsigned char), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.SLConfigDescriptor. + length, sizeof(unsigned char), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.SLConfigDescriptor. + predifined, sizeof(unsigned char), 1, imf); + + + //Sample Size box// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.type, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.version, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.sample_size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.sample_count, sizeof(u32), 1, imf); + swap = bytereverse(moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.sample_count); + for(i=0; i<swap; i++){ + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.entry_size[i], sizeof(u32), 1, imf); + } + + //Sample to chunk box// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.type, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.version, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.entry_count, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.first_chunk, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.samples_per_chunk, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.sample_description_index, sizeof(u32), 1, imf); + + //Chunk offset// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + ChunkOffsetBox.size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + ChunkOffsetBox.type, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + ChunkOffsetBox.version, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + ChunkOffsetBox.entry_count, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + ChunkOffsetBox.chunk_offset[numtrack], sizeof(u32), 1, imf); + } + + //Group Container + fwrite(&moov.GroupContainerBox.size, sizeof(u32), 1, imf); + fwrite(&moov.GroupContainerBox.type, sizeof(u32), 1, imf); + fwrite(&moov.GroupContainerBox.num_groups, sizeof(u16), 1, imf); + //Group Box + numgroups = bytereverse16(moov.GroupContainerBox.num_groups); + for(i=0; i<numgroups; i++){ + fwrite(&moov.GroupContainerBox.GroupBox[i].size, sizeof(u32), 1, imf); + fwrite(&moov.GroupContainerBox.GroupBox[i].type, sizeof(u32), 1, imf); + fwrite(&moov.GroupContainerBox.GroupBox[i].version, sizeof(u32), 1, imf); + fwrite(&moov.GroupContainerBox.GroupBox[i].group_ID, sizeof(u32), 1, imf); + fwrite(&moov.GroupContainerBox.GroupBox[i].num_elements, sizeof(u16), 1, imf); + numel = bytereverse16(moov.GroupContainerBox.GroupBox[i].num_elements); + for(j=0; j<numel; j++){ + fwrite(&moov.GroupContainerBox.GroupBox[i].groupElemId[j].element_ID, sizeof(u32), 1, imf); + } + fwrite(&moov.GroupContainerBox.GroupBox[i].group_activation_mode, sizeof(unsigned char), 1, imf); + if(moov.GroupContainerBox.GroupBox[i].group_activation_mode==2){ + fwrite(&moov.GroupContainerBox.GroupBox[i].group_activation_elements_number, sizeof(u16), 1, imf); + } + fwrite(&moov.GroupContainerBox.GroupBox[i].group_reference_volume, sizeof(u16), 1, imf); + for (j=0; j<22; j++) { + fwrite(&moov.GroupContainerBox.GroupBox[i].group_name[j], sizeof(char), 1, imf); + } + for (j=0; j<32; j++) { + fwrite(&moov.GroupContainerBox.GroupBox[i].group_description[j], sizeof(char), 1, imf); + } + + } + + //PresetContainerBox + fwrite(&moov.PresetContainerBox.size, sizeof(u32), 1, imf); + fwrite(&moov.PresetContainerBox.type, sizeof(u32), 1, imf); + fwrite(&moov.PresetContainerBox.num_preset, sizeof(unsigned char), 1, imf); + fwrite(&moov.PresetContainerBox.default_preset_ID, sizeof(unsigned char), 1, imf); + + //Preset Box + for (i=0; i<moov.PresetContainerBox.num_preset; i++) { + fwrite(&moov.PresetContainerBox.PresetBox[i].size, sizeof(u32), 1, imf); + fwrite(&moov.PresetContainerBox.PresetBox[i].type, sizeof(u32), 1, imf); + fwrite(&moov.PresetContainerBox.PresetBox[i].flags, sizeof(u32), 1, imf); + fwrite(&moov.PresetContainerBox.PresetBox[i].preset_ID, sizeof(unsigned char), 1, imf); + fwrite(&moov.PresetContainerBox.PresetBox[i].num_preset_elements, sizeof(unsigned char), 1, imf); + for (j=0; j< moov.PresetContainerBox.PresetBox[i].num_preset_elements; j++) { + fwrite(&moov.PresetContainerBox.PresetBox[i].presElemId[j]. + preset_element_ID, sizeof(u32), 1, imf); + } + fwrite(&moov.PresetContainerBox.PresetBox[i].preset_type , sizeof(unsigned char), 1, imf); + fwrite(&moov.PresetContainerBox.PresetBox[i].preset_global_volume, sizeof(unsigned char), 1, imf); + + type = moov.PresetContainerBox.PresetBox[i].preset_type; + + switch(type){ + + case 0: for (j=0; j< moov.PresetContainerBox.PresetBox[i].num_preset_elements; j++) { + fwrite(&moov.PresetContainerBox.PresetBox[i].StaticTrackVolume.presVolumElem[j]. + preset_volume_element,sizeof(unsigned char), 1, imf); + } + break; + case 1: for (j=0; j<num_ch; j++){ + fwrite(&moov.PresetContainerBox.PresetBox[i].StaticObjectVolume.InputCH[j]. + num_input_channel,sizeof(unsigned char), 1, imf); + } + fwrite(&moov.PresetContainerBox.PresetBox[i].StaticObjectVolume.output_channel_type, sizeof(unsigned char), 1, imf); + for (j=0; j<totaltracks; j++){ + for (k=0; k<num_ch; k++){ + for (m=0; m<num_ch; m++){ + fwrite(&moov.PresetContainerBox.PresetBox[i].StaticObjectVolume.presElVol[j]. + Input[k].Output[m].preset_volume_element, sizeof(unsigned char), 1, imf); + } + } + } + break; + case 2: fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicTrackVolume.num_updates, sizeof(u16), 1, imf); + temp = bytereverse16(moov.PresetContainerBox.PresetBox[i].DynamicTrackVolume.num_updates); + for (j=0; j<temp; j++){ + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicTrackVolume. + DynamicChange[j].updated_sample_number, sizeof(u16), 1, imf); + for (k=0; k<totaltracks; k++){ + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicTrackVolume.DynamicChange[j]. + presVolumElem[k].preset_volume_element, sizeof(unsigned char), 1, imf); + } + } + break; + case 3: fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicObjectVolume.num_updates, sizeof(u16), 1, imf); + for (j=0; j<totaltracks; j++) { + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicObjectVolume.InputCH[j].num_input_channel, sizeof(u8), 1, imf); + } + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicObjectVolume.output_channel_type, sizeof(u8), 1, imf); + temp = bytereverse16(moov.PresetContainerBox.PresetBox[i].DynamicObjectVolume.num_updates); + for (j=0; j<temp; j++){ + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicObjectVolume. + DynamicChange[j].updated_sample_number, sizeof(u16), 1, imf); + for (k=0; k<totaltracks; k++){ + for (m=0; m<num_ch; m++){ + for (t=0; t<num_ch; t++){ + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicObjectVolume.DynamicChange[j]. + presElVol[k].Input[m].Output[t].preset_volume_element, sizeof(u8), 1, imf); + } + } + } + } + break; + case 4: fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume.num_updates, sizeof(u16), 1, imf); + temp = bytereverse16(moov.PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume.num_updates); + for (j=0; j<temp; j++){ + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].start_sample_number, sizeof(u16), 1, imf); + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].duration_update, sizeof(u16), 1, imf); + for (k=0; k<totaltracks; k++){ + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume.DynamicChange[j]. + presElVol[k].end_preset_volume_element, sizeof(unsigned char), 1, imf); + } + } + break; + case 5: // NOT YET IMPLEMENTED INTO THE PLAYER! + printf("\n\nTHIS PRESET IS NOT YET IMPLEMENTED INTO THE PLAYER!!! PLAYER MAY CRASH WITH THIS FILE!!!\n\n"); + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicObjectApproxVolume.num_updates, sizeof(u16), 1, imf); + for (j=0; j<totaltracks; j++) { + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicObjectApproxVolume.InputCH[j].num_input_channel, sizeof(u8), 1, imf); + } + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicObjectApproxVolume.output_channel_type, sizeof(u8), 1, imf); + temp = bytereverse16(moov.PresetContainerBox.PresetBox[i].DynamicObjectApproxVolume.num_updates); + for (j=0; j<temp; j++){ + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicObjectApproxVolume. + DynamicChange[j].start_sample_number, sizeof(u16), 1, imf); + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicObjectApproxVolume. + DynamicChange[j].duration_update, sizeof(u16), 1, imf); + for (k=0; k<totaltracks; k++){ + for (m=0; m<num_ch; m++){ + for (t=0; t<num_ch; t++){ + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicObjectApproxVolume.DynamicChange[j]. + presElVol[k].Input[m].Output[t].preset_volume_element, sizeof(u8), 1, imf); + } + } + } + } + break; + case 6: printf("\nERROR WRITING PRESET CONTAINER IN OUTPUT FILE - Not valid case (6)\n"); + system("pause"); + exit(1); + break; + case 7: printf("\nERROR WRITING PRESET CONTAINER IN OUTPUT FILE - Not valid case (7)\n"); + system("pause"); + exit(1); + break; + case 8: for (j=0; j< moov.PresetContainerBox.PresetBox[i].num_preset_elements; j++) { + fwrite(&moov.PresetContainerBox.PresetBox[i].StaticTrackVolume.presVolumElem[j]. + preset_volume_element,sizeof(unsigned char), 1, imf); + fwrite(&moov.PresetContainerBox.PresetBox[i].StaticTrackVolume.presVolumElem[j].EQ.num_eq_filters, sizeof(u8), 1, imf); + //EQ + if (moov.PresetContainerBox.PresetBox[i].StaticTrackVolume.presVolumElem[j].EQ.num_eq_filters != 0) { + for (k=0; k<moov.PresetContainerBox.PresetBox[i].StaticTrackVolume.presVolumElem[j].EQ.num_eq_filters; k++){ + fwrite(&moov.PresetContainerBox.PresetBox[i].StaticTrackVolume. + presVolumElem[j].EQ.Filter[k].filter_type, sizeof(u8), 1, imf); + fwrite(&moov.PresetContainerBox.PresetBox[i].StaticTrackVolume. + presVolumElem[j].EQ.Filter[k].filter_reference_frequency, sizeof(u16), 1, imf); + fwrite(&moov.PresetContainerBox.PresetBox[i].StaticTrackVolume. + presVolumElem[j].EQ.Filter[k].filter_gain, sizeof(u8), 1, imf); + fwrite(&moov.PresetContainerBox.PresetBox[i].StaticTrackVolume. + presVolumElem[j].EQ.Filter[k].filter_bandwidth, sizeof(u8), 1, imf); + } //close for + } //close if + } + break; + case 9: // NOT YET IMPLEMENTED INTO THE PLAYER! + printf("\n\nTHIS PRESET IS NOT YET IMPLEMENTED INTO THE PLAYER!!! PLAYER MAY CRASH WITH THIS FILE!!!\n\n"); + break; + case 10:// NOT YET IMPLEMENTED INTO THE PLAYER! + printf("\n\nTHIS PRESET IS NOT YET IMPLEMENTED INTO THE PLAYER!!! PLAYER MAY CRASH WITH THIS FILE!!!\n\n"); + break; + case 11:// NOT YET IMPLEMENTED INTO THE PLAYER! + printf("\n\nTHIS PRESET IS NOT YET IMPLEMENTED INTO THE PLAYER!!! PLAYER MAY CRASH WITH THIS FILE!!!\n\n"); + break; + case 12:// NOT YET IMPLEMENTED INTO THE PLAYER! + printf("\n\nTHIS PRESET IS NOT YET IMPLEMENTED INTO THE PLAYER!!! PLAYER MAY CRASH WITH THIS FILE!!!\n\n"); + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume.num_updates, sizeof(u16), 1, imf); + temp = bytereverse16(moov.PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume.num_updates); + for (j=0; j<temp; j++){ + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].start_sample_number, sizeof(u16), 1, imf); + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].duration_update, sizeof(u16), 1, imf); + for (k=0; k<totaltracks; k++){ + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume.DynamicChange[j]. + presElVol[k].end_preset_volume_element, sizeof(u8), 1, imf); + //EQ + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].presElVol[k].EQ.num_eq_filters, sizeof(u8), 1, imf); + if(moov.PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].presElVol[k].EQ.num_eq_filters != 0){ + for (t=0; t<moov.PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].presElVol[k].EQ.num_eq_filters; t++){ + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].presElVol[k].EQ.Filter[t].filter_type, sizeof(u8), 1, imf); + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].presElVol[k].EQ.Filter[t].filter_reference_frequency, sizeof(u16), 1, imf); + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].presElVol[k].EQ.Filter[t].end_filter_gain, sizeof(u8), 1, imf); + fwrite(&moov.PresetContainerBox.PresetBox[i].DynamicTrackApproxVolume. + DynamicChange[j].presElVol[k].EQ.Filter[t].filter_bandwidth, sizeof(u8), 1, imf); + } // close for (t) + }//close if + + }// close for (k) + } //close for (j) + break; + case 13:// NOT YET IMPLEMENTED INTO THE PLAYER! + printf("\n\nTHIS PRESET IS NOT YET IMPLEMENTED INTO THE PLAYER!!! PLAYER MAY CRASH WITH THIS FILE!!!\n\n"); + break; + default: printf("\nERROR WRITING PRESET CONTAINER IN OUTPUT FILE - Not valid case (default)\n"); + system("pause"); + exit(1); + break; + + } // close switch + + for (j=0; j<50; j++) { + fwrite(&moov.PresetContainerBox.PresetBox[i].preset_name[j], sizeof(char), 1, imf); + } + + } // close for + + + //Rules Container// + fwrite(&moov.RulesContainer.size, sizeof(u32), 1, imf); + fwrite(&moov.RulesContainer.type, sizeof(u32), 1, imf); + fwrite(&moov.RulesContainer.num_selection_rules, sizeof(u16), 1, imf); + fwrite(&moov.RulesContainer.num_mixing_rules, sizeof(u16), 1, imf); + //Selection Rules// + fwrite(&moov.RulesContainer.SelectionRules.size, sizeof(u32), 1, imf); + fwrite(&moov.RulesContainer.SelectionRules.type, sizeof(u32), 1, imf); + fwrite(&moov.RulesContainer.SelectionRules.version, sizeof(u32), 1, imf); + fwrite(&moov.RulesContainer.SelectionRules.selection_rule_ID, sizeof(u16), 1, imf); + fwrite(&moov.RulesContainer.SelectionRules.selection_rule_type, sizeof(unsigned char), 1, imf); + fwrite(&moov.RulesContainer.SelectionRules.element_ID, sizeof(u32), 1, imf); + + swap = moov.RulesContainer.SelectionRules.selection_rule_type; + if ( swap==0 ) { + fwrite(&moov.RulesContainer.SelectionRules.min_num_elements, sizeof(u16), 1, imf); + fwrite(&moov.RulesContainer.SelectionRules.max_num_elements, sizeof(u16), 1, imf); + } + if ( swap==1 || swap ==3 ){ + fwrite(&moov.RulesContainer.SelectionRules.key_element_ID, sizeof(u32), 1, imf); + } + + for(i=0; i<20; i++){ + fwrite(&moov.RulesContainer.SelectionRules.rule_description[i], sizeof(char), 1, imf); + } + + //Mixing Rules// + fwrite(&moov.RulesContainer.MixingRules.size, sizeof(u32), 1, imf); + fwrite(&moov.RulesContainer.MixingRules.type, sizeof(u32), 1, imf); + fwrite(&moov.RulesContainer.MixingRules.version, sizeof(u32), 1, imf); + fwrite(&moov.RulesContainer.MixingRules.mixing_rule_ID, sizeof(u16), 1, imf); + fwrite(&moov.RulesContainer.MixingRules.mixing_type,sizeof(unsigned char), 1, imf); + fwrite(&moov.RulesContainer.MixingRules.element_ID, sizeof(u32), 1, imf); + + swap = moov.RulesContainer.MixingRules.mixing_type; + if( swap==3 ){ + fwrite(&moov.RulesContainer.MixingRules.min_volume, sizeof(u16), 1, imf); + fwrite(&moov.RulesContainer.MixingRules.max_volume, sizeof(u16), 1, imf); + } else { + fwrite(&moov.RulesContainer.MixingRules.key_elem_ID, sizeof(u32), 1, imf); + } + for(i=0; i<17; i++){ + fwrite(&moov.RulesContainer.MixingRules.mix_description[i], + sizeof(char), 1, imf); + } + + //TIMED TEXT + fwrite(&moov.TrackBox[numtrack].size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].type, sizeof(u32), 1, imf); + //Track header// + fwrite(&moov.TrackBox[numtrack].TrackHeaderBox, + sizeof(moov.TrackBox[numtrack].TrackHeaderBox), 1, imf); + //Media Box// + fwrite(&moov.TrackBox[numtrack].MediaBox.size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.type, sizeof(u32), 1, imf); + //Media Header// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaHeaderBox, + sizeof(moov.TrackBox[numtrack].MediaBox.MediaHeaderBox), 1, imf); + //Handler Box// + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.type, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.version, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.pre_defined, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.handler_type, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.reserved[0], sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.reserved[1], sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.reserved[2], sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.data[0], sizeof(unsigned char), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.data[1], sizeof(unsigned char), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.data[2], sizeof(unsigned char), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.data[3], sizeof(unsigned char), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.HandlerBox.data[4], sizeof(unsigned char), 1, imf); + //Media information box// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.type, sizeof(u32), 1, imf); + //Null media header// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.NullMediaHeaderBox.size, + sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.NullMediaHeaderBox.type, + sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.NullMediaHeaderBox.flags, + sizeof(u32), 1, imf); + //Data Information + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.size,sizeof(u32),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.type,sizeof(u32),1,imf); + //Data Reference + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.size,sizeof(u32),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.type,sizeof(u32),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.flags,sizeof(u32),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.entry_count,sizeof(u32),1,imf); + //Data Entry URL + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryUrlBox.size,sizeof(u32),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryUrlBox.type,sizeof(u32),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.DataReferenceBox.DataEntryUrlBox.flags,sizeof(u32),1,imf); + //Sample table box// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + type, sizeof(u32), 1, imf); + //Time to sample box// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.type, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.version, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.entry_count, sizeof(u32), 1, imf); + swap = bytereverse(moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.entry_count); + pos = swap; + + for (i=0; i<pos; i++) { + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.sample_count[i], sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.sample_delta[i], sizeof(u32), 1, imf); + } + + //Sample description box// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.type, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.version, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.entry_count, sizeof(u32), 1, imf); + //tx3g + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.size,sizeof(u32),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.type,sizeof(u32),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.a,sizeof(u32),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.b,sizeof(u32),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.displayFlags,sizeof(u32),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.horizontaljustification,sizeof(u8),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.verticaljustification,sizeof(u8),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.backgroundcolorrgba[0],sizeof(u8),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.backgroundcolorrgba[1],sizeof(u8),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.backgroundcolorrgba[2],sizeof(u8),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.backgroundcolorrgba[3],sizeof(u8),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.top,sizeof(u16),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.left,sizeof(u16),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.bottom,sizeof(u16),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.right,sizeof(u16),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.startChar,sizeof(u16),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.endChar,sizeof(u16),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.fontID,sizeof(u16),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.facestyleflags,sizeof(u8),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.fontsize,sizeof(u8),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.textcolorrgba[0],sizeof(u8),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.textcolorrgba[1],sizeof(u8),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.textcolorrgba[2],sizeof(u8),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.textcolorrgba[3],sizeof(u8),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.FontTableBox.size,sizeof(u32),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.FontTableBox.type,sizeof(u32),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.FontTableBox.entrycount,sizeof(u16),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.FontTableBox.fontID,sizeof(u16),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.FontTableBox.fontnamelenght,sizeof(u8),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.FontTableBox.font[0],sizeof(u8),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.FontTableBox.font[1],sizeof(u8),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.FontTableBox.font[2],sizeof(u8),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.FontTableBox.font[3],sizeof(u8),1,imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox. + SampleTableBox.SampleDescriptionBox.TextSampleEntry.FontTableBox.font[4],sizeof(u8),1,imf); + //Sample Size box// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.type, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.version, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.sample_size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.sample_count, sizeof(u32), 1, imf); + swap = bytereverse(moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.sample_count); + + for(i=0; i<swap; i++){ + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.entry_size[i], sizeof(u32), 1, imf); + } + + //Sample to chunk box// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.type, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.version, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.entry_count, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.first_chunk, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.samples_per_chunk, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.sample_description_index, sizeof(u32), 1, imf); + + //Chunk offset// + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + ChunkOffsetBox.size, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + ChunkOffsetBox.type, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + ChunkOffsetBox.version, sizeof(u32), 1, imf); + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + ChunkOffsetBox.entry_count, sizeof(u32), 1, imf); + swap=0x00; + fwrite(&swap,sizeof(u32),1,imf); + for (i=0;i<bytereverse(moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + ChunkOffsetBox.entry_count);i++){ + + fwrite(&moov.TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + ChunkOffsetBox.chunk_offset[i], sizeof(u32), 1, imf); + } + + //Song Image// + /* Go to function "writemeta" */ + +} + + +void writepresets(MovieBox moov, int numtrack,int totaltracks, FILE *imf) { + + //int i, j, k, m, t, temp, type; + + // this function is executed in "writemoovbox"; + // to be implemented as standalone +} + +// Fill the MetaBox + +int metacontainer(MetaBox *meta) { + //int swap; + + u32 sizeMETA; + u32 sizeHDLR = 36; + u32 sizeDINF; + u32 sizeDREF = 0; //16 + u32 sizeURL = 0; //12 + u32 sizeILOC = 36 - 2; + u32 sizeIINF; + u32 sizeINFE = 44; + u32 sizeXML = 12 + 2000; + char name[6] = "image"; + char type_content[18] = "application/other"; + char encoding[4] = "jpg"; + + //METADATA + char xml[2000] = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><Mpeg7 xmlns=\"urn:mpeg:mpeg7:schema:2001\"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:mpeg7=\"urn:mpeg:mpeg7:schema:2001\"xmlns:xml=\"http://www.w3.org/XML/1998/namespace\"xsi:schemaLocation=\"urn:mpeg:mpeg7:schema:2001 Mpeg7-2001.xsd\"><Description xsi:type=\"CreationDescriptionType\"><CreationInformation><Creation><Title type=\"songTitle\">IMAF Song</Title><Title type=\"albumTitle\">Encoder</Title><Abstract><FreeTextAnnotation>QMUL</FreeTextAnnotation></Abstract><Creator><Role href=\"urn:mpeg:mpeg7:RoleCS:2001:PERFORMER\"/><Agent xsi:type=\"PersonType\"><Name><FamilyName></FamilyName><GivenName>Frank Sinatra</GivenName></Name></Agent></Creator><CreationCoordinates><Date><TimePoint>2013</TimePoint></Date></CreationCoordinates><CopyrightString></CopyrightString></Creation><Classification><Genre href=\"urn:id3:cs:ID3genreCS:v1:12\"><Name>Electro</Name></Genre></Classification></CreationInformation></Description><Description xsi:type=\"SemanticDescriptionType\"> <Semantics> <SemanticBase xsi:type=\"SemanticStateType\"><AttributeValuePair><Attribute><TermUse href=\"urn:mpeg:maf:cs:musicplayer:CollectionElementsCS:2007:assetNum\"/></Attribute><IntegerValue>07</IntegerValue></AttributeValuePair><AttributeValuePair><Attribute><TermUse href=\"urn:mpeg:maf:cs:musicplayer:CollectionElementsCS:2013:assetTot\"/></Attribute><IntegerValue>11</IntegerValue></AttributeValuePair></SemanticBase></Semantics></Description><Description xsi:type=\"SemanticDescriptionType\"><MediaInformation><MediaIdentification><EntityIdentifier></EntityIdentifier></MediaIdentification></MediaInformation></Description></Mpeg7>"; + + sizeDINF = 8;// + sizeDREF + sizeURL; + sizeIINF = 14 + sizeINFE; + sizeMETA = 12 + sizeHDLR + sizeDINF + sizeILOC + sizeIINF + sizeXML; + + meta->size = bytereverse(sizeMETA); + meta->type = bytereverse('meta'); + meta->version = 0; + //HandlerBox + meta->theHandler.size = bytereverse(sizeHDLR); + meta->theHandler.type = bytereverse('hdlr'); + meta->theHandler.version = 0; + meta->theHandler.pre_defined = 0; + meta->theHandler.handler_type = bytereverse('meta'); + meta->theHandler.reserved[0] = 0; + meta->theHandler.reserved[1] = 0; + meta->theHandler.reserved[2] = 0; + meta->theHandler.name[0] = bytereverse('m'); + meta->theHandler.name[1] = bytereverse('p'); + meta->theHandler.name[2] = bytereverse('7'); + meta->theHandler.name[3] = bytereverse('t'); + //DataInformationBox + meta->file_locations.size = bytereverse(sizeDINF); + meta->file_locations.type = bytereverse('dinf'); + /* + //DataReferenceBox + meta->file_locations.DataReferenceBox.size = bytereverse(sizeDREF); + meta->file_locations.DataReferenceBox.type = bytereverse('dref'); + meta->file_locations.DataReferenceBox.flags = bytereverse(0); // CHECK THIS VALUE + meta->file_locations.DataReferenceBox.entry_count = bytereverse(1); + //DataEntryUrlBox + meta->file_locations.DataReferenceBox.DataEntryUrlBox.size = bytereverse(sizeURL); + meta->file_locations.DataReferenceBox.DataEntryUrlBox.type = bytereverse('url '); // 'url ' with blank space + meta->file_locations.DataReferenceBox.DataEntryUrlBox.flags = bytereverse(0); // CHECK THIS VALUE + */ + //item_location + meta->item_locations.size = bytereverse(sizeILOC); + meta->item_locations.type = bytereverse('iloc'); + meta->item_locations.version = 0; + meta->item_locations.offset_size = 68; // 0100|0100 offset_size = 4 + lenght_size = 4 + //meta->item_locations.lenght_size = 4; //already included + meta->item_locations.base_offset_size = 64; // 0100|0000 base_offset_size = 4 + reserved = 0 + //meta->item_locations.reserved = 0; //already included + meta->item_locations.item_count = bytereverse16(1); + meta->item_locations.item_ID = bytereverse16(1); + meta->item_locations.data_reference_index = 0; + //meta->item_locations.base_offset = bytereverse(); // corresponding to iloc_offset in insertImage function + meta->item_locations.extent_count = bytereverse16(1); + //meta->item_locations.extent_offset = bytereverse(); // corresponding to iloc_offset in insertImage function + //meta->item_locations.extent_length = bytereverse(); // corresponding to imagesize in insertImage function + + //ItemInfoBox + meta->item_infos.size = bytereverse(sizeIINF); + meta->item_infos.type = bytereverse('iinf'); + meta->item_infos.version = 0; + meta->item_infos.entry_count = bytereverse16(1); + + //info_entry + meta->item_infos.info_entry.size = bytereverse(sizeINFE); + meta->item_infos.info_entry.type = bytereverse('infe'); + meta->item_infos.info_entry.version = 0; + meta->item_infos.info_entry.item_ID = bytereverse16(1); + meta->item_infos.info_entry.item_protection_index = 0; + strcpy(meta->item_infos.info_entry.item_name, name); + strcpy(meta->item_infos.info_entry.content_type, type_content); + strcpy(meta->item_infos.info_entry.content_encoding, encoding); + + //XMLBox (MetaData) + meta->XMLBox.size = bytereverse(sizeXML); + meta->XMLBox.type = bytereverse('xml '); + meta->XMLBox.version = 0; + strcpy(meta->XMLBox.string, xml); + + return sizeMETA; +} + +//Read the image's size +u32 getImageSize(const char *imagedir){ + u32 size; + FILE *img; + + img = fopen(imagedir,"rb"); + + //Calculate size of the picture + fseek(img,0,SEEK_END); + size = ftell(img); + fclose(img); + + return size; +} +//Read the text´s size +int getTextSize (FILE *text){ + + int d=0,sizetext=0,dat=0,dat1=0,dat2=0,dat3=0; + + //TEXT-FILE + //Find mdat in text file in order to know the size of the text file + d=0; + while(d==0){ + + fread (&dat,sizeof(unsigned char),1,text); //read a byte and saves it in dat + fread (&dat1,sizeof(unsigned char),1,text); + fread (&dat2,sizeof(unsigned char),1,text); + fread (&dat3,sizeof(unsigned char),1,text); + fseek(text,-3,SEEK_CUR); + + if(dat == 0x6D && dat1 == 0x64 && dat2 == 0x61 && dat3 == 0x74){ // 6D646174 = mdat + d=1; + } + + } //close while + + fseek (text,-5,SEEK_CUR);//positionate the pointer at the first byte of size + fread (&dat,sizeof(unsigned char),1,text); //first byte of size + fread (&dat1,sizeof(unsigned char),1,text);//second byte of size + fread (&dat2,sizeof(unsigned char),1,text);//third byte of size + fread (&dat3,sizeof(unsigned char),1,text);//fourth byte of size + + sizetext = (dat<<24) | (dat1<<16) | (dat2<<8) | (dat3); + sizetext = sizetext-8-16; //4 bytes of size and 4 bytes of type and 16 bytes of padding + + fseek (text,20,SEEK_CUR);//Advance 20 bytes, because the pointer must advance 20 bytes to read the size of the first string.This is because of the way that Quicktime creates the 3gp + + return sizetext; + + +} + +//Read the JPEG file + +void insertImage (MetaBox *meta, FILE **imf, u32 imagesize, const char *imagedir) { + + FILE *img; + u64 iloc_offset = 0; + unsigned char *imgbuffer; + + img = fopen(imagedir,"rb"); + + // Binary reading + fseek(img,0,SEEK_SET); + imgbuffer= (unsigned char*)malloc(sizeof(unsigned char)*imagesize); + fread(imgbuffer, 1, imagesize, img); + fclose(img); + + // Find position in the IMAF file and write the image + iloc_offset = ftell(*imf); + fwrite(imgbuffer,1,imagesize, *imf); + + // Set image size and offset values + meta->item_locations.base_offset = bytereverse(iloc_offset); + meta->item_locations.extent_length = bytereverse(imagesize); + meta->item_locations.extent_offset = bytereverse(iloc_offset); + +} + + +void writemetabox(MetaBox meta, FILE *imf) { + + int i=0; + + //MetaBox + fwrite(&meta.size, sizeof(u32), 1, imf); + fwrite(&meta.type, sizeof(u32), 1, imf); + fwrite(&meta.version, sizeof(u32), 1, imf); + //Handler + fwrite(&meta.theHandler.size, sizeof(u32), 1, imf); + fwrite(&meta.theHandler.type, sizeof(u32), 1, imf); + fwrite(&meta.theHandler.version, sizeof(u32), 1, imf); + fwrite(&meta.theHandler.pre_defined, sizeof(u32), 1, imf); + fwrite(&meta.theHandler.handler_type, sizeof(u32), 1, imf); + fwrite(&meta.theHandler.reserved[0], sizeof(u32), 1, imf); + fwrite(&meta.theHandler.reserved[1], sizeof(u32), 1, imf); + fwrite(&meta.theHandler.reserved[2], sizeof(u32), 1, imf); + fwrite(&meta.theHandler.name[0], sizeof(unsigned char), 1, imf); + fwrite(&meta.theHandler.name[1], sizeof(unsigned char), 1, imf); + fwrite(&meta.theHandler.name[2], sizeof(unsigned char), 1, imf); + fwrite(&meta.theHandler.name[3], sizeof(unsigned char), 1, imf); + //Data Information Box + fwrite(&meta.file_locations.size, sizeof(u32), 1, imf); + fwrite(&meta.file_locations.type, sizeof(u32), 1, imf); + /* + //Data Reference + fwrite(&meta.file_locations.DataReferenceBox.size, sizeof(u32), 1, imf); + fwrite(&meta.file_locations.DataReferenceBox.type, sizeof(u32), 1, imf); + fwrite(&meta.file_locations.DataReferenceBox.flags, sizeof(u32), 1, imf); + fwrite(&meta.file_locations.DataReferenceBox.entry_count, sizeof(u32), 1, imf); + + fwrite(&meta.file_locations.DataReferenceBox.DataEntryUrlBox.size, sizeof(u32), 1, imf); + fwrite(&meta.file_locations.DataReferenceBox.DataEntryUrlBox.type, sizeof(u32), 1, imf); + fwrite(&meta.file_locations.DataReferenceBox.DataEntryUrlBox.flags, sizeof(u32), 1, imf); + */ + //Item Location Box + fwrite(&meta.item_locations.size, sizeof(u32), 1, imf); + fwrite(&meta.item_locations.type, sizeof(u32), 1, imf); + fwrite(&meta.item_locations.version, sizeof(u32), 1, imf); + fwrite(&meta.item_locations.offset_size, sizeof(unsigned char), 1, imf); + //fwrite(&meta.item_locations.lenght_size, sizeof(unsigned char), 1, imf); + fwrite(&meta.item_locations.base_offset_size, sizeof(unsigned char), 1, imf); + //fwrite(&meta.item_locations.reserved, sizeof(unsigned char), 1, imf); + fwrite(&meta.item_locations.item_count, sizeof(u16), 1, imf); + fwrite(&meta.item_locations.item_ID, sizeof(u16), 1, imf); + fwrite(&meta.item_locations.data_reference_index, sizeof(u16), 1, imf); + fwrite(&meta.item_locations.base_offset, sizeof(u32), 1, imf); + fwrite(&meta.item_locations.extent_count, sizeof(u16), 1, imf); + fwrite(&meta.item_locations.extent_offset, sizeof(u32), 1, imf); + fwrite(&meta.item_locations.extent_length, sizeof(u32), 1, imf); + //Item Info + fwrite(&meta.item_infos.size, sizeof(u32), 1, imf); + fwrite(&meta.item_infos.type, sizeof(u32), 1, imf); + fwrite(&meta.item_infos.version, sizeof(u32), 1, imf); + fwrite(&meta.item_infos.entry_count, sizeof(u16), 1, imf); + //Info Entry + fwrite(&meta.item_infos.info_entry.size, sizeof(u32), 1, imf); + fwrite(&meta.item_infos.info_entry.type, sizeof(u32), 1, imf); + fwrite(&meta.item_infos.info_entry.version, sizeof(u32), 1, imf); + fwrite(&meta.item_infos.info_entry.item_ID, sizeof(u16), 1, imf); + fwrite(&meta.item_infos.info_entry.item_protection_index, sizeof(u16), 1, imf); + for (i=0; i<6; i++){ + fwrite(&meta.item_infos.info_entry.item_name[i], sizeof(char), 1, imf); + } + for (i=0; i<18; i++){ + fwrite(&meta.item_infos.info_entry.content_type[i], sizeof(char), 1, imf); + } + for (i=0; i<4; i++){ + fwrite(&meta.item_infos.info_entry.content_encoding[i], sizeof(char), 1, imf); + } + //XML for metadata + fwrite(&meta.XMLBox.size, sizeof(u32), 1, imf); + fwrite(&meta.XMLBox.type, sizeof(u32), 1, imf); + fwrite(&meta.XMLBox.version, sizeof(u32), 1, imf); + for(i=0; i<2000; i++){ + fwrite(&meta.XMLBox.string[i], sizeof(char), 1, imf); + } + +} + +//TIMED-TEXT's funcionts +int trackstructure_text (MovieBox *moov, int numtrack, int clock, + int durationTrack, int sizemdat, const char *textfile,FILE *text,int totaltracks ) { // creates the text trak structure + int swap; + u32 sizeURL; + u32 sizeDREF; + u32 sizeDINF; + u32 sizeSMHD; + u32 sizeMINF; + u32 sizeHDLR; + u32 sizeMDHD; + u32 sizeMDIA; + u32 sizeTKHD; + u32 sizeTRAK; + + + //Sample Table Box + int sizeSTBL = 0; + + sizeSTBL = samplecontainer_text(moov, numtrack,sizemdat, textfile,totaltracks); + + //Data Entry Url Box + sizeURL = 12; + swap = bytereverse(sizeURL); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox. + DataReferenceBox.DataEntryUrlBox.size = swap; + swap = bytereverse('url '); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox. + DataReferenceBox.DataEntryUrlBox.type = swap; + swap = bytereverse(1); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox. + DataReferenceBox.DataEntryUrlBox.flags = swap; // =1 Track in same file as movie atom. + + //Data Reference + sizeDREF = sizeURL+ 16; + swap = bytereverse(sizeDREF); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox. + DataReferenceBox.size = swap; + swap = bytereverse('dref'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox. + DataReferenceBox.type = swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox. + DataReferenceBox.flags = 0; + swap = bytereverse(1); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox. + DataReferenceBox.entry_count = swap; + + //Data information Box// + sizeDINF = sizeDREF + 8; + swap = bytereverse(sizeDINF); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.size = swap; + swap = bytereverse('dinf'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.type = swap; + + + //Null Media Header Box + swap = bytereverse(12); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.NullMediaHeaderBox.size = swap ; + swap = bytereverse ('nmhd'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.NullMediaHeaderBox.type = swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.NullMediaHeaderBox.flags = 0; + + //Media Information Box// + sizeMINF = sizeDINF + sizeSTBL + 8 + 12; + swap = bytereverse(sizeMINF); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.size = swap; + swap = bytereverse('minf'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.type = swap; + + //Handler Box// + sizeHDLR = 37; + swap = bytereverse(sizeHDLR); + moov->TrackBox[numtrack].MediaBox.HandlerBox.size = swap; + swap = bytereverse('hdlr'); + moov->TrackBox[numtrack].MediaBox.HandlerBox.type = swap; + moov->TrackBox[numtrack].MediaBox.HandlerBox.version = 0; + moov->TrackBox[numtrack].MediaBox.HandlerBox.pre_defined = 0; + swap = bytereverse('text'); + moov->TrackBox[numtrack].MediaBox.HandlerBox.handler_type = swap; + moov->TrackBox[numtrack].MediaBox.HandlerBox.reserved[0] = 0; + moov->TrackBox[numtrack].MediaBox.HandlerBox.reserved[1] = 0; + moov->TrackBox[numtrack].MediaBox.HandlerBox.reserved[2] = 0; + moov->TrackBox[numtrack].MediaBox.HandlerBox.data[0] = 't'; + moov->TrackBox[numtrack].MediaBox.HandlerBox.data[1] = 'e'; + moov->TrackBox[numtrack].MediaBox.HandlerBox.data[2] = 'x'; + moov->TrackBox[numtrack].MediaBox.HandlerBox.data[3] = 't'; + moov->TrackBox[numtrack].MediaBox.HandlerBox.data[4] = '\0'; + + //Media Header Box// + sizeMDHD = 32; + swap = bytereverse(sizeMDHD); + moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.size = swap; + swap = bytereverse('mdhd'); + moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.type = swap; + moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.version = 0; + swap = bytereverse(clock); + moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.creation_time = swap; + moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.modification_time = swap; + swap = bytereverse(1000); + moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.timescale = swap; + swap = bytereverse(durationTrack); + moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.duration = swap; + moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.language = 0xC455; + moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.pre_defined = 0; + + //Media Box// + sizeMDIA = sizeMDHD + sizeHDLR + sizeMINF + 8; + swap = bytereverse(sizeMDIA); + moov->TrackBox[numtrack].MediaBox.size = swap; + swap = bytereverse('mdia'); + moov->TrackBox[numtrack].MediaBox.type = swap; + + //Track Header// + sizeTKHD = 92; + swap = bytereverse (sizeTKHD); + moov->TrackBox[numtrack].TrackHeaderBox.size = swap; + swap = bytereverse ('tkhd'); + moov->TrackBox[numtrack].TrackHeaderBox.type = swap ; + swap = bytereverse (0x00000007); + moov->TrackBox[numtrack].TrackHeaderBox.version = swap; + swap = bytereverse (clock); + moov->TrackBox[numtrack].TrackHeaderBox.creation_time = swap; + moov->TrackBox[numtrack].TrackHeaderBox.modification_time = swap; + moov->TrackBox[numtrack].TrackHeaderBox.track_ID = bytereverse(12345678); + moov->TrackBox[numtrack].TrackHeaderBox.reserved = 0; + swap = bytereverse (durationTrack); + moov->TrackBox[numtrack].TrackHeaderBox.duration = swap; + moov->TrackBox[numtrack].TrackHeaderBox.reserved2[0] = 0; + moov->TrackBox[numtrack].TrackHeaderBox.reserved2[1] = 0; + moov->TrackBox[numtrack].TrackHeaderBox.layer = 0; + moov->TrackBox[numtrack].TrackHeaderBox.alternate_group = 0; + moov->TrackBox[numtrack].TrackHeaderBox.volume = 0; + moov->TrackBox[numtrack].TrackHeaderBox.reserved3 = 0; + swap = bytereverse (0x00010000); + moov->TrackBox[numtrack].TrackHeaderBox.matrix[0] = swap; + moov->TrackBox[numtrack].TrackHeaderBox.matrix[1] = 0; + moov->TrackBox[numtrack].TrackHeaderBox.matrix[2] = 0; + moov->TrackBox[numtrack].TrackHeaderBox.matrix[3] = 0; + moov->TrackBox[numtrack].TrackHeaderBox.matrix[4] = swap; + moov->TrackBox[numtrack].TrackHeaderBox.matrix[5] = 0; + moov->TrackBox[numtrack].TrackHeaderBox.matrix[6] = 0; + moov->TrackBox[numtrack].TrackHeaderBox.matrix[7] = 0; + swap = bytereverse(0x40000000); + moov->TrackBox[numtrack].TrackHeaderBox.matrix[8] = swap; + moov->TrackBox[numtrack].TrackHeaderBox.width =0; + moov->TrackBox[numtrack].TrackHeaderBox.height = 0; + + //Track container + sizeTRAK = sizeTKHD + sizeMDIA + 8; + swap = bytereverse (sizeTRAK); // Size of one track + moov->TrackBox[numtrack].size = swap; + swap = bytereverse ('trak'); + moov->TrackBox[numtrack].type = swap; + + return sizeTRAK; +} + + +int aux (FILE *text,int num,int num1,int num2,int num3,int *sal) { + int dat=0,dat1=0,dat2=0,dat3=0,size=0,d=0,cnt=0,i=0; + fseek(text,0,SEEK_SET); + d=0; + while(d==0){ + + fread (&dat,sizeof(unsigned char),1,text); + cnt++; + fread (&dat1,sizeof(unsigned char),1,text); + cnt++; + fread (&dat2,sizeof(unsigned char),1,text); + cnt++; + fread (&dat3,sizeof(unsigned char),1,text); + cnt++; + fseek(text, -3 ,SEEK_CUR); + if(dat == num && dat1 == num1 && dat2 == num2 && dat3 == num3){ + + d=1; + } + + else{ + + cnt=cnt-3; + } + + } //end while + + + fseek (text,0,SEEK_SET);//positionate the pointer at first + + cnt=cnt-7;//size is located 7 bytes before type + for (d=1;d<=cnt;d++){ + + fread (&dat,sizeof(unsigned char),1,text); + + } + fread (&dat1,sizeof(unsigned char),1,text); + fread (&dat2,sizeof(unsigned char),1,text); + fread (&dat3,sizeof(unsigned char),1,text); + + size = (dat<<24) | (dat1<<16) | (dat2<<8) | (dat3); + + for (i=1;i<=8;i++) { //advance sample_size + fread (&dat,sizeof(unsigned char),1,text); + } + fread(&dat,1,1,text); + fread(&dat1,1,1,text); + fread(&dat2,1,1,text); + fread(&dat3,1,1,text); + + *sal = (dat<<24) | (dat1<<16) | (dat2<<8) | (dat3); + + + return size; + +} + +int samplecontainer_text(MovieBox *moov, int numtrack, int sizemdat,const char *textfiles,int totaltracks) { + + u32 sizeSTSD, sizeSTSZ, swap,i=0; + u32 sizeSTTS; + u32 sizeSTSC = 0; + u32 sizeSTCO = 0; + u32 sizeSTBL=0; + int dat=0,dat1=0,dat2=0,dat3=0,sal=0, samplecount=0; + + //Sample Description Box// + FILE *text; + + text=fopen ( textfiles,"rb"); + fseek(text,0,SEEK_CUR); + + //stsd + + sizeSTSD =16+64; + swap = bytereverse(sizeSTSD); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.size = swap; + swap = bytereverse('stsd'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.type = swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.version = 0; + swap = bytereverse(1); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleDescriptionBox.entry_count = swap; + + + //tx3g + swap = bytereverse(64); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.size=swap; + swap = bytereverse('tx3g'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.type=swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.a=0; + swap=bytereverse(1); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.b=swap; + swap = bytereverse(0x00000800);//continuous karaoke + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.displayFlags = swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.horizontaljustification=0x01; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.verticaljustification=0x01; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.backgroundcolorrgba[0]= 0x00; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.backgroundcolorrgba[1]= 0x00; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.backgroundcolorrgba[2]= 0x00; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.backgroundcolorrgba[3]= 0xFF; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.top=0; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.left=0; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.bottom=0x6400; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.right=0x2C01; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.startChar=0; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.endChar=0; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.fontID=0x0100; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.facestyleflags=0x01; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.fontsize=0x0A; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.textcolorrgba[0]=0xFF; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.textcolorrgba[1]=0xFF; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.textcolorrgba[2]=0xFF; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.textcolorrgba[3]=0xFF; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.FontTableBox.size =0x12000000; + swap =bytereverse('ftab'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.FontTableBox.type =swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.FontTableBox.entrycount=0x0100; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.FontTableBox.fontID =0x0200; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.FontTableBox.fontnamelenght =0x05; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.FontTableBox.font[0] =0x53; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.FontTableBox.font[1] =0x65; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.FontTableBox.font[2] =0x72; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.FontTableBox.font[3] =0x69; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleDescriptionBox.TextSampleEntry.FontTableBox.font[4] =0x66; + + //stsz + + sizeSTSZ=aux(text,0x73,0x74,0x73,0x7A,&sal)+4; // the function aux looks for the box stsz in 3gp file and returns the size + swap = bytereverse('stsz'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.type = swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.version = 0; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleSizeBox.sample_size=0; + + fseek(text,0,SEEK_CUR); + + fread(&dat,1,1,text); //read sample_count + fread(&dat1,1,1,text); + fread(&dat2,1,1,text); + fread(&dat3,1,1,text); + + samplecount = (dat<<24) | (dat1<<16) | (dat2<<8) | (dat3); + + swap= bytereverse(samplecount); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleSizeBox.sample_count=swap; + + for (i=1;i<=samplecount;i++){ + + swap = bytereverse(size_phrase[i-1]); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleSizeBox.entry_size[i-1]=swap; + } + + sizeSTSZ= 20 + bytereverse(moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleSizeBox.sample_count)*4; + swap = bytereverse(sizeSTSZ); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleSizeBox.size = swap; + + + //Time To Sample Box// + + fseek (text,0,SEEK_SET);//positionate the pointer at first + sizeSTTS=aux(text,0x73,0x74,0x74,0x73,&sal); + + swap = bytereverse(sizeSTTS); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.size = swap; + swap = bytereverse('stts'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.type = swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + TimeToSampleBox.version = 0; + swap = bytereverse(sal); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.TimeToSampleBox.entry_count=swap; + fseek(text,0,SEEK_CUR); + for(i=1;i<=sal;i++){ + + fread(&dat,1,1,text);//read count + fread(&dat1,1,1,text); + fread(&dat2,1,1,text); + fread(&dat3,1,1,text); + + dat = (dat<<24) | (dat1<<16) | (dat2<<8) | (dat3); + + + swap = bytereverse(dat); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.TimeToSampleBox.sample_count[i-1]=swap; + fread(&dat,1,1,text);//read delta + + fread(&dat1,1,1,text); + + fread(&dat2,1,1,text); + + fread(&dat3,1,1,text); + + + dat = (dat<<24) | (dat1<<16) | (dat2<<8) | (dat3); + + swap = bytereverse(dat/0.6);// the input text file has time_scale = 600 but the audio has time scale=1000 + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.TimeToSampleBox.sample_delta[i-1]=swap; + } + + //Sample To Chunk// + + dat=0; + fseek (text,0,SEEK_SET);//positionate the pointer at first + sizeSTSC = aux(text,0x73,0x74,0x73,0x63,&sal); + dat=sal; + swap = bytereverse(sizeSTSC); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.size = swap; + swap = bytereverse('stsc'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.type = swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.version = 0; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + SampleToChunk.entry_count = bytereverse(1); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleToChunk.first_chunk=bytereverse(1); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleToChunk.samples_per_chunk=moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleSizeBox.sample_count; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.SampleToChunk.sample_description_index = bytereverse(1); + + //Chunk Offset Box// + sizeSTCO=24; + swap = bytereverse(sizeSTCO); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + ChunkOffsetBox.size = swap; + swap = bytereverse('co64'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + ChunkOffsetBox.type = swap; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + ChunkOffsetBox.version = 0; + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + ChunkOffsetBox.entry_count = bytereverse(1); + dat=32+sizemdat*totaltracks; + swap=bytereverse(dat); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox. + ChunkOffsetBox.chunk_offset [0]= swap; + + //Sample Table Box // + sizeSTBL = 8 + sizeSTSD + sizeSTSZ + sizeSTSC + sizeSTCO + sizeSTTS; + swap = bytereverse(sizeSTBL); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.size = swap; + swap = bytereverse('stbl'); + moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.type =swap; + return sizeSTBL; +} + +//AUX Functions for endianness + +int bytereverse(int num) { + int swapped; + swapped = ((num>>24)&0xff) | // move byte 3 to byte 0 + ((num<<8)&0xff0000) | // move byte 1 to byte 2 + ((num>>8)&0xff00) | // move byte 2 to byte 1 + ((num<<24)&0xff000000); // byte 0 to byte 3 + return swapped; +} +int bytereverse16(int num) { + int swapped; + swapped = ( ((num<<8)&0xff00) | // move byte 1 to byte 2 + ((num>>8)&0x00ff) ); // byte 2 to byte 1 + return swapped; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/IMAFencoder.h Mon Nov 04 17:15:52 2013 +0000 @@ -0,0 +1,609 @@ +#ifndef IMAFENCODER_H +#define IMAFENCODER_H + +//***********************************************************// +// Interactive Music Audio Format (IMAF) ENCODER // +// Version 2.0 // +// // +// Eugenio Oñate Hospital // +// Costantino Taglialatela & Jesus Corral Garcìa // +// // +// Copyright (c) 2013 Centre for Digital Music (C4DM) // +// Queen Mary University of London. All rights reserved. // +//***********************************************************// +// IM_AF Encoder.h // +//***********************************************************// + + +/* for FILE typedef, */ +#include <stdio.h> + +#define maxtracks 8 //change this value to support more than 8 audio tracks. This value was 6 before I changed it +#define maxgroups 2 +#define maxpreset 10 +#define maxrules 10 +#define maxfilters 3 //Max number of Filters for an EQ preset +#define maxdynamic 2 //Max number of Dynamic Volume changes +#define num_ch 2 //Number of channel outputs (STEREO) + +typedef long long u64; +typedef unsigned int u32; +typedef unsigned short u16; +typedef unsigned char u8; + +//typedef struct nametrack { // Stores the different titles of the tracks +// char title[20]; +//}nametrack[maxtracks]; + +typedef struct FileTypeBox +{ + u32 size; + u32 type; // ftyp + u32 major_brand; // brand identifier + u32 minor_version; // informative integer for the mirror version + u32 compatible_brands[2]; //list of brands +}FileTypeBox; + +typedef struct MovieBox //extends Box('moov') +{ + u32 size; + u32 type; // moov + + struct MovieHeaderBox + { + u32 size; + u32 type; // mvhd + u32 version; // version + flag + u32 creation_time; + u32 modification_time; + u32 timescale; // specifies the time-scale + u32 duration; + u32 rate; // typically 1.0 + u16 volume; // typically full volume + u16 reserved; // =0 + u32 reserved2[2]; //=0 + u32 matrix[9]; // information matrix for video (u,v,w) + u32 pre_defined[6]; // =0 + u32 next_track_ID; //non zero value for the next track ID + }MovieHeaderBox; + + struct TrackBox + { + u32 size; + u32 type; + struct TrackHeaderBox + { + u32 size; + u32 type; + u32 version; // version + flag + u32 creation_time; + u32 modification_time; + u32 track_ID; + u32 reserved; // =0 + u32 duration; + u32 reserved2[2]; // =0 + u16 layer; // =0 // for video + u16 alternate_group; // =0 + u16 volume; // full volume is 1 = 0x0100 + u16 reserved3;// =0 + u32 matrix[9]; // for video + u32 width; // video + u32 height; // video + }TrackHeaderBox; + + struct MediaBox // extends Box('mdia') + { + u32 size; + u32 type; + struct MediaHeaderBox // extends FullBox('mdhd', version,0) + { + u32 size; + u32 type; + u32 version; // version + flag + u32 creation_time; + u32 modification_time; + u32 timescale; + u32 duration; + u16 language; // [pad,5x3] = 16 bits and pad = 0 + u16 pre_defined; // =0 + }MediaHeaderBox; + struct HandlerBox // extends FullBox('hdlr') + { + u32 size; + u32 type; + u32 version; // version = 0 + flag + u32 pre_defined; // =0 + u32 handler_type; // = 'soun' for audio track, text or hint + u32 reserved[3]; // =0 + unsigned char data[5]; // Does not work! only 4 bytes + + }HandlerBox; + struct MediaInformationBox //extends Box('minf') + { + u32 size; + u32 type; + // smhd in sound track only!! + struct SoundMediaHeaderBox //extends FullBox('smhd') + { + u32 size; + u32 type; + u32 version; + u16 balance; // =0 place mono tracks in stereo. 0 is center + u16 reserved; // =0 + }SoundMediaHeaderBox; + struct NullMediaHeaderBox //extends FullBox('nmhd') + { + u32 size; + u32 type; + u32 flags; + }NullMediaHeaderBox; + struct DataInformationBox //extends Box('dinf') + { + u32 size; + u32 type; + struct DataReferenceBox + { + u32 size; + u32 type; + u32 flags; + u32 entry_count; // counts the actual entries. + struct DataEntryUrlBox //extends FullBox('url', version=0, flags) + { + u32 size; + u32 type; + u32 flags; + }DataEntryUrlBox; + }DataReferenceBox; + }DataInformationBox; + struct SampleTableBox // extends Box('stbl') + { + u32 size; + u32 type; + struct TimeToSampleBox{ + u32 size; + u32 type; + u32 version; + u32 entry_count; + u32 sample_count[3000]; + u32 sample_delta[3000]; + }TimeToSampleBox; + struct SampleDescriptionBox // stsd + { + u32 size; + u32 type; + u32 version; + u32 entry_count; // = 1 number of entries + // unsigned char esds[88]; + struct TextSampleEntry{ + u32 size; + u32 type; //tx3g + u32 a; + u32 b; + u32 displayFlags; + u8 horizontaljustification; + u8 verticaljustification; + u8 backgroundcolorrgba[4]; + u16 top; + u16 left; + u16 bottom; + u16 right; + //StyleRecord + u16 startChar; + u16 endChar; + u16 fontID; + u8 facestyleflags; + u8 fontsize; + u8 textcolorrgba[4]; + struct FontTableBoX{ + u32 size; + u32 type; + u16 entrycount; + u16 fontID; + u8 fontnamelenght; + u8 font[5]; //Serif + }FontTableBox; + }TextSampleEntry; + struct AudioSampleEntry{ + u32 size; + u32 type; //mp4a + char reserved[6]; + u16 data_reference_index; // = 1 + u32 reserved2[2]; + u16 channelcount; // = 2 + u16 samplesize; // = 16 + u32 reserved3; + u32 samplerate; // 44100 << 16 + // unsigned char esds[81]; + struct ESbox{ + u32 size; + u32 type; + u32 version; + struct ES_Descriptor{ + unsigned char tag; + unsigned char length; + u16 ES_ID; + unsigned char mix; + struct DecoderConfigDescriptor{ + unsigned char tag; + unsigned char length; + unsigned char objectProfileInd; + u32 mix; + u32 maxBitRate; + u32 avgBitrate; + /* struct DecoderSpecificInfo{ + unsigned char tag; + unsigned length; + // unsigned char decSpecificInfosize; + unsigned char decSpecificInfoData[2]; + }DecoderSpecificInfo; + */ }DecoderConfigDescriptor; + struct SLConfigDescriptor{ + unsigned char tag; + unsigned char length; + unsigned char predifined; + }SLConfigDescriptor; + }ES_Descriptor; + }ESbox; + }AudioSampleEntry; + }SampleDescriptionBox; + struct SampleSizeBox{ + u32 size; + u32 type; + u32 version; + u32 sample_size; // =0 + u32 sample_count; + u32 entry_size[9000]; + }SampleSizeBox; + struct SampleToChunk{ + u32 size; + u32 type; + u32 version; + u32 entry_count; + u32 first_chunk; + u32 samples_per_chunk; + u32 sample_description_index; + }SampleToChunk; + struct ChunkOffsetBox{ + u32 size; + u32 type; + u32 version; + u32 entry_count; + u32 chunk_offset[maxtracks]; + }ChunkOffsetBox; + }SampleTableBox; + }MediaInformationBox; + }MediaBox; + }TrackBox[maxtracks]; // max 10 tracks + + struct PresetContainerBox // extends Box('prco') + { + u32 size; + u32 type; + unsigned char num_preset; + unsigned char default_preset_ID; + struct PresetBox //extends FullBox('prst',version=0,flags) + { + u32 size; + u32 type; + u32 flags; + unsigned char preset_ID; + unsigned char num_preset_elements; + struct presElemId{ + u32 preset_element_ID; + }presElemId[maxtracks]; + unsigned char preset_type; + unsigned char preset_global_volume; + + // if (preset_type == 0) || (preset_type == 8) - Static track volume preset + struct StaticTrackVolume{ + struct presVolumElem{ + u8 preset_volume_element; + struct EQ{ // if preset_type == 8 (with EQ) + u8 num_eq_filters; + struct Filter{ + u8 filter_type; + u16 filter_reference_frequency; + u8 filter_gain; + u8 filter_bandwidth; + }Filter[maxfilters]; + }EQ; + }presVolumElem[maxtracks]; + }StaticTrackVolume; + + // if (preset_type == 1) || (preset_type == 9) - Static object volume preset + struct StaticObjectVolume{ + struct InputCH{ + u8 num_input_channel; + }InputCH[maxtracks]; + u8 output_channel_type; + struct presElVol_1{ + struct Input{ + struct Output{ + u8 preset_volume_element; + }Output[num_ch]; + struct EQ_1{ // if preset_type == 9 (with EQ) + u8 num_eq_filters; + struct Filter_1{ + u8 filter_type; + u16 filter_reference_frequency; + u8 filter_gain; + u8 filter_bandwidth; + }Filter[maxfilters]; + }EQ; + }Input[num_ch]; + }presElVol[maxtracks]; + }StaticObjectVolume; + + // if (preset_type == 2) || (preset_type == 10) - Dynamic track volume preset + struct DynamicTrackVolume{ + u16 num_updates; + struct DynamicChange{ + u16 updated_sample_number; + struct presVolumElem_2{ + u8 preset_volume_element; + struct EQ_2{ // if preset_type == 10 (with EQ) + u8 num_eq_filters; + struct Filter_2{ + u8 filter_type; + u16 filter_reference_frequency; + u8 filter_gain; + u8 filter_bandwidth; + }Filter[maxfilters]; + }EQ; + }presVolumElem[maxtracks]; + }DynamicChange[maxdynamic]; + }DynamicTrackVolume; + + // if (preset_type == 3) || (preset_type == 11) - Dynamic object volume preset + struct DynamicObjectVolume{ + u16 num_updates; + struct InputCH_3{ + u8 num_input_channel; + }InputCH[maxtracks]; + u8 output_channel_type; + struct DynamicChange_3{ + u16 updated_sample_number; + struct presElVol{ + struct Input_3{ + struct Output_3{ + u8 preset_volume_element; + }Output[num_ch]; + struct EQ_3{ // if preset_type == 11 (with EQ) + u8 num_eq_filters; + struct Filter_3{ + u8 filter_type; + u16 filter_reference_frequency; + u8 filter_gain; + u8 filter_bandwidth; + }Filter[maxfilters]; + }EQ; + }Input[num_ch]; + }presElVol[maxtracks]; + }DynamicChange[maxdynamic]; + }DynamicObjectVolume; + + // if (preset_type == 4) || (preset_type == 12) - Dynamic track approximated volume preset + struct DynamicTrackApproxVolume{ + u16 num_updates; + struct DynamicChange_4{ + u16 start_sample_number; + u16 duration_update; + struct presElVol_4{ + u8 end_preset_volume_element; + struct EQ_4{ // if preset_type == 12 (with EQ) + u8 num_eq_filters; + struct Filter_4{ + u8 filter_type; + u16 filter_reference_frequency; + u8 end_filter_gain; + u8 filter_bandwidth; + }Filter[maxfilters]; + }EQ; + }presElVol[maxtracks]; + }DynamicChange[maxdynamic]; + }DynamicTrackApproxVolume; + + // if (preset_type == 5) || (preset_type == 13) - Dynamic object approximated volume preset + // THIS STRUCTURE GIVES STACK OVERFLOW PROBLEMS - MORE STACK SIZE NEEDED -> Needs investigation + struct DynamicObjectApproxVolume{ + u16 num_updates; + struct InputCH_5{ + u8 num_input_channel; + }InputCH[maxtracks]; + u8 output_channel_type; + struct DynamicChange_5{ + u16 start_sample_number; + u16 duration_update; + struct presElVol_5{ + struct Input_5{ + struct Output_5{ + u8 preset_volume_element; + }Output[num_ch]; + struct EQ_5{ // if preset_type == 11 (with EQ) + u8 num_eq_filters; + struct Filter_5{ + u8 filter_type; + u16 filter_reference_frequency; + u8 end_filter_gain; + u8 filter_bandwidth; + }Filter[maxfilters]; + }EQ; + }Input[num_ch]; + }presElVol[maxtracks]; + }DynamicChange[maxdynamic]; + }DynamicObjectApproxVolume; + + char preset_name[50]; + + }PresetBox[maxpreset]; + + }PresetContainerBox; + + struct RulesContainer{ + u32 size; + u32 type; + u16 num_selection_rules; + u16 num_mixing_rules; + struct SelectionRules{ + u32 size; + u32 type; + u32 version; + u16 selection_rule_ID; + unsigned char selection_rule_type; + u32 element_ID; + // Only for Min/Max Rule + // if (selection_rule_type==0) + u16 min_num_elements; + u16 max_num_elements; + // Only for Exclusion and Implication Rules + // if (selection_rule_type==1 || selection_rule_type==3) + u32 key_element_ID; + char rule_description[20]; + }SelectionRules; + struct MixingRules{ + u32 size; + u32 type; + u32 version; + u16 mixing_rule_ID; + unsigned char mixing_type; + u32 element_ID; + u16 min_volume; + u16 max_volume; + u32 key_elem_ID; + char mix_description[17]; + }MixingRules; + }RulesContainer; + struct GroupContainerBox{ //extends Box('grco') + u32 size; // = 10 + sizeGRUP + u32 type; + u16 num_groups; + struct GroupBox{ // extends FullBox('grup') + u32 size; // = 21 + 22 + 32 (+2 if group_activation_mode = 2) + u32 type; + u32 version; + u32 group_ID; + u16 num_elements; + struct groupElemId{ + u32 element_ID; + }groupElemId[maxtracks]; + unsigned char group_activation_mode; + u16 group_activation_elements_number; + u16 group_reference_volume; + char group_name[22]; + char group_description[32]; + }GroupBox[maxgroups]; + }GroupContainerBox; +}MovieBox; + +typedef struct MetaBox // extends FullBox ('meta') +{ + u32 size; + u32 type; + u32 version; + struct theHandler //extends FullBox HandlerBox('hdlr') + { + u32 size; + u32 type; + u32 version; // version = 0 + flag + u32 pre_defined; // =0 + u32 handler_type; // = 'meta' for Timed Metadata track + u32 reserved[3]; // =0 + unsigned char name[4]; + }theHandler; + struct file_locations //extends Box DataInformationBox('dinf') + { + u32 size; + u32 type; +/* struct DataReferenceBox2 + { + u32 size; + u32 type; + u32 flags; + u32 entry_count; // = 1 + struct DataEntryUrlBox2 //extends FullBox('url', version=0, flags) + { + u32 size; + u32 type; + u32 flags; + }DataEntryUrlBox; + }DataReferenceBox; */ + }file_locations; + struct item_locations //extends FullBox ItemLocationBox('iloc') + { + u32 size; + u32 type; + u32 version; // version = 0 + flags + unsigned char offset_size; // = 4 bytes + unsigned char lenght_size; // = 4 bytes + unsigned char base_offset_size; // = 4 bytes + unsigned char reserved; // = 0 + u16 item_count; // = 1 + u16 item_ID; // = 1 + u16 data_reference_index; // = 0 (this file) + u32 base_offset; // size=(base_offset_size*8)=4*8 + u16 extent_count; // = 1 + u32 extent_offset; // size=(offset_size*8)=4*8 + u32 extent_length; // size=(lenght_size*8)=4*8 + }item_locations; + struct item_infos //extends FullBox ItemInfoBox('iinf') + { + u32 size; + u32 type; + u32 version; // version = 0 + flag + u16 entry_count; // = 1 + struct info_entry// extends FullBox ItemInfoEntry('infe') + { + u32 size; + u32 type; + u32 version; // = 0 + u16 item_ID; // = 1 + u16 item_protection_index; // = 0 for "unprotected" + char item_name[6]; // name with max 5 characters + char content_type[18]; // = 'application/other' -> 17 characters + char content_encoding[4]; // = 'jpg' for JPEG image -> 3 characters + }info_entry; + }item_infos; + struct XMLBox // extends FullBox('xml ') + { + u32 size; + u32 type; + u32 version; + char string[2000]; + }XMLBox; +}MetaBox; + +typedef struct MediaDataBox // extends Box('mdat') +{ + u32 size; + u32 type; + unsigned char data; +}MediaDataBox; + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#endif // IMAFENCODER_H
--- a/main/MainWindow.cpp Mon Nov 04 17:13:35 2013 +0000 +++ b/main/MainWindow.cpp Mon Nov 04 17:15:52 2013 +0000 @@ -5,7 +5,7 @@ An audio file viewer and annotation editor. Centre for Digital Music, Queen Mary, University of London. This file copyright 2006-2007 Chris Cannam and QMUL. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the @@ -13,6 +13,7 @@ COPYING included with this distribution for more information. */ + #include "../version.h" #include "MainWindow.h" @@ -127,6 +128,23 @@ using std::map; using std::set; +//IMAF REQUIRED LIBRARIES AND VARIABLES +#include "IMAFencoder.c" +#include "checkbox.h" +#include <QFileDialog> +#include "imafdecoder.cpp" + +QString ImafFileName,ImageFileName,TextFileName; //name of the files +QString files_paths[maxtracks]; // change maxtracks in IMAFencoder.h +int ImafVolumeValues[maxtracks]; +int numtracks; +bool has_image, has_lyrics; +int selrule_type, selrule_par1, selrule_par2; +int mixrule_type, mixrule_par1, mixrule_par2, mixrule_par3, mixrule_par4; +int group_tracks[maxtracks], group_volume; +QString group_descr, group_name; +int preset_type, fade_in; + MainWindow::MainWindow(bool withAudioOutput, bool withOSCSupport) : MainWindowBase(withAudioOutput, withOSCSupport, true), @@ -244,7 +262,7 @@ m_playSpeed->setRangeMapper(new PlaySpeedRangeMapper(0, 200)); m_playSpeed->setShowToolTip(true); connect(m_playSpeed, SIGNAL(valueChanged(int)), - this, SLOT(playSpeedChanged(int))); + this, SLOT(playSpeedChanged(int))); connect(m_playSpeed, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget())); connect(m_playSpeed, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget())); @@ -263,7 +281,7 @@ layout->addWidget(m_playSpeed, 1, 3); layout->addWidget(m_fader, 1, 4); - m_playControlsWidth = + m_playControlsWidth = m_fader->width() + m_playSpeed->width() + layout->spacing() * 2; layout->setColumnMinimumWidth(0, 14); @@ -303,12 +321,12 @@ connect(m_midiInput, SIGNAL(eventsAvailable()), this, SLOT(midiEventsAvailable())); - + TransformFactory::getInstance()->startPopulationThread(); - m_versionTester = new VersionTester + VersionTester *vt = new VersionTester ("sonicvisualiser.org", "/latest-version.txt", SV_VERSION); - connect(m_versionTester, SIGNAL(newerVersionAvailable(QString)), + connect(vt, SIGNAL(newerVersionAvailable(QString)), this, SLOT(newerVersionAvailable(QString))); } @@ -319,7 +337,6 @@ delete m_activityLog; delete m_preferencesDialog; delete m_layerTreeDialog; - delete m_versionTester; Profiles::getInstance()->dump(); // SVDEBUG << "MainWindow::~MainWindow finishing" << endl; } @@ -485,7 +502,7 @@ m_keyReference->registerShortcut(action); menu->addAction(action); toolbar->addAction(action); - + icon = il.load("filesaveas"); icon.addPixmap(il.loadPixmap("filesaveas-22")); action = new QAction(icon, tr("Save Session &As..."), this); @@ -519,6 +536,19 @@ connect(this, SIGNAL(canExportAudio(bool)), action, SLOT(setEnabled(bool))); menu->addAction(action); + QAction *actionCreateIMAF = new QAction(tr("&Export IMAF File..."), this); + actionCreateIMAF->setStatusTip(tr("Export selection as an IMAF file")); + menu->addAction(actionCreateIMAF); + connect(actionCreateIMAF,SIGNAL(triggered()),this,SLOT(exportIMAF())); + + QAction *actionOpenIMAF = new QAction(tr("&Import IMAF File..."), this); + actionOpenIMAF->setStatusTip(tr("Import IMAF file")); + menu->addAction(actionOpenIMAF); + connect(actionOpenIMAF,SIGNAL(triggered()),this,SLOT(importIMAF())); + + + + menu->addSeparator(); action = new QAction(tr("Import Annotation &Layer..."), this); @@ -571,7 +601,7 @@ action->setStatusTip(tr("Adjust the application preferences")); connect(action, SIGNAL(triggered()), this, SLOT(preferences())); menu->addAction(action); - + menu->addSeparator(); action = new QAction(il.load("exit"), tr("&Quit"), this); @@ -658,7 +688,7 @@ m_keyReference->registerShortcut(action); menu->addAction(action); m_rightButtonMenu->addAction(action); - + action = new QAction(tr("Select &Visible Range"), this); action->setShortcut(tr("Ctrl+Shift+A")); action->setStatusTip(tr("Select the time range corresponding to the current window width")); @@ -666,7 +696,7 @@ connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); m_keyReference->registerShortcut(action); menu->addAction(action); - + action = new QAction(tr("Select to &Start"), this); action->setShortcut(tr("Shift+Left")); action->setStatusTip(tr("Select from the start of the session to the current playback position")); @@ -674,7 +704,7 @@ connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); m_keyReference->registerShortcut(action); menu->addAction(action); - + action = new QAction(tr("Select to &End"), this); action->setShortcut(tr("Shift+Right")); action->setStatusTip(tr("Select from the current playback position to the end of the session")); @@ -773,7 +803,7 @@ action->setStatusTip(tr("Set the counters used for counter-based labelling")); connect(action, SIGNAL(triggered()), this, SLOT(resetInstantsCounters())); menu->addAction(action); - + action = new QAction(tr("Renumber Selected Instants"), this); action->setStatusTip(tr("Renumber the selected instants using the current labelling scheme")); connect(action, SIGNAL(triggered()), this, SLOT(renumberInstants())); @@ -802,7 +832,7 @@ connect(this, SIGNAL(canScroll(bool)), m_scrollLeftAction, SLOT(setEnabled(bool))); m_keyReference->registerShortcut(m_scrollLeftAction); menu->addAction(m_scrollLeftAction); - + m_scrollRightAction = new QAction(tr("Scroll &Right"), this); m_scrollRightAction->setShortcut(tr("Right")); m_scrollRightAction->setStatusTip(tr("Scroll the current pane to the right")); @@ -810,7 +840,7 @@ connect(this, SIGNAL(canScroll(bool)), m_scrollRightAction, SLOT(setEnabled(bool))); m_keyReference->registerShortcut(m_scrollRightAction); menu->addAction(m_scrollRightAction); - + action = new QAction(tr("&Jump Left"), this); action->setShortcut(tr("Ctrl+Left")); action->setStatusTip(tr("Scroll the current pane a big step to the left")); @@ -818,7 +848,7 @@ connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); m_keyReference->registerShortcut(action); menu->addAction(action); - + action = new QAction(tr("J&ump Right"), this); action->setShortcut(tr("Ctrl+Right")); action->setStatusTip(tr("Scroll the current pane a big step to the right")); @@ -834,7 +864,7 @@ connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); m_keyReference->registerShortcut(action); menu->addAction(action); - + action = new QAction(tr("Peek Right"), this); action->setShortcut(tr("Alt+Right")); action->setStatusTip(tr("Scroll the current pane to the right without moving the playback cursor or other panes")); @@ -855,7 +885,7 @@ connect(this, SIGNAL(canZoom(bool)), m_zoomInAction, SLOT(setEnabled(bool))); m_keyReference->registerShortcut(m_zoomInAction); menu->addAction(m_zoomInAction); - + m_zoomOutAction = new QAction(il.load("zoom-out"), tr("Zoom &Out"), this); m_zoomOutAction->setShortcut(tr("Down")); @@ -864,7 +894,7 @@ connect(this, SIGNAL(canZoom(bool)), m_zoomOutAction, SLOT(setEnabled(bool))); m_keyReference->registerShortcut(m_zoomOutAction); menu->addAction(m_zoomOutAction); - + action = new QAction(tr("Restore &Default Zoom"), this); action->setStatusTip(tr("Restore the zoom level to the default")); connect(action, SIGNAL(triggered()), this, SLOT(zoomDefault())); @@ -903,7 +933,7 @@ menu->addSeparator(); QActionGroup *overlayGroup = new QActionGroup(this); - + action = new QAction(tr("Show &No Overlays"), this); action->setShortcut(tr("0")); action->setStatusTip(tr("Hide times, layer names, and scale")); @@ -913,7 +943,7 @@ overlayGroup->addAction(action); m_keyReference->registerShortcut(action); menu->addAction(action); - + action = new QAction(tr("Show &Minimal Overlays"), this); action->setShortcut(tr("9")); action->setStatusTip(tr("Show times and basic scale")); @@ -923,7 +953,7 @@ overlayGroup->addAction(action); m_keyReference->registerShortcut(action); menu->addAction(action); - + action = new QAction(tr("Show &All Overlays"), this); action->setShortcut(tr("8")); action->setStatusTip(tr("Show times, layer names, and scale")); @@ -935,7 +965,7 @@ menu->addAction(action); menu->addSeparator(); - + action = new QAction(tr("Show &Zoom Wheels"), this); action->setShortcut(tr("Z")); action->setStatusTip(tr("Show thumbwheels for zooming horizontally and vertically")); @@ -998,18 +1028,18 @@ MainWindow::setupPaneAndLayerMenus() { if (m_paneMenu) { - m_paneActions.clear(); - m_paneMenu->clear(); + m_paneActions.clear(); + m_paneMenu->clear(); } else { - m_paneMenu = menuBar()->addMenu(tr("&Pane")); + m_paneMenu = menuBar()->addMenu(tr("&Pane")); m_paneMenu->setTearOffEnabled(true); } if (m_layerMenu) { - m_layerActions.clear(); - m_layerMenu->clear(); + m_layerActions.clear(); + m_layerMenu->clear(); } else { - m_layerMenu = menuBar()->addMenu(tr("&Layer")); + m_layerMenu = menuBar()->addMenu(tr("&Layer")); m_layerMenu->setTearOffEnabled(true); } @@ -1043,44 +1073,43 @@ // menu->addSeparator(); LayerFactory::LayerTypeSet emptyLayerTypes = - LayerFactory::getInstance()->getValidEmptyLayerTypes(); + LayerFactory::getInstance()->getValidEmptyLayerTypes(); for (LayerFactory::LayerTypeSet::iterator i = emptyLayerTypes.begin(); - i != emptyLayerTypes.end(); ++i) { - - QIcon icon; - QString mainText, tipText, channelText; - LayerFactory::LayerType type = *i; - QString name = LayerFactory::getInstance()->getLayerPresentationName(type); - - icon = il.load(LayerFactory::getInstance()->getLayerIconName(type)); - - mainText = tr("Add New %1 Layer").arg(name); - tipText = tr("Add a new empty layer of type %1").arg(name); - - action = new QAction(icon, mainText, this); - action->setStatusTip(tipText); - - if (type == LayerFactory::Text) { - action->setShortcut(tr("T")); + i != emptyLayerTypes.end(); ++i) { + + QIcon icon; + QString mainText, tipText, channelText; + LayerFactory::LayerType type = *i; + QString name = LayerFactory::getInstance()->getLayerPresentationName(type); + + icon = il.load(LayerFactory::getInstance()->getLayerIconName(type)); + + mainText = tr("Add New %1 Layer").arg(name); + tipText = tr("Add a new empty layer of type %1").arg(name); + + action = new QAction(icon, mainText, this); + action->setStatusTip(tipText); + + if (type == LayerFactory::Text) { + action->setShortcut(tr("T")); m_keyReference->registerShortcut(action); - } - - connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); - connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); - m_layerActions[action] = LayerConfiguration(type); - menu->addAction(action); - m_rightButtonLayerMenu->addAction(action); } - + connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); + connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); + m_layerActions[action] = LayerConfiguration(type); + menu->addAction(action); + m_rightButtonLayerMenu->addAction(action); + } + m_rightButtonLayerMenu->addSeparator(); menu->addSeparator(); LayerFactory::LayerType backgroundTypes[] = { - LayerFactory::Waveform, - LayerFactory::Spectrogram, - LayerFactory::MelodicRangeSpectrogram, - LayerFactory::PeakFrequencySpectrogram, + LayerFactory::Waveform, + LayerFactory::Spectrogram, + LayerFactory::MelodicRangeSpectrogram, + LayerFactory::PeakFrequencySpectrogram, LayerFactory::Spectrum }; @@ -1092,24 +1121,24 @@ } for (unsigned int i = 0; - i < sizeof(backgroundTypes)/sizeof(backgroundTypes[0]); ++i) { + i < sizeof(backgroundTypes)/sizeof(backgroundTypes[0]); ++i) { const int paneMenuType = 0, layerMenuType = 1; - for (int menuType = paneMenuType; menuType <= layerMenuType; ++menuType) { - - if (menuType == paneMenuType) menu = m_paneMenu; - else menu = m_layerMenu; - - QMenu *submenu = 0; + for (int menuType = paneMenuType; menuType <= layerMenuType; ++menuType) { + + if (menuType == paneMenuType) menu = m_paneMenu; + else menu = m_layerMenu; + + QMenu *submenu = 0; QIcon icon; QString mainText, shortcutText, tipText, channelText; LayerFactory::LayerType type = backgroundTypes[i]; bool mono = true; - + switch (type) { - + case LayerFactory::Waveform: icon = il.load("waveform"); mainText = tr("Add &Waveform"); @@ -1122,7 +1151,7 @@ } mono = false; break; - + case LayerFactory::Spectrogram: icon = il.load("spectrogram"); mainText = tr("Add Spectro&gram"); @@ -1134,7 +1163,7 @@ tipText = tr("Add a new layer showing a spectrogram"); } break; - + case LayerFactory::MelodicRangeSpectrogram: icon = il.load("spectrogram"); mainText = tr("Add &Melodic Range Spectrogram"); @@ -1146,7 +1175,7 @@ tipText = tr("Add a new layer showing a spectrogram set up for an overview of note pitches"); } break; - + case LayerFactory::PeakFrequencySpectrogram: icon = il.load("spectrogram"); mainText = tr("Add Pea&k Frequency Spectrogram"); @@ -1158,7 +1187,7 @@ tipText = tr("Add a new layer showing a spectrogram set up for tracking frequencies"); } break; - + case LayerFactory::Spectrum: icon = il.load("spectrum"); mainText = tr("Add Spectr&um"); @@ -1170,16 +1199,16 @@ tipText = tr("Add a new layer showing a frequency spectrum"); } break; - + default: break; } std::vector<Model *> candidateModels = models; - + for (std::vector<Model *>::iterator mi = candidateModels.begin(); mi != candidateModels.end(); ++mi) { - + Model *model = *mi; int channels = 0; @@ -1224,9 +1253,9 @@ m_keyReference->registerShortcut(action); } menu->addAction(action); - + } else { - + if (!submenu) { submenu = menu->addMenu(mainText); submenu->setTearOffEnabled(true); @@ -1254,7 +1283,7 @@ if (isDefault) { action = new QAction(icon, actionText, this); if (!model || model == getMainModel()) { - action->setShortcut(shortcutText); + action->setShortcut(shortcutText); } } else { action = new QAction(actionText, this); @@ -1295,9 +1324,9 @@ m_layerActions[action] = LayerConfiguration(type, 0, 0); m_rightButtonLayerMenu->addAction(action); } - } - } - } + } + } + } } m_rightButtonLayerMenu->addSeparator(); @@ -1411,7 +1440,7 @@ m_transformActionsReverse.clear(); m_transformsMenu->clear(); } else { - m_transformsMenu = menuBar()->addMenu(tr("&Transform")); + m_transformsMenu = menuBar()->addMenu(tr("&Transform")); m_transformsMenu->setTearOffEnabled(true); m_transformsMenu->setSeparatorsCollapsible(true); } @@ -1437,7 +1466,7 @@ m_transformsMenu->addSeparator(); m_rightButtonTransformsMenu->addSeparator(); - + for (vector<TransformDescription::Type>::iterator i = types.begin(); i != types.end(); ++i) { @@ -1539,9 +1568,9 @@ } for (unsigned int i = 0; i < transforms.size(); ++i) { - - QString name = transforms[i].name; - if (name == "") name = transforms[i].identifier; + + QString name = transforms[i].name; + if (name == "") name = transforms[i].identifier; // std::cerr << "Plugin Name: " << name << std::endl; @@ -1568,11 +1597,11 @@ .arg(output); } - QAction *action = new QAction(tr("%1...").arg(name), this); - connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); - m_transformActions[action] = transforms[i].identifier; + QAction *action = new QAction(tr("%1...").arg(name), this); + connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); + m_transformActions[action] = transforms[i].identifier; m_transformActionsReverse[transforms[i].identifier] = action; - connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); + connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); action->setStatusTip(transforms[i].longDescription); @@ -1611,7 +1640,7 @@ if (output == "") { parentMenu->addAction(pluginName, action); } else { - pluginNameMenus[type][pluginName] = + pluginNameMenus[type][pluginName] = parentMenu->addMenu(pluginName); connect(this, SIGNAL(canAddLayer(bool)), pluginNameMenus[type][pluginName], @@ -1650,7 +1679,7 @@ { QMenu *menu = menuBar()->addMenu(tr("&Help")); menu->setTearOffEnabled(true); - + m_keyReference->setCategory(tr("Help")); IconLoader il; @@ -1658,9 +1687,9 @@ QString name = QApplication::applicationName(); QAction *action = new QAction(il.load("help"), - tr("&Help Reference"), this); + tr("&Help Reference"), this); action->setShortcut(tr("F1")); - action->setStatusTip(tr("Open the %1 reference manual").arg(name)); + action->setStatusTip(tr("Open the %1 reference manual").arg(name)); connect(action, SIGNAL(triggered()), this, SLOT(help())); m_keyReference->registerShortcut(action); menu->addAction(action); @@ -1671,14 +1700,14 @@ connect(action, SIGNAL(triggered()), this, SLOT(keyReference())); m_keyReference->registerShortcut(action); menu->addAction(action); - - action = new QAction(tr("%1 on the &Web").arg(name), this); - action->setStatusTip(tr("Open the %1 website").arg(name)); + + action = new QAction(tr("%1 on the &Web").arg(name), this); + action->setStatusTip(tr("Open the %1 website").arg(name)); connect(action, SIGNAL(triggered()), this, SLOT(website())); menu->addAction(action); - - action = new QAction(tr("&About %1").arg(name), this); - action->setStatusTip(tr("Show information about %1").arg(name)); + + action = new QAction(tr("&About %1").arg(name), this); + action->setStatusTip(tr("Show information about %1").arg(name)); connect(action, SIGNAL(triggered()), this, SLOT(about())); menu->addAction(action); } @@ -1689,8 +1718,8 @@ m_recentFilesMenu->clear(); vector<QString> files = m_recentFiles.getRecent(); for (size_t i = 0; i < files.size(); ++i) { - QAction *action = new QAction(files[i], this); - connect(action, SIGNAL(triggered()), this, SLOT(openRecentFile())); + QAction *action = new QAction(files[i], this); + connect(action, SIGNAL(triggered()), this, SLOT(openRecentFile())); if (i == 0) { action->setShortcut(tr("Ctrl+R")); m_keyReference->registerShortcut @@ -1698,7 +1727,7 @@ action->shortcut().toString(), tr("Re-open the current or most recently opened file")); } - m_recentFilesMenu->addAction(action); + m_recentFilesMenu->addAction(action); } } @@ -1776,7 +1805,7 @@ } else { ti->second->setShortcut(QString("")); } - m_recentTransformsMenu->addAction(ti->second); + m_recentTransformsMenu->addAction(ti->second); } } @@ -1803,49 +1832,49 @@ for (int i = 0; i < m_paneStack->getPaneCount(); ++i) { - Pane *pane = m_paneStack->getPane(i); - if (!pane) continue; - - for (int j = 0; j < pane->getLayerCount(); ++j) { - - Layer *layer = pane->getLayer(j); - if (!layer) continue; - if (observedLayers.find(layer) != observedLayers.end()) { + Pane *pane = m_paneStack->getPane(i); + if (!pane) continue; + + for (int j = 0; j < pane->getLayerCount(); ++j) { + + Layer *layer = pane->getLayer(j); + if (!layer) continue; + if (observedLayers.find(layer) != observedLayers.end()) { // std::cerr << "found duplicate layer " << layer << std::endl; - continue; - } - -// std::cerr << "found new layer " << layer << " (name = " + continue; + } + +// std::cerr << "found new layer " << layer << " (name = " // << layer->getLayerPresentationName() << ")" << std::endl; - orderedLayers.push_back(layer); - observedLayers.insert(layer); + orderedLayers.push_back(layer); + observedLayers.insert(layer); if (factory->isLayerSliceable(layer)) { sliceableLayers.insert(layer); } - } } + } map<QString, int> observedNames; for (size_t i = 0; i < orderedLayers.size(); ++i) { - + Layer *layer = orderedLayers[i]; - QString name = layer->getLayerPresentationName(); - int n = ++observedNames[name]; - if (n > 1) name = QString("%1 <%2>").arg(name).arg(n); - - QIcon icon = il.load(factory->getLayerIconName + QString name = layer->getLayerPresentationName(); + int n = ++observedNames[name]; + if (n > 1) name = QString("%1 <%2>").arg(name).arg(n); + + QIcon icon = il.load(factory->getLayerIconName (factory->getLayerType(layer))); - QAction *action = new QAction(icon, name, this); - connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); - connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); - m_existingLayerActions[action] = layer; - - m_existingLayersMenu->addAction(action); + QAction *action = new QAction(icon, name, this); + connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); + connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); + m_existingLayerActions[action] = layer; + + m_existingLayersMenu->addAction(action); if (sliceableLayers.find(layer) != sliceableLayers.end()) { action = new QAction(icon, name, this); @@ -1899,7 +1928,7 @@ m_playAction->setStatusTip(tr("Start or stop playback from the current position")); connect(m_playAction, SIGNAL(triggered()), this, SLOT(play())); connect(m_playSource, SIGNAL(playStatusChanged(bool)), - m_playAction, SLOT(setChecked(bool))); + m_playAction, SLOT(setChecked(bool))); connect(m_playSource, SIGNAL(playStatusChanged(bool)), this, SLOT(playStatusChanged(bool))); connect(this, SIGNAL(canPlay(bool)), m_playAction, SLOT(setEnabled(bool))); @@ -2019,7 +2048,7 @@ fastAction->setStatusTip(tr("Time-stretch playback to speed it up without changing pitch")); connect(fastAction, SIGNAL(triggered()), this, SLOT(speedUpPlayback())); connect(this, SIGNAL(canSpeedUpPlayback(bool)), fastAction, SLOT(setEnabled(bool))); - + QAction *slowAction = menu->addAction(tr("Slow Down")); slowAction->setShortcut(tr("Ctrl+PgDown")); slowAction->setStatusTip(tr("Time-stretch playback to slow it down without changing pitch")); @@ -2060,7 +2089,7 @@ m_toolActions[ViewManager::NavigateMode] = action; action = toolbar->addAction(il.load("select"), - tr("Select")); + tr("Select")); action->setCheckable(true); action->setShortcut(tr("2")); action->setStatusTip(tr("Select ranges")); @@ -2070,7 +2099,7 @@ m_toolActions[ViewManager::SelectMode] = action; action = toolbar->addAction(il.load("move"), - tr("Edit")); + tr("Edit")); action->setCheckable(true); action->setShortcut(tr("3")); action->setStatusTip(tr("Edit items in layer")); @@ -2081,7 +2110,7 @@ m_toolActions[ViewManager::EditMode] = action; action = toolbar->addAction(il.load("draw"), - tr("Draw")); + tr("Draw")); action->setCheckable(true); action->setShortcut(tr("4")); action->setStatusTip(tr("Draw new items in layer")); @@ -2092,7 +2121,7 @@ m_toolActions[ViewManager::DrawMode] = action; action = toolbar->addAction(il.load("erase"), - tr("Erase")); + tr("Erase")); action->setCheckable(true); action->setShortcut(tr("5")); action->setStatusTip(tr("Erase items from layer")); @@ -2148,20 +2177,20 @@ (haveCurrentPane && (currentLayer != 0)); bool havePlayTarget = - (m_playTarget != 0); - bool haveSelection = - (m_viewManager && - !m_viewManager->getSelections().empty()); + (m_playTarget != 0); + bool haveSelection = + (m_viewManager && + !m_viewManager->getSelections().empty()); bool haveCurrentEditableLayer = - (haveCurrentLayer && - currentLayer->isLayerEditable()); - bool haveCurrentTimeInstantsLayer = - (haveCurrentLayer && - dynamic_cast<TimeInstantLayer *>(currentLayer)); - bool haveCurrentTimeValueLayer = - (haveCurrentLayer && - dynamic_cast<TimeValueLayer *>(currentLayer)); - + (haveCurrentLayer && + currentLayer->isLayerEditable()); + bool haveCurrentTimeInstantsLayer = + (haveCurrentLayer && + dynamic_cast<TimeInstantLayer *>(currentLayer)); + bool haveCurrentTimeValueLayer = + (haveCurrentLayer && + dynamic_cast<TimeValueLayer *>(currentLayer)); + bool alignMode = m_viewManager && m_viewManager->getAlignMode(); emit canChangeSolo(havePlayTarget && !alignMode); emit canAlign(havePlayTarget && m_document && m_document->canAlign()); @@ -2171,7 +2200,7 @@ emit canSpeedUpPlayback(v < m_playSpeed->maximum()); emit canSlowDownPlayback(v > m_playSpeed->minimum()); - if (m_viewManager && + if (m_viewManager && (m_viewManager->getToolMode() == ViewManager::MeasureMode)) { emit canDeleteSelection(haveCurrentLayer); m_deleteSelectedAction->setText(tr("&Delete Current Measurement")); @@ -2206,8 +2235,8 @@ MainWindow::updateDescriptionLabel() { if (!getMainModel()) { - m_descriptionLabel->setText(tr("No audio file loaded.")); - return; + m_descriptionLabel->setText(tr("No audio file loaded.")); + return; } QString description; @@ -2217,15 +2246,15 @@ if (m_playSource) tsr = m_playSource->getTargetSampleRate(); if (ssr != tsr) { - description = tr("%1Hz (resampling to %2Hz)").arg(ssr).arg(tsr); + description = tr("%1Hz (resampling to %2Hz)").arg(ssr).arg(tsr); } else { - description = QString("%1Hz").arg(ssr); + description = QString("%1Hz").arg(ssr); } description = QString("%1 - %2") - .arg(RealTime::frame2RealTime(getMainModel()->getEndFrame(), ssr) - .toText(false).c_str()) - .arg(description); + .arg(RealTime::frame2RealTime(getMainModel()->getEndFrame(), ssr) + .toText(false).c_str()) + .arg(description); m_descriptionLabel->setText(description); } @@ -2286,11 +2315,11 @@ QString path = getOpenFileName(FileFinder::AudioFile); if (path != "") { - if (openAudio(path, ReplaceSession) == FileOpenFailed) { + if (openAudio(path, ReplaceSession) == FileOpenFailed) { emit hideSplash(); - QMessageBox::critical(this, tr("Failed to open file"), - tr("<b>File open failed</b><p>Audio file \"%1\" could not be opened").arg(path)); - } + QMessageBox::critical(this, tr("Failed to open file"), + tr("<b>File open failed</b><p>Audio file \"%1\" could not be opened").arg(path)); + } } } @@ -2300,12 +2329,14 @@ QString path = getOpenFileName(FileFinder::AudioFile); if (path != "") { - if (openAudio(path, CreateAdditionalModel) == FileOpenFailed) { + if (openAudio(path, CreateAdditionalModel) == FileOpenFailed) { emit hideSplash(); - QMessageBox::critical(this, tr("Failed to open file"), - tr("<b>File open failed</b><p>Audio file \"%1\" could not be opened").arg(path)); - } + QMessageBox::critical(this, tr("Failed to open file"), + tr("<b>File open failed</b><p>Audio file \"%1\" could not be opened").arg(path)); + } } + + files_paths[int(m_paneStack->getPaneCount())-1] = path; } void @@ -2314,11 +2345,11 @@ QString path = getOpenFileName(FileFinder::AudioFile); if (path != "") { - if (openAudio(path, ReplaceMainModel) == FileOpenFailed) { + if (openAudio(path, ReplaceMainModel) == FileOpenFailed) { emit hideSplash(); - QMessageBox::critical(this, tr("Failed to open file"), - tr("<b>File open failed</b><p>Audio file \"%1\" could not be opened").arg(path)); - } + QMessageBox::critical(this, tr("Failed to open file"), + tr("<b>File open failed</b><p>Audio file \"%1\" could not be opened").arg(path)); + } } } @@ -2339,7 +2370,7 @@ if (!layer) continue; cerr << "layer = " << layer->objectName() << endl; Model *m = layer->getModel(); - RangeSummarisableTimeValueModel *wm = + RangeSummarisableTimeValueModel *wm = dynamic_cast<RangeSummarisableTimeValueModel *>(m); if (wm) { cerr << "found: " << wm->objectName() << endl; @@ -2401,35 +2432,35 @@ if (selections.size() == 1) { - QStringList items; - items << tr("Export the selected region only") - << tr("Export the whole audio file"); - - bool ok = false; - QString item = ListInputDialog::getItem - (this, tr("Select region to export"), - tr("Which region from the original audio file do you want to export?"), - items, 0, &ok); - - if (!ok || item.isEmpty()) return; - - if (item == items[0]) selectionToWrite = &ms; + QStringList items; + items << tr("Export the selected region only") + << tr("Export the whole audio file"); + + bool ok = false; + QString item = ListInputDialog::getItem + (this, tr("Select region to export"), + tr("Which region from the original audio file do you want to export?"), + items, 0, &ok); + + if (!ok || item.isEmpty()) return; + + if (item == items[0]) selectionToWrite = &ms; } else if (selections.size() > 1) { - QStringList items; - items << tr("Export the selected regions into a single audio file") - << tr("Export the selected regions into separate files") - << tr("Export the whole audio file"); - - QString item = ListInputDialog::getItem - (this, tr("Select region to export"), - tr("Multiple regions of the original audio file are selected.\nWhat do you want to export?"), - items, 0, &ok); - - if (!ok || item.isEmpty()) return; - - if (item == items[0]) { + QStringList items; + items << tr("Export the selected regions into a single audio file") + << tr("Export the selected regions into separate files") + << tr("Export the whole audio file"); + + QString item = ListInputDialog::getItem + (this, tr("Select region to export"), + tr("Multiple regions of the original audio file are selected.\nWhat do you want to export?"), + items, 0, &ok); + + if (!ok || item.isEmpty()) return; + + if (item == items[0]) { selectionToWrite = &ms; @@ -2437,37 +2468,37 @@ multiple = true; - int n = 1; - QString base = path; - base.replace(".wav", ""); - - for (MultiSelection::SelectionList::iterator i = selections.begin(); - i != selections.end(); ++i) { - - MultiSelection subms; - subms.setSelection(*i); - - QString subpath = QString("%1.%2.wav").arg(base).arg(n); - ++n; - - if (QFileInfo(subpath).exists()) { - error = tr("Fragment file %1 already exists, aborting").arg(subpath); - break; - } - - WavFileWriter subwriter(subpath, + int n = 1; + QString base = path; + base.replace(".wav", ""); + + for (MultiSelection::SelectionList::iterator i = selections.begin(); + i != selections.end(); ++i) { + + MultiSelection subms; + subms.setSelection(*i); + + QString subpath = QString("%1.%2.wav").arg(base).arg(n); + ++n; + + if (QFileInfo(subpath).exists()) { + error = tr("Fragment file %1 already exists, aborting").arg(subpath); + break; + } + + WavFileWriter subwriter(subpath, model->getSampleRate(), model->getChannelCount(), WavFileWriter::WriteToTemporary); subwriter.writeModel(model, &subms); - ok = subwriter.isOK(); - - if (!ok) { - error = subwriter.getError(); - break; - } - } - } + ok = subwriter.isOK(); + + if (!ok) { + error = subwriter.getError(); + break; + } + } + } } if (!multiple) { @@ -2476,8 +2507,8 @@ model->getChannelCount(), WavFileWriter::WriteToTemporary); writer.writeModel(model, selectionToWrite); - ok = writer.isOK(); - error = writer.getError(); + ok = writer.isOK(); + error = writer.getError(); } if (ok) { @@ -2488,25 +2519,28 @@ m_recentFiles.addFile(path); } } else { - QMessageBox::critical(this, tr("Failed to write file"), error); + QMessageBox::critical(this, tr("Failed to write file"), error); } } + + + void MainWindow::importLayer() { Pane *pane = m_paneStack->getCurrentPane(); - + if (!pane) { - // shouldn't happen, as the menu action should have been disabled - std::cerr << "WARNING: MainWindow::importLayer: no current pane" << std::endl; - return; + // shouldn't happen, as the menu action should have been disabled + std::cerr << "WARNING: MainWindow::importLayer: no current pane" << std::endl; + return; } if (!getMainModel()) { - // shouldn't happen, as the menu action should have been disabled - std::cerr << "WARNING: MainWindow::importLayer: No main model -- hence no default sample rate available" << std::endl; - return; + // shouldn't happen, as the menu action should have been disabled + std::cerr << "WARNING: MainWindow::importLayer: No main model -- hence no default sample rate available" << std::endl; + return; } QString path = getOpenFileName(FileFinder::LayerFile); @@ -2514,7 +2548,7 @@ if (path != "") { FileOpenStatus status = openLayer(path); - + if (status == FileOpenFailed) { emit hideSplash(); QMessageBox::critical(this, tr("Failed to open file"), @@ -2627,7 +2661,7 @@ { Pane *pane = m_paneStack->getCurrentPane(); if (!pane) return; - + QString path = getSaveFileName(FileFinder::ImageFile); if (path == "") return; @@ -2642,7 +2676,7 @@ pane->getLastVisibleFrame()); size_t sf0 = 0, sf1 = 0; - + if (haveSelection) { MultiSelection::SelectionList selections = m_viewManager->getSelections(); sf0 = selections.begin()->getStartFrame(); @@ -2686,7 +2720,7 @@ bool ok = lid->exec(); QString item = lid->getCurrentString(); delete lid; - + if (!ok || item.isEmpty()) return; settings.setValue("lastimageexportregion", deflt); @@ -2708,7 +2742,7 @@ QMessageBox::critical(this, tr("Failed to save image file"), tr("Failed to save image file %1").arg(path)); } - + delete image; } @@ -2726,8 +2760,8 @@ this, SLOT(contextHelpChanged(const QString &))); if (!m_timeRulerLayer) { - m_timeRulerLayer = m_document->createMainModelLayer - (LayerFactory::TimeRuler); + m_timeRulerLayer = m_document->createMainModelLayer + (LayerFactory::TimeRuler); } m_document->addLayerToView(pane, m_timeRulerLayer); @@ -2759,29 +2793,29 @@ while (m_paneStack->getPaneCount() > 0) { - Pane *pane = m_paneStack->getPane(m_paneStack->getPaneCount() - 1); - - while (pane->getLayerCount() > 0) { - m_document->removeLayerFromView - (pane, pane->getLayer(pane->getLayerCount() - 1)); - } - - m_overview->unregisterView(pane); - m_paneStack->deletePane(pane); + Pane *pane = m_paneStack->getPane(m_paneStack->getPaneCount() - 1); + + while (pane->getLayerCount() > 0) { + m_document->removeLayerFromView + (pane, pane->getLayer(pane->getLayerCount() - 1)); } + m_overview->unregisterView(pane); + m_paneStack->deletePane(pane); + } + while (m_paneStack->getHiddenPaneCount() > 0) { - Pane *pane = m_paneStack->getHiddenPane - (m_paneStack->getHiddenPaneCount() - 1); - - while (pane->getLayerCount() > 0) { - m_document->removeLayerFromView - (pane, pane->getLayer(pane->getLayerCount() - 1)); - } - - m_overview->unregisterView(pane); - m_paneStack->deletePane(pane); + Pane *pane = m_paneStack->getHiddenPane + (m_paneStack->getHiddenPaneCount() - 1); + + while (pane->getLayerCount() > 0) { + m_document->removeLayerFromView + (pane, pane->getLayer(pane->getLayerCount() - 1)); + } + + m_overview->unregisterView(pane); + m_paneStack->deletePane(pane); } delete m_layerTreeDialog.data(); @@ -2818,8 +2852,8 @@ if (openSessionFile(path) == FileOpenFailed) { emit hideSplash(); - QMessageBox::critical(this, tr("Failed to open file"), - tr("<b>File open failed</b><p>Session file \"%1\" could not be opened").arg(path)); + QMessageBox::critical(this, tr("Failed to open file"), + tr("<b>File open failed</b><p>Session file \"%1\" could not be opened").arg(path)); } } @@ -2845,6 +2879,11 @@ QMessageBox::critical(this, tr("Failed to open file"), tr("<b>Audio required</b><p>Unable to load layer data from \"%1\" without an audio file.<br>Please load at least one audio file before importing annotations.").arg(path)); } + + files_paths[0] = path; + QTextStream out(stdout); + out << path; + } void @@ -2884,11 +2923,11 @@ { QObject *obj = sender(); QAction *action = dynamic_cast<QAction *>(obj); - + if (!action) { - std::cerr << "WARNING: MainWindow::openRecentFile: sender is not an action" - << std::endl; - return; + std::cerr << "WARNING: MainWindow::openRecentFile: sender is not an action" + << std::endl; + return; } QString path = action->text(); @@ -2914,9 +2953,9 @@ QAction *action = qobject_cast<QAction *>(s); if (!action) { - std::cerr << "WARNING: MainWindow::applyTemplate: sender is not an action" - << std::endl; - return; + std::cerr << "WARNING: MainWindow::applyTemplate: sender is not an action" + << std::endl; + return; } QString n = action->objectName(); @@ -2953,14 +2992,14 @@ layout->addWidget(lineEdit, 1, 0); QCheckBox *makeDefault = new QCheckBox(tr("Set as default template for future audio files")); layout->addWidget(makeDefault, 2, 0); - + QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); layout->addWidget(bb, 3, 0); connect(bb, SIGNAL(accepted()), d, SLOT(accept())); connect(bb, SIGNAL(accepted()), d, SLOT(accept())); connect(bb, SIGNAL(rejected()), d, SLOT(reject())); - + if (d->exec() == QDialog::Accepted) { QString name = lineEdit->text(); @@ -2998,19 +3037,19 @@ MainWindow::paneAdded(Pane *pane) { if (m_overview) m_overview->registerView(pane); -} +} void MainWindow::paneHidden(Pane *pane) { - if (m_overview) m_overview->unregisterView(pane); -} + if (m_overview) m_overview->unregisterView(pane); +} void MainWindow::paneAboutToBeDeleted(Pane *pane) { - if (m_overview) m_overview->unregisterView(pane); -} + if (m_overview) m_overview->unregisterView(pane); +} void MainWindow::paneDropAccepted(Pane *pane, QStringList uriList) @@ -3049,8 +3088,8 @@ if (pane) m_paneStack->setCurrentPane(pane); QUrl testUrl(text); - if (testUrl.scheme() == "file" || - testUrl.scheme() == "http" || + if (testUrl.scheme() == "file" || + testUrl.scheme() == "http" || testUrl.scheme() == "ftp") { QStringList list; list.push_back(text); @@ -3069,14 +3108,14 @@ if (m_openingAudioFile) { // std::cerr << "Busy - ignoring close event" << std::endl; - e->ignore(); - return; + e->ignore(); + return; } if (!m_abandoning && !checkSaveModified()) { // std::cerr << "Close refused by user - ignoring close event" << endl; - e->ignore(); - return; + e->ignore(); + return; } QSettings settings; @@ -3129,7 +3168,7 @@ } else { if (!QFileInfo(svDir).isDir()) return false; } - + // This name doesn't have to be unguessable #ifndef _WIN32 QString fname = QString("tmp-%1-%2.sv") @@ -3161,23 +3200,23 @@ emit hideSplash(); - int button = - QMessageBox::warning(this, - tr("Session modified"), - tr("<b>Session modified</b><p>The current session has been modified.<br>Do you want to save it?"), - QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, + int button = + QMessageBox::warning(this, + tr("Session modified"), + tr("<b>Session modified</b><p>The current session has been modified.<br>Do you want to save it?"), + QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, QMessageBox::Yes); if (button == QMessageBox::Yes) { - saveSession(); - if (m_documentModified) { // save failed -- don't proceed! - return false; - } else { + saveSession(); + if (m_documentModified) { // save failed -- don't proceed! + return false; + } else { return true; // saved, so it's safe to continue now } } else if (button == QMessageBox::No) { - m_documentModified = false; // so we know to abandon it - return true; + m_documentModified = false; // so we know to abandon it + return true; } // else cancel @@ -3195,7 +3234,7 @@ bool prevNewSession = settings.value("newsessionforrdfaudio", true).toBool(); settings.endGroup(); bool newSession = true; - + QStringList items; items << tr("Close the current session and create a new one") << tr("Add this data to the current session"); @@ -3205,12 +3244,12 @@ (this, tr("Select target for import"), tr("<b>Select a target for import</b><p>This RDF document refers to one or more audio files.<br>You already have an audio waveform loaded.<br>What would you like to do with the new data?"), items, prevNewSession ? 0 : 1, &ok); - + if (!ok || item.isEmpty()) { *cancel = true; return false; } - + newSession = (item == items[0]); settings.beginGroup("MainWindow"); settings.setValue("newsessionforrdfaudio", newSession); @@ -3224,15 +3263,15 @@ MainWindow::saveSession() { if (m_sessionFile != "") { - if (!saveSessionFile(m_sessionFile)) { - QMessageBox::critical(this, tr("Failed to save file"), - tr("<b>Save failed</b><p>Session file \"%1\" could not be saved.").arg(m_sessionFile)); - } else { - CommandHistory::getInstance()->documentSaved(); - documentRestored(); - } + if (!saveSessionFile(m_sessionFile)) { + QMessageBox::critical(this, tr("Failed to save file"), + tr("<b>Save failed</b><p>Session file \"%1\" could not be saved.").arg(m_sessionFile)); } else { - saveSessionAs(); + CommandHistory::getInstance()->documentSaved(); + documentRestored(); + } + } else { + saveSessionAs(); } } @@ -3248,15 +3287,15 @@ if (path == "") return; if (!saveSessionFile(path)) { - QMessageBox::critical(this, tr("Failed to save file"), - tr("<b>Save failed</b><p>Session file \"%1\" could not be saved.").arg(path)); + QMessageBox::critical(this, tr("Failed to save file"), + tr("<b>Save failed</b><p>Session file \"%1\" could not be saved.").arg(path)); } else { - setWindowTitle(tr("%1: %1") + setWindowTitle(tr("%1: %1") .arg(QApplication::applicationName()) - .arg(QFileInfo(path).fileName())); - m_sessionFile = path; - CommandHistory::getInstance()->documentSaved(); - documentRestored(); + .arg(QFileInfo(path).fileName())); + m_sessionFile = path; + CommandHistory::getInstance()->documentSaved(); + documentRestored(); m_recentFiles.addFile(path); emit activity(tr("Save session as \"%1\"").arg(path)); } @@ -3274,8 +3313,8 @@ } else { m_panLayer->setBaseColour (ColourDatabase::getInstance()->getColourIndex(tr("Green"))); - } - } + } + } } void @@ -3286,7 +3325,7 @@ if (!m_playControlsSpacer) return; int spacerWidth = width - m_playControlsWidth - 4; - + // SVDEBUG << "resizing spacer from " << m_playControlsSpacer->width() << " to " << spacerWidth << endl; m_playControlsSpacer->setFixedSize(QSize(spacerWidth, 2)); @@ -3297,19 +3336,19 @@ { QObject *s = sender(); QAction *action = dynamic_cast<QAction *>(s); - + if (!action) { - std::cerr << "WARNING: MainWindow::addPane: sender is not an action" - << std::endl; - return; + std::cerr << "WARNING: MainWindow::addPane: sender is not an action" + << std::endl; + return; } PaneActionMap::iterator i = m_paneActions.find(action); if (i == m_paneActions.end()) { - std::cerr << "WARNING: MainWindow::addPane: unknown action " - << action->objectName() << std::endl; - return; + std::cerr << "WARNING: MainWindow::addPane: unknown action " + << action->objectName() << std::endl; + return; } addPane(i->second, action->text()); @@ -3334,15 +3373,15 @@ if (configuration.layer != LayerFactory::TimeRuler && configuration.layer != LayerFactory::Spectrum) { - if (!m_timeRulerLayer) { + if (!m_timeRulerLayer) { // std::cerr << "no time ruler layer, creating one" << std::endl; - m_timeRulerLayer = m_document->createMainModelLayer - (LayerFactory::TimeRuler); - } + m_timeRulerLayer = m_document->createMainModelLayer + (LayerFactory::TimeRuler); + } // SVDEBUG << "adding time ruler layer " << m_timeRulerLayer << endl; - m_document->addLayerToView(pane, m_timeRulerLayer); + m_document->addLayerToView(pane, m_timeRulerLayer); } Layer *newLayer = m_document->createLayer(configuration.layer); @@ -3394,27 +3433,27 @@ { QObject *s = sender(); QAction *action = dynamic_cast<QAction *>(s); - + if (!action) { - std::cerr << "WARNING: MainWindow::addLayer: sender is not an action" - << std::endl; - return; + std::cerr << "WARNING: MainWindow::addLayer: sender is not an action" + << std::endl; + return; } Pane *pane = m_paneStack->getCurrentPane(); - + if (!pane) { - std::cerr << "WARNING: MainWindow::addLayer: no current pane" << std::endl; - return; + std::cerr << "WARNING: MainWindow::addLayer: no current pane" << std::endl; + return; } ExistingLayerActionMap::iterator ei = m_existingLayerActions.find(action); if (ei != m_existingLayerActions.end()) { - Layer *newLayer = ei->second; - m_document->addLayerToView(pane, newLayer); - m_paneStack->setCurrentLayer(pane, newLayer); - return; + Layer *newLayer = ei->second; + m_document->addLayerToView(pane, newLayer); + m_paneStack->setCurrentLayer(pane, newLayer); + return; } ei = m_sliceActions.find(action); @@ -3431,39 +3470,40 @@ dest, SLOT(sliceableModelReplaced(const Model *, const Model *))); connect(m_document, SIGNAL(modelAboutToBeDeleted(Model *)), dest, SLOT(modelAboutToBeDeleted(Model *))); + } - m_document->addLayerToView(pane, newLayer); - m_paneStack->setCurrentLayer(pane, newLayer); - return; + m_document->addLayerToView(pane, newLayer); + m_paneStack->setCurrentLayer(pane, newLayer); + return; } TransformActionMap::iterator i = m_transformActions.find(action); if (i == m_transformActions.end()) { - LayerActionMap::iterator i = m_layerActions.find(action); - - if (i == m_layerActions.end()) { - std::cerr << "WARNING: MainWindow::addLayer: unknown action " - << action->objectName() << std::endl; - return; - } - - LayerFactory::LayerType type = i->second.layer; - - LayerFactory::LayerTypeSet emptyTypes = - LayerFactory::getInstance()->getValidEmptyLayerTypes(); - - Layer *newLayer = 0; - - if (emptyTypes.find(type) != emptyTypes.end()) { - - newLayer = m_document->createEmptyLayer(type); + LayerActionMap::iterator i = m_layerActions.find(action); + + if (i == m_layerActions.end()) { + std::cerr << "WARNING: MainWindow::addLayer: unknown action " + << action->objectName() << std::endl; + return; + } + + LayerFactory::LayerType type = i->second.layer; + + LayerFactory::LayerTypeSet emptyTypes = + LayerFactory::getInstance()->getValidEmptyLayerTypes(); + + Layer *newLayer = 0; + + if (emptyTypes.find(type) != emptyTypes.end()) { + + newLayer = m_document->createEmptyLayer(type); if (newLayer) { m_toolActions[ViewManager::DrawMode]->trigger(); } - } else { + } else { Model *model = i->second.sourceModel; @@ -3508,7 +3548,7 @@ m_paneStack->setCurrentLayer(pane, newLayer); } - return; + return; } //!!! want to do something like this, but it's not supported in @@ -3517,11 +3557,11 @@ int channel = -1; // pick up the default channel from any existing layers on the same pane for (int j = 0; j < pane->getLayerCount(); ++j) { - int c = LayerFactory::getInstance()->getChannel(pane->getLayer(j)); - if (c != -1) { - channel = c; - break; - } + int c = LayerFactory::getInstance()->getChannel(pane->getLayer(j)); + if (c != -1) { + channel = c; + break; + } } */ @@ -3535,12 +3575,12 @@ } void -MainWindow::addLayer(QString transformId) +MainWindow:: addLayer(QString transformId) { Pane *pane = m_paneStack->getCurrentPane(); if (!pane) { - std::cerr << "WARNING: MainWindow::addLayer: no current pane" << std::endl; - return; + std::cerr << "WARNING: MainWindow::addLayer: no current pane" << std::endl; + return; } Transform transform = TransformFactory::getInstance()-> @@ -3566,7 +3606,7 @@ } if (defaultInputModel) break; } - + size_t startFrame = 0, duration = 0; size_t endFrame = 0; m_viewManager->getSelection().getExtents(startFrame, endFrame); @@ -3606,18 +3646,18 @@ { Pane *pane = m_paneStack->getCurrentPane(); if (pane) { - Layer *layer = pane->getSelectedLayer(); - if (layer) { - bool ok = false; - QString newName = QInputDialog::getText - (this, tr("Rename Layer"), - tr("New name for this layer:"), - QLineEdit::Normal, layer->objectName(), &ok); - if (ok) { - layer->setPresentationName(newName); - setupExistingLayersMenus(); - } - } + Layer *layer = pane->getSelectedLayer(); + if (layer) { + bool ok = false; + QString newName = QInputDialog::getText + (this, tr("Rename Layer"), + tr("New name for this layer:"), + QLineEdit::Normal, layer->objectName(), &ok); + if (ok) { + layer->setPresentationName(newName); + setupExistingLayersMenus(); + } + } } } @@ -3631,7 +3671,7 @@ } TransformId transform = finder->getTransform(); delete finder; - + if (getMainModel() != 0 && m_paneStack->getCurrentPane() != 0) { addLayer(transform); } @@ -3648,13 +3688,13 @@ MainWindow::alignToggled() { QAction *action = dynamic_cast<QAction *>(sender()); - + if (!m_viewManager) return; if (action) { - m_viewManager->setAlignMode(action->isChecked()); + m_viewManager->setAlignMode(action->isChecked()); } else { - m_viewManager->setAlignMode(!m_viewManager->getAlignMode()); + m_viewManager->setAlignMode(!m_viewManager->getAlignMode()); } if (m_viewManager->getAlignMode()) { @@ -3680,8 +3720,8 @@ for (int i = 0; i < m_paneStack->getPaneCount(); ++i) { - Pane *pane = m_paneStack->getPane(i); - if (!pane) continue; + Pane *pane = m_paneStack->getPane(i); + if (!pane) continue; pane->update(); } @@ -3749,7 +3789,7 @@ Layer *layer = pane->getLayer(i); if (LayerFactory::getInstance()->getLayerType(layer) == LayerFactory::Waveform) { - RangeSummarisableTimeValueModel *tvm = + RangeSummarisableTimeValueModel *tvm = dynamic_cast<RangeSummarisableTimeValueModel *>(layer->getModel()); if (tvm) { m_panLayer->setModel(tvm); @@ -3854,7 +3894,7 @@ (this, tr("Sample rate mismatch"), tr("<b>Wrong sample rate</b><p>The sample rate of this audio file (%1 Hz) does not match\nthe current playback rate (%2 Hz).<p>The file will play at the wrong speed and pitch.<p>Change the <i>Resample mismatching files on import</i> option under <i>File</i> -> <i>Preferences</i> if you want to alter this behaviour.") .arg(requested).arg(actual)); - } + } updateDescriptionLabel(); } @@ -3954,7 +3994,7 @@ if (!noteOn) continue; insertInstantAt(ev.getTime()); } -} +} void MainWindow::playStatusChanged(bool playing) @@ -4015,7 +4055,7 @@ if (!a) return; int type = m_numberingActions[a]; - + if (m_labeller) m_labeller->setType(Labeller::ValueType(type)); QSettings settings; @@ -4029,12 +4069,12 @@ { QAction *a = dynamic_cast<QAction *>(sender()); if (!a) return; - + int cycle = a->text().toInt(); if (cycle == 0) return; if (m_labeller) m_labeller->setCounterCycleSize(cycle); - + QSettings settings; settings.beginGroup("MainWindow"); settings.setValue("labellercycle", cycle); @@ -4345,7 +4385,7 @@ aboutText.replace(tr("With "), tr("Using ")); #endif - aboutText += + aboutText += "<p><small>Sonic Visualiser Copyright © 2005–2013 Chris Cannam and " "Queen Mary, University of London.</small></p>" "<p><small>This program is free software; you can redistribute it and/or " @@ -4353,7 +4393,7 @@ "published by the Free Software Foundation; either version 2 of the " "License, or (at your option) any later version.<br>See the file " "COPYING included with this distribution for more information.</small></p>"; - + QMessageBox::about(this, tr("About Sonic Visualiser"), aboutText); } @@ -4379,3 +4419,766 @@ } + +CheckBox::CheckBox(QWidget *parent) + : QWidget(parent) +{ +// SELECTION RULES + QGroupBox *selrule_box = new QGroupBox(QString::fromUtf8("SELECTION RULES"),this); + selrule_box->setFont(QFont("Times", 9, QFont::Bold)); + selrule_box->move(5,5); + selrule_box->resize(235,130); + QButtonGroup *selrule_group = new QButtonGroup(this); + selrule_group->setObjectName("Selection Rule"); + + QRadioButton *minmax_rule = new QRadioButton(QString::fromUtf8("Min/Max Rule"),this); + minmax_rule->move(20,25); + minmax_rule->setObjectName("0"); + QRadioButton *exclusion_rule = new QRadioButton(QString::fromUtf8("Exclusion Rule"),this); + exclusion_rule->move(20,45); + exclusion_rule->setObjectName("1"); + QRadioButton *notmute_rule = new QRadioButton(QString::fromUtf8("Not Mute Rule"),this); + notmute_rule->move(130,25); + notmute_rule->setObjectName("2"); + QRadioButton *implication_rule = new QRadioButton(QString::fromUtf8("Implication Rule"),this); + implication_rule->move(130,45); + implication_rule->setObjectName("3"); + + selrule_group->addButton(minmax_rule); + selrule_group->addButton(exclusion_rule); + selrule_group->addButton(notmute_rule); + selrule_group->addButton(implication_rule); + + QSpinBox *sel_par1 = new QSpinBox(this); + sel_par1->setEnabled(true); + sel_par1->setGeometry(QRect(20, 75, 40, 20)); + sel_par1->setMinimum(1); + sel_par1->setMaximum(numtracks); + selrule_par1 = sel_par1->value(); + + sel_rule1 = new QLabel(this); + sel_rule1->setText("Parameter 1"); + sel_rule1->setGeometry(70, 75, 100, 20); + + QSpinBox *sel_par2 = new QSpinBox(this); + sel_par2->setEnabled(true); + sel_par2->setGeometry(QRect(20, 100, 40, 20)); + sel_par2->setMinimum(1); + sel_par2->setMaximum(numtracks); + selrule_par2 = sel_par2->value(); + + sel_rule2 = new QLabel(this); + sel_rule2->setText("Parameter 2"); + sel_rule2->setGeometry(70, 100, 100, 20); + + connect(selrule_group, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(set_selruleType(QAbstractButton*))); + connect(sel_par1, SIGNAL(valueChanged(int)), this, SLOT(set_selrulePAR1(int))); + connect(sel_par2, SIGNAL(valueChanged(int)), this, SLOT(set_selrulePAR2(int))); + +// MIXING RULES (yet to implement) + QGroupBox *mixrule_box = new QGroupBox(QString::fromUtf8("MIXING RULES"),this); + mixrule_box->setFont(QFont("Times", 9, QFont::Bold)); + mixrule_box->move(255,5); + mixrule_box->resize(330,130); + QButtonGroup *mixrule_group = new QButtonGroup(this); + mixrule_group->setObjectName("Mixing Rule"); + + QRadioButton *equivalence_rule = new QRadioButton(QString::fromUtf8("Equivalence Rule"),this); + equivalence_rule->move(270,25); + equivalence_rule->setObjectName("0"); + QRadioButton *upper_rule = new QRadioButton(QString::fromUtf8("Upper Rule"),this); + upper_rule->move(270,45); + upper_rule->setObjectName("1"); + QRadioButton *lower_rule = new QRadioButton(QString::fromUtf8("Lower Rule"),this); + lower_rule->move(380,25); + lower_rule->setObjectName("2"); + QRadioButton *limit_rule = new QRadioButton(QString::fromUtf8("Limit Rule"),this); + limit_rule->move(380,45); + limit_rule->setObjectName("3"); + + mixrule_group->addButton(equivalence_rule); + mixrule_group->addButton(upper_rule); + mixrule_group->addButton(lower_rule); + mixrule_group->addButton(limit_rule); + + QSpinBox *mix_par1 = new QSpinBox(this); + mix_par1->setEnabled(true); + mix_par1->setGeometry(QRect(270, 75, 40, 20)); + mix_par1->setMinimum(1); + mix_par1->setMaximum(numtracks); + mixrule_par1 = mix_par1->value(); + + mix_rule1 = new QLabel(this); + mix_rule1->setText("Parameter 1"); + mix_rule1->setGeometry(320, 75, 100, 20); + + QSpinBox *mix_par2 = new QSpinBox(this); + mix_par2->setEnabled(true); + mix_par2->setGeometry(QRect(270, 100, 40, 20)); + mix_par2->setMinimum(1); + mix_par2->setMaximum(numtracks); + mixrule_par2 = mix_par2->value(); + + mix_rule2 = new QLabel(this); + mix_rule2->setText("Parameter 2"); + mix_rule2->setGeometry(320, 100, 100, 20); + + QSpinBox *mix_par3 = new QSpinBox(this); + mix_par3->setEnabled(true); + mix_par3->setGeometry(QRect(410, 75, 40, 20)); + mix_par3->setMinimum(0); + mix_par3->setMaximum(100); + mixrule_par3 = mix_par3->value(); + + mix_rule3 = new QLabel(this); + mix_rule3->setText("Parameter 3"); + mix_rule3->setGeometry(460, 75, 100, 20); + + QSpinBox *mix_par4 = new QSpinBox(this); + mix_par4->setEnabled(true); + mix_par4->setGeometry(QRect(410, 100, 40, 20)); + mix_par4->setMinimum(0); + mix_par4->setMaximum(100); + mixrule_par4 = mix_par4->value(); + + mix_rule4 = new QLabel(this); + mix_rule4->setText("Parameter 4"); + mix_rule4->setGeometry(460, 100, 100, 20); + + connect(mixrule_group, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(set_mixruleType(QAbstractButton*))); + connect(mix_par1, SIGNAL(valueChanged(int)), this, SLOT(set_mixrulePAR1(int))); + connect(mix_par2, SIGNAL(valueChanged(int)), this, SLOT(set_mixrulePAR2(int))); + connect(mix_par3, SIGNAL(valueChanged(int)), this, SLOT(set_mixrulePAR3(int))); + connect(mix_par4, SIGNAL(valueChanged(int)), this, SLOT(set_mixrulePAR4(int))); +// connect(equivalence_rule, SIGNAL(toggled(bool)), mix_rule1, SLOT() + +// GROUPS + QGroupBox *group_box = new QGroupBox(QString::fromUtf8("GROUPS"),this); + group_box->setFont(QFont("Times", 9, QFont::Bold)); + group_box->move(5,150); + group_box->resize(580,100); + + group_label = new QLabel(this); + group_label->setText("Select tracks for the group:"); + group_label->setGeometry(20, 165, 200, 20); + + QButtonGroup *group_cb = new QButtonGroup(this); + group_cb->setObjectName("Group"); + + for (int i=1; i<=numtracks; i++) { + QCheckBox *track_cb = new QCheckBox(QString::number(i), this); + track_cb->setGeometry(80*i,185,95,30); + track_cb->setObjectName(QString::number(i)); + group_cb->setExclusive(false); + group_cb->addButton(track_cb); + } + + QSpinBox *group_vol = new QSpinBox(this); + group_vol->setEnabled(true); + group_vol->setGeometry(QRect(280, 220, 40, 20)); + group_vol->setMinimum(0); + group_vol->setMaximum(100); + group_vol->setValue(100); + group_volume = group_vol->value(); + + grp_vol = new QLabel(this); + grp_vol->setText("Group Volume"); + grp_vol->setGeometry(330, 220, 100, 20); + + group_name_line = new QLineEdit(this); + group_name_line->setGeometry(25,220,150,20); + group_name_line->setText("Insert a name"); + group_name_line->setMaxLength(20); + + grp_name = new QLabel(this); + grp_name->setText("Group Name"); + grp_name->setGeometry(180,220,100,20); + + connect(group_cb, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(set_TrackInGroup(QAbstractButton*))); + connect(group_name_line, SIGNAL(textChanged(QString)), this, SLOT(set_GroupName(QString))); + connect(group_vol, SIGNAL(valueChanged(int)), this, SLOT(set_GroupVolume(int))); + +// PRESETS + QGroupBox *preset_box = new QGroupBox(QString::fromUtf8("PRESETS"),this); + preset_box->setFont(QFont("Times", 9, QFont::Bold)); + preset_box->move(5,270); + preset_box->resize(580,90); + + QButtonGroup *preset_group = new QButtonGroup(this); + preset_group->setObjectName("Presets"); + + QRadioButton *static_preset = new QRadioButton(QString::fromUtf8("Static Volume"),this); + static_preset->move(20,290); + static_preset->setObjectName("0"); + + QRadioButton *dynamic_preset = new QRadioButton(QString::fromUtf8("Dynamic Volume"),this); + dynamic_preset->move(150,290); + dynamic_preset->setObjectName("4"); + + preset_group->addButton(static_preset); + preset_group->addButton(dynamic_preset); + + QButtonGroup *fade_group = new QButtonGroup(this); + fade_group->setObjectName("Fade IN/OUT"); + + QRadioButton *fade_in = new QRadioButton(QString::fromUtf8("Fade IN"),this); + fade_in->move(170,310); + fade_in->setObjectName("1"); + fade_in->setDisabled(true); + + QRadioButton *fade_out = new QRadioButton(QString::fromUtf8("Fade OUT"),this); + fade_out->move(170,330); + fade_out->setObjectName("0"); + fade_out->setDisabled(true); + + fade_group->addButton(fade_in); + fade_group->addButton(fade_out); + + connect(preset_group, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(set_presetType(QAbstractButton*))); + connect(dynamic_preset, SIGNAL(toggled(bool)), fade_in, SLOT(setEnabled(bool))); + connect(dynamic_preset, SIGNAL(toggled(bool)), fade_out, SLOT(setEnabled(bool))); + connect(fade_group, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(set_fade(QAbstractButton*))); + + +// IMAGE AND LYRICS + QCheckBox *text_cb = new QCheckBox("Include lyrics", this); + text_cb->setGeometry(20, 380, 95, 30); + QCheckBox *jpeg_cb = new QCheckBox("Include picture", this); + jpeg_cb->setGeometry(20, 430, 95, 30); + + line->setGeometry(120, 380, 320, 30); + line2->setGeometry(120, 430, 320, 30); + + QPushButton *create = new QPushButton("Export", this); + create->setGeometry(20, 500, 95, 30); + + QPushButton *TextFilePath = new QPushButton("Select text file", this); + TextFilePath->setGeometry(460, 380, 95, 30); + TextFilePath->setDisabled(true); + + QPushButton *JpegFilePath = new QPushButton("Select JPEG file", this); + JpegFilePath->setGeometry(460, 430, 95, 30); + JpegFilePath->setDisabled(true); + + // Enable/disable push buttons + connect(text_cb, SIGNAL(toggled(bool)), TextFilePath, SLOT(setEnabled(bool))); + connect(jpeg_cb, SIGNAL(toggled(bool)), JpegFilePath, SLOT(setEnabled(bool))); + // Check the inclusion of image and text + connect(text_cb, SIGNAL(stateChanged(int)), this, SLOT(insertLyrics(int))); // yet to implement + connect(jpeg_cb, SIGNAL(stateChanged(int)), this, SLOT(insertImage(int))); + // Set image and text paths + connect(TextFilePath, SIGNAL(clicked()), this , SLOT(defineImafTextFile())); + connect(JpegFilePath, SIGNAL(clicked()), this , SLOT(defineImafImageFile())); + // Create the file + connect(create, SIGNAL(clicked()), this , SLOT(saveImafFile())); + connect(create, SIGNAL(clicked()), this, SLOT(close())); +} + +void CheckBox::insertImage(int state) +{ + if (state) { + has_image = true; + } else{ + has_image = false; + } +} + +void CheckBox::insertLyrics(int state) +{ + if (state) { + has_lyrics = true; + } else{ + has_lyrics = false; + } +} + +void CheckBox::saveImafFile() +{ + ImafFileName = QFileDialog::getSaveFileName(this, tr("Save IMAF"), "/", tr("IMAF (*.ima)")); + + group_descr = "Thisgroup"; + + if( ImafFileName != "" ){ //if the user press cancel the function mainIMAFencoder won´t be called + mainIMAFencoder(numtracks, files_paths, ImafFileName, ImageFileName, TextFileName, + ImafVolumeValues, has_image, selrule_type, selrule_par1, selrule_par2, + mixrule_type, mixrule_par1, mixrule_par2, mixrule_par3, mixrule_par4, + group_tracks, group_volume, group_name, group_descr, preset_type, fade_in); + } +} + +void CheckBox::defineImafImageFile() +{ + ImageFileName = QFileDialog::getOpenFileName(this, tr("Select JPEG"), "/", tr("JPEG (*.jpg)")); + line2->setText(ImageFileName); +} + +void CheckBox::defineImafTextFile() +{ + TextFileName = QFileDialog::getOpenFileName(this, tr("Select text file"), "/", tr("Text File (*.3gp)")); + line->setText(TextFileName); +} + +void +MainWindow::exportIMAF() +{ + numtracks = m_paneStack->getPaneCount(); + + for (int i = 0; i < numtracks; ++i) { + //ImafVolumeValues[i] = int(m_paneStack->getPane(i)->getLayer(0)->getPlayParameters()->getVolImaf())/2; + } + + CheckBox *imaf_window = new CheckBox(); + + imaf_window->resize(600,540); + imaf_window->move(100,100); + imaf_window->setWindowTitle("Export IMAF"); + imaf_window->show(); +} + + + +void MainWindow::insertLyrics(size_t frame, QString text){ + Pane *pane = m_paneStack->getCurrentPane(); + + + pane = m_paneStack->getCurrentPane(); + if (!pane) { + return; + } + + frame = pane->alignFromReference(frame); + + Layer *layer = dynamic_cast<TimeInstantLayer *> + (pane->getSelectedLayer()); + + if (!layer) { + for (int i = pane->getLayerCount(); i > 0; --i) { + layer = dynamic_cast<TimeInstantLayer *>(pane->getLayer(i - 1)); + if (layer) break; + } + + if (!layer) { + CommandHistory::getInstance()->startCompoundOperation + (tr("Add Point"), true); + layer = m_document->createEmptyLayer(LayerFactory::TimeInstants); + if (layer) { + m_document->addLayerToView(pane, layer); + m_paneStack->setCurrentLayer(pane, layer); + } + CommandHistory::getInstance()->endCompoundOperation(); + } + } + + if (layer) { + + Model *model = layer->getModel(); + SparseOneDimensionalModel *sodm = dynamic_cast<SparseOneDimensionalModel *> + (model); + + if (sodm) { + SparseOneDimensionalModel::Point point(frame, ""); + + SparseOneDimensionalModel::Point prevPoint(0); + bool havePrevPoint = false; + + SparseOneDimensionalModel::EditCommand *command = + new SparseOneDimensionalModel::EditCommand(sodm, tr("Add Point")); + + if (m_labeller->requiresPrevPoint()) { + + SparseOneDimensionalModel::PointList prevPoints = + sodm->getPreviousPoints(frame); + + if (!prevPoints.empty()) { + prevPoint = *prevPoints.begin(); + havePrevPoint = true; + } + } + + if (m_labeller) { + + m_labeller->setSampleRate(sodm->getSampleRate()); + + if (m_labeller->actingOnPrevPoint()) { + command->deletePoint(prevPoint); + } + + m_labeller->label<SparseOneDimensionalModel::Point> + (point, havePrevPoint ? &prevPoint : 0); + + if (m_labeller->actingOnPrevPoint()) { + command->addPoint(prevPoint); + } + } + point.label=text; + command->addPoint(point); + + command->setName(tr("Add Point at %1 s") + .arg(RealTime::frame2RealTime + (frame, + sodm->getSampleRate()) + .toText(false).c_str())); + + Command *c = command->finish(); + if (c) CommandHistory::getInstance()->addCommand(c, false); + } + } + +} + +void MainWindow::importIMAF() +{ + + QString filename; + int haslyrics; // if this variable != 2 -> there are lyrics + filename = QFileDialog::getOpenFileName(this, + tr("Import IMAF"), "/", tr("IMAF (*.ima)")); + + haslyrics = mainIMAFdecoder(filename); + + openMP3IMAF(); + + if (haslyrics!=2){ + addPaneToStack();//it creates a new pane to show the lyrics + + Pane *pane = m_paneStack->getCurrentPane(); + LayerFactory::LayerType type ; //set the type of layer + type = LayerFactory::TimeInstants; + //create a new layer + Layer *newLayer = 0; + newLayer = m_document->createEmptyLayer(type); + m_toolActions[ViewManager::DrawMode]->trigger(); + m_document->addLayerToView(pane, newLayer); + + //create a new layer + Layer *newLayer1 = 0; + newLayer1 = m_document->createEmptyLayer(type); + m_toolActions[ViewManager::DrawMode]->trigger(); + m_document->addLayerToView(pane, newLayer1); + m_paneStack->setCurrentLayer(pane, newLayer); + + //editCurrentLayer(); + + //text decoder + unsigned char dat,dat1,dat2,dat3; + QTextStream out(stdout); + FILE *imf; + imf = fopen (filename.toStdString().c_str(),"rb"); + + fseek (imf,0,SEEK_SET); + fseek (imf,24,SEEK_CUR); //jump to 'mdat' + fread(&dat, sizeof(unsigned char), 1, imf); + fread(&dat1, sizeof(unsigned char), 1, imf); + fread(&dat2, sizeof(unsigned char), 1, imf); + fread(&dat3, sizeof(unsigned char), 1, imf); + int sizemdat = (dat<<24) | (dat1<<16) | (dat2<<8) | (dat3); + fseek(imf, sizemdat-4, SEEK_CUR); // -4 because we have to sub the 4 bytes of size + + fseek (imf,16,SEEK_CUR); + fseek (imf,96,SEEK_CUR); // next track id is placed 96 bytes after the last byte of type 'mvhd' + + fread(&dat, sizeof(unsigned char), 1, imf); + fread(&dat1, sizeof(unsigned char), 1, imf); + fread(&dat2, sizeof(unsigned char), 1, imf); + fread(&dat3, sizeof(unsigned char), 1, imf); + + + audiotracks = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3)) -1 ; //read the number of audio tracks.It is ´-1´ because the field indicates the number of tracks +1 + + fread(&dat, sizeof(unsigned char), 1, imf);//read the size of trak.Every track must be the same size + fread(&dat1, sizeof(unsigned char), 1, imf); + fread(&dat2, sizeof(unsigned char), 1, imf); + fread(&dat3, sizeof(unsigned char), 1, imf); + + int sizetrak = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3)); + + fseek(imf, (sizetrak-4)*audiotracks, SEEK_CUR); + + int d=0; + while (d==0){ + + fread(&dat, sizeof(unsigned char), 1, imf); + fread(&dat1, sizeof(unsigned char), 1, imf); + fread(&dat2, sizeof(unsigned char), 1, imf); + fread(&dat3, sizeof(unsigned char), 1, imf); + + + if (dat == 0x73 && dat1 == 0x74 && dat2 == 0x74 && dat3 == 0x73) { // 73 74 74 73 = s t t s + d=1; + } + + else{ + fseek(imf, -3, SEEK_CUR); //if we have not readen ´stts´ + } + + } //close while + + fread(&dat, sizeof(unsigned char), 1, imf);//avanzamos 4 bytes (son los 4 bytes de version) + fread(&dat, sizeof(unsigned char), 1, imf); + fread(&dat, sizeof(unsigned char), 1, imf); + fread(&dat, sizeof(unsigned char), 1, imf); + + fread(&dat, sizeof(unsigned char), 1, imf);//estos 4 bytes son los de número de entradas de la tabla (entry_count) + fread(&dat1, sizeof(unsigned char), 1, imf); + fread(&dat2, sizeof(unsigned char), 1, imf); + fread(&dat3, sizeof(unsigned char), 1, imf); + + int entry_count = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3)); + + int sample_count [entry_count]; + int sample_delta [entry_count]; + + for (int i=0;i<entry_count;i++){ + + + fread(&dat, sizeof(unsigned char), 1, imf); + fread(&dat1, sizeof(unsigned char), 1, imf); + fread(&dat2, sizeof(unsigned char), 1, imf); + fread(&dat3, sizeof(unsigned char), 1, imf); + + sample_count[i] = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3)); + + fread(&dat, sizeof(unsigned char), 1, imf); + fread(&dat1, sizeof(unsigned char), 1, imf); + fread(&dat2, sizeof(unsigned char), 1, imf); + fread(&dat3, sizeof(unsigned char), 1, imf); + + + sample_delta[i] = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3)); + + } + + d=0; + while (d==0){ + + fread(&dat, sizeof(unsigned char), 1, imf); + fread(&dat1, sizeof(unsigned char), 1, imf); + fread(&dat2, sizeof(unsigned char), 1, imf); + fread(&dat3, sizeof(unsigned char), 1, imf); + + if (dat == 0x73 && dat1 == 0x74 && dat2 == 0x73 && dat3 == 0x7A) { // 73 74 73 7A = s t s z + d=1; + } + + else{ + fseek(imf, -3, SEEK_CUR); //if we have not readen ´stts´ + } + + } //close while + + for (int i=1;i<=8;i++){ //avanzamos 8 posiciones + + fread(&dat, sizeof(unsigned char), 1, imf); + + } + + fread(&dat, sizeof(unsigned char), 1, imf); //read sample_count + fread(&dat1, sizeof(unsigned char), 1, imf); + fread(&dat2, sizeof(unsigned char), 1, imf); + fread(&dat3, sizeof(unsigned char), 1, imf); + + int samplecount = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3)); + int sample_size[samplecount]; + for (int i=0;i<samplecount;i++){ + + fread(&dat, sizeof(unsigned char), 1, imf); + fread(&dat1, sizeof(unsigned char), 1, imf); + fread(&dat2, sizeof(unsigned char), 1, imf); + fread(&dat3, sizeof(unsigned char), 1, imf); + + sample_size[i] = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3));// the size of every string including modifiers + + } + + d=0; + while (d==0){ + + fread(&dat, sizeof(unsigned char), 1, imf); + fread(&dat1, sizeof(unsigned char), 1, imf); + fread(&dat2, sizeof(unsigned char), 1, imf); + fread(&dat3, sizeof(unsigned char), 1, imf); + + if (dat == 0x63 && dat1 == 0x6F && dat2 == 0x36 && dat3 == 0x34) { // 63 6F 36 34 = c o 6 4 + d=1; + } + + else{ + fseek(imf, -3, SEEK_CUR); //if we have not readen ´stts´ + } + + } //close while + + for (int i=1;i<=12;i++){ //advance 12 memory bytes + + fread(&dat, sizeof(unsigned char), 1, imf); + + } + + fread(&dat, sizeof(unsigned char), 1, imf); //read co64 box + fread(&dat1, sizeof(unsigned char), 1, imf); + fread(&dat2, sizeof(unsigned char), 1, imf); + fread(&dat3, sizeof(unsigned char), 1, imf); + + int chunk_offset = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3)); + + fseek (imf,0,SEEK_SET); + fseek (imf,chunk_offset,SEEK_CUR); //jump to the position where starts text strings + + int num_modifiers; + float duration1; + for (int j=0;j<samplecount;j++){ + + fread(&dat, sizeof(unsigned char), 1, imf); // read sizestring + fread(&dat1, sizeof(unsigned char), 1, imf); + + int sizestring = ((dat<<8) | (dat1)); + + char text [sizestring+1]; + + for (int i=0;i<sizestring;i++){ + fread(&dat, sizeof(unsigned char), 1, imf); + text [i] = dat; + } + text[sizestring]= '\0';// indicates the end of the char string.If we don´t add this character, the conversion to QString does not work + num_modifiers = sample_size[j]-sizestring-2; + + for (int i=0;i<num_modifiers;i++){ + fread(&dat, sizeof(unsigned char), 1, imf); + } + QString result (text);//convert string char to QString + duration1=0; + for (int h=0;h<j;h++){ + duration1 = sample_delta[h]+duration1; + } + float duration2 = duration1 / 1000; + int duration3 = duration2 * 44100; + if (sizestring >1){ //sizestring = 1 when there is only a blank space.We do not want to add a blank space alone. + + if (samplecount%2==0){//to avoid overlapping + m_paneStack->setCurrentLayer(pane, newLayer); + insertLyrics (duration3, result); + } + else{ + m_paneStack->setCurrentLayer(pane, newLayer1); + insertLyrics (duration3, result); + } + + + } // close if + } //close for + } // close if haslyrics + +} +void +MainWindow::openMP3IMAF() +{ + FileOpenStatus status; + + for (int i=0;i<audiotracks;i++){ + + char buf[2]; + sprintf(buf, "%d", i); //convert int to char + status = open(buf, CreateAdditionalModel); + remove (buf); + + } + +} +void CheckBox::set_selruleType(QAbstractButton *button) +{ + selrule_type = button->objectName().toInt(); + + if( (selrule_type == 0) || (selrule_type == 1) || (selrule_type == 3) ){ + sel_rule1->setText("Track A"); + sel_rule1->setDisabled(false); + sel_rule2->setText("Track B"); + sel_rule2->setDisabled(false); + }else{ + sel_rule1->setText("Track A"); + sel_rule1->setDisabled(false); + sel_rule2->setDisabled(true); + } +} + +void CheckBox::set_selrulePAR1(int value) +{ + selrule_par1 = value; // TRACK A +} + +void CheckBox::set_selrulePAR2(int value) +{ + selrule_par2 = value; // TRACK B +} + +void CheckBox::set_mixruleType(QAbstractButton *button) +{ + mixrule_type = button->objectName().toInt(); + + if( (mixrule_type == 0) || (mixrule_type == 1) || (mixrule_type == 2) ){ + mix_rule1->setText("Track A"); + mix_rule1->setDisabled(false); + mix_rule2->setText("Track B"); + mix_rule2->setDisabled(false); + mix_rule3->setDisabled(true); + mix_rule4->setDisabled(true); + }else{ + mix_rule1->setText("Track A"); + mix_rule1->setDisabled(false); + mix_rule2->setDisabled(true); + mix_rule3->setText("Min Volume"); + mix_rule3->setDisabled(false); + mix_rule4->setText("Max Volume"); + mix_rule4->setDisabled(false); + } +} + +void CheckBox::set_mixrulePAR1(int value) +{ + mixrule_par1 = value; // TRACK A +} + +void CheckBox::set_mixrulePAR2(int value) +{ + mixrule_par2 = value; // TRACK B +} + +void CheckBox::set_mixrulePAR3(int value) +{ + mixrule_par3 = value; // MIN VOL for Limit Rule +} + +void CheckBox::set_mixrulePAR4(int value) +{ + mixrule_par4 = value; // MAX VOL for Limit Rule +} + +void CheckBox::set_TrackInGroup(QAbstractButton *button) +{ + int temp = button->objectName().toInt(); + + if (button->isChecked()){ + group_tracks[temp-1] = 1; + }else{ + group_tracks[temp-1] = 0; + } +} + +void CheckBox::set_GroupName(QString name) +{ + group_name = name; +} + +void CheckBox::set_GroupVolume(int value) +{ + group_volume = value; +} + +void CheckBox::set_presetType(QAbstractButton *button) +{ + preset_type = button->objectName().toInt(); +} + +void CheckBox::set_fade(QAbstractButton *button) +{ + fade_in = button->objectName().toInt(); +}
--- a/main/MainWindow.h Mon Nov 04 17:13:35 2013 +0000 +++ b/main/MainWindow.h Mon Nov 04 17:15:52 2013 +0000 @@ -5,7 +5,7 @@ An audio file viewer and annotation editor. Centre for Digital Music, Queen Mary, University of London. This file copyright 2006-2007 Chris Cannam and QMUL. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the @@ -60,7 +60,6 @@ class ActivityLog; class QFileSystemWatcher; class QScrollArea; -class VersionTester; class MainWindow : public MainWindowBase { @@ -186,13 +185,17 @@ virtual void about(); virtual void keyReference(); virtual void newerVersionAvailable(QString); + virtual void exportIMAF(); + virtual void importIMAF(); + virtual void openMP3IMAF(); + virtual void insertLyrics(size_t frame, QString text); protected: Overview *m_overview; Fader *m_fader; AudioDial *m_playSpeed; WaveformLayer *m_panLayer; - + QScrollArea *m_mainScroll; bool m_mainMenusCreated; @@ -246,17 +249,15 @@ QFileSystemWatcher *m_templateWatcher; - VersionTester *m_versionTester; - struct LayerConfiguration { - LayerConfiguration(LayerFactory::LayerType _layer - = LayerFactory::TimeRuler, + LayerConfiguration(LayerFactory::LayerType _layer + = LayerFactory::TimeRuler, Model *_source = 0, int _channel = -1) : - layer(_layer), sourceModel(_source), channel(_channel) { } - LayerFactory::LayerType layer; + layer(_layer), sourceModel(_source), channel(_channel) { } + LayerFactory::LayerType layer; Model *sourceModel; - int channel; + int channel; }; typedef std::map<QAction *, LayerConfiguration> PaneActionMap; @@ -300,7 +301,7 @@ virtual void updatePositionStatusDisplays() const; virtual bool shouldCreateNewSessionForRDFAudio(bool *cancel); - + virtual void connectLayerEditDialog(ModelDataTableDialog *); };
--- a/main/OSCHandler.cpp Mon Nov 04 17:13:35 2013 +0000 +++ b/main/OSCHandler.cpp Mon Nov 04 17:15:52 2013 +0000 @@ -5,7 +5,7 @@ An audio file viewer and annotation editor. Centre for Digital Music, Queen Mary, University of London. This file copyright 2006-2007 Chris Cannam and QMUL. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the @@ -35,7 +35,7 @@ void MainWindow::handleOSCMessage(const OSCMessage &message) { - SVDEBUG << "MainWindow::handleOSCMessage: thread id = " + SVDEBUG << "MainWindow::handleOSCMessage: thread id = " << QThread::currentThreadId() << endl; // This large function should really be abstracted out. @@ -154,7 +154,7 @@ if (play) { m_viewManager->setPlaySelectionMode(selection); - } + } if (selection) { MultiSelection::SelectionList sl = m_viewManager->getSelections(); @@ -199,7 +199,7 @@ } } else if (message.getMethod() == "stop") { - + if (m_playSource->isPlaying()) m_playSource->stop(); } else if (message.getMethod() == "loop") { @@ -241,7 +241,7 @@ if (message.getArgCount() == 2 && message.getArg(0).canConvert(QVariant::Double) && message.getArg(1).canConvert(QVariant::Double)) { - + double t0 = message.getArg(0).toDouble(); double t1 = message.getArg(1).toDouble(); if (t1 < t0) { double temp = t0; t0 = t1; t1 = temp; } @@ -250,7 +250,7 @@ f0 = lrint(t0 * getMainModel()->getSampleRate()); f1 = lrint(t1 * getMainModel()->getSampleRate()); - + Pane *pane = m_paneStack->getCurrentPane(); Layer *layer = 0; if (pane) layer = pane->getSelectedLayer(); @@ -301,7 +301,7 @@ } QString str = message.getArg(0).toString(); - + LayerFactory::LayerType type = LayerFactory::getInstance()->getLayerTypeForName(str); @@ -313,7 +313,7 @@ LayerConfiguration configuration(type, getMainModel(), channel); - + addPane(configuration, tr("Add %1 Pane") .arg(LayerFactory::getInstance()-> @@ -352,7 +352,7 @@ m_viewManager->setOverlayMode(ViewManager::MinimalOverlays); } else { m_viewManager->setOverlayMode(ViewManager::AllOverlays); - } + } } else if (property == "zoomwheels") { m_viewManager->setZoomWheelsEnabled(value > 0.5); } else if (property == "propertyboxes") { @@ -360,7 +360,7 @@ (m_paneStack->getLayoutStyle() == PaneStack::NoPropertyStacks)); if (toggle) togglePropertyBoxes(); } - + } else { PropertyContainer *container = 0; Pane *pane = m_paneStack->getCurrentPane(); @@ -416,7 +416,7 @@ if (message.getArgCount() == 1 && message.getArg(0).canConvert(QVariant::String)) { - + QString target = message.getArg(0).toString(); if (target == "pane") { @@ -428,7 +428,7 @@ deleteCurrentLayer(); } else { - + std::cerr << "WARNING: MainWindow::handleOSCMessage: Unknown delete target " << target << std::endl; } } @@ -491,12 +491,12 @@ } } else if (message.getMethod() == "quit") { - + m_abandoning = true; close(); } else if (message.getMethod() == "resize") { - + if (message.getArgCount() == 2) { int width = 0, height = 0; @@ -530,9 +530,9 @@ TransformId transformId = message.getArg(0).toString(); - Transform transform = TransformFactory::getInstance()-> + Transform transform = TransformFactory::getInstance()-> getDefaultTransformFor(transformId); - + Layer *newLayer = m_document->createDerivedLayer (transform, getMainModel()); @@ -548,5 +548,5 @@ << "method \"" << message.getMethod().toStdString() << "\"" << std::endl; } - + }
--- a/main/PreferencesDialog.cpp Mon Nov 04 17:13:35 2013 +0000 +++ b/main/PreferencesDialog.cpp Mon Nov 04 17:15:52 2013 +0000 @@ -5,7 +5,7 @@ An audio file viewer and annotation editor. Centre for Digital Music, Queen Mary, University of London. This file copyright 2006 Chris Cannam. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the @@ -56,7 +56,7 @@ m_tabs = new QTabWidget; grid->addWidget(m_tabs, 0, 0); - + m_tabs->setTabPosition(QTabWidget::North); // Create this first, as slots that get called from the ctor will @@ -77,7 +77,7 @@ this, SLOT(windowTypeChanged(WindowType))); QComboBox *smoothing = new QComboBox; - + int sm = prefs->getPropertyRangeAndValue("Spectrogram Y Smoothing", &min, &max, &deflt); m_spectrogramSmoothing = sm; @@ -92,7 +92,7 @@ this, SLOT(spectrogramSmoothingChanged(int))); QComboBox *xsmoothing = new QComboBox; - + int xsm = prefs->getPropertyRangeAndValue("Spectrogram X Smoothing", &min, &max, &deflt); m_spectrogramXSmoothing = xsm; @@ -136,7 +136,7 @@ QComboBox *audioDevice = new QComboBox; std::vector<QString> devices = AudioTargetFactory::getInstance()->getCallbackTargetNames(); - + QSettings settings; settings.beginGroup("Preferences"); QString targetName = settings.value("audio-target", "").toString(); @@ -233,7 +233,7 @@ // General tab QFrame *frame = new QFrame; - + QGridLayout *subgrid = new QGridLayout; frame->setLayout(subgrid); @@ -260,7 +260,7 @@ subgrid->addWidget(resampleQuality, row++, 1, 1, 2); subgrid->setRowStretch(row, 10); - + m_tabOrdering[GeneralTab] = m_tabs->count(); m_tabs->addTab(frame, tr("&General")); @@ -299,7 +299,7 @@ subgrid->addWidget(showSplash, row++, 1, 1, 1); subgrid->setRowStretch(row, 10); - + m_tabOrdering[AppearanceTab] = m_tabs->count(); m_tabs->addTab(frame, tr("&Appearance")); @@ -331,9 +331,9 @@ subgrid->addWidget(m_windowTypeSelector, row++, 1, 2, 2); subgrid->setRowStretch(row, 10); row++; - + subgrid->setRowStretch(row, 10); - + m_tabOrdering[AnalysisTab] = m_tabs->count(); m_tabs->addTab(frame, tr("Anal&ysis")); @@ -343,7 +343,7 @@ subgrid = new QGridLayout; frame->setLayout(subgrid); row = 0; - + subgrid->addWidget(new QLabel(tr("Default session template for audio files:")), row++, 0); QListWidget *lw = new QListWidget(); @@ -384,7 +384,7 @@ QDialogButtonBox *bb = new QDialogButtonBox(Qt::Horizontal); grid->addWidget(bb, 1, 0); - + QPushButton *ok = new QPushButton(tr("OK")); QPushButton *cancel = new QPushButton(tr("Cancel")); bb->addButton(ok, QDialogButtonBox::AcceptRole); @@ -550,7 +550,7 @@ prefs->setBackgroundMode(Preferences::BackgroundMode(m_backgroundMode)); prefs->setTimeToTextMode(Preferences::TimeToTextMode(m_timeToTextMode)); prefs->setViewFontSize(m_viewFontSize); - + std::vector<QString> devices = AudioTargetFactory::getInstance()->getCallbackTargetNames(); @@ -571,7 +571,7 @@ tr("<b>Restart required</b><p>One or more of the application preferences you have changed may not take full effect until Sonic Visualiser is restarted.</p><p>Please exit and restart the application now if you want these changes to take effect immediately.</p>")); m_changesOnRestart = false; } -} +} void PreferencesDialog::cancelClicked()
--- a/main/PreferencesDialog.h Mon Nov 04 17:13:35 2013 +0000 +++ b/main/PreferencesDialog.h Mon Nov 04 17:15:52 2013 +0000 @@ -5,7 +5,7 @@ An audio file viewer and annotation editor. Centre for Digital Music, Queen Mary, University of London. This file copyright 2006 Chris Cannam. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the @@ -78,7 +78,7 @@ QString m_currentTemplate; QStringList m_templates; - + WindowType m_windowType; int m_spectrogramSmoothing; int m_spectrogramXSmoothing;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/checkbox.h Mon Nov 04 17:15:52 2013 +0000 @@ -0,0 +1,46 @@ +#ifndef CHECKBOX_H +#define CHECKBOX_H + +#include <QWidget> +#include <QlineEdit> +#include <QButtonGroup> +#include <QRadioButton> +#include <QGroupBox> +#include <QSpinBox> +#include "MainWindow.h" + +class CheckBox : public QWidget +{ + Q_OBJECT + +public: + CheckBox(QWidget *parent = 0); + QLineEdit *line = new QLineEdit("", this); + QLineEdit *line2 = new QLineEdit("", this); + QLabel *sel_rule1, *sel_rule2; + QLabel *mix_rule1, *mix_rule2, *mix_rule3, *mix_rule4; + QLabel *group_label, *grp_vol, *grp_name; + QLineEdit *group_name_line; + +private slots: + void defineImafTextFile(); + void defineImafImageFile(); + void saveImafFile(); + void insertLyrics(int state); + void insertImage(int state); + void set_selruleType(QAbstractButton *button); + void set_selrulePAR1(int value); + void set_selrulePAR2(int value); + void set_mixruleType(QAbstractButton *button); + void set_mixrulePAR1(int value); + void set_mixrulePAR2(int value); + void set_mixrulePAR3(int value); + void set_mixrulePAR4(int value); + void set_TrackInGroup(QAbstractButton *button); + void set_GroupName(QString name); + void set_GroupVolume(int value); + void set_presetType(QAbstractButton *button); + void set_fade(QAbstractButton *button); +}; + +#endif // CHECKBOX_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/imafdecoder.cpp Mon Nov 04 17:15:52 2013 +0000 @@ -0,0 +1,212 @@ +//Jesús Corral García +//Universidad de Málaga + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <QTextStream> +#include <QString> +#include "MainWindow.h" + + +int audiotracks; //number of audio tracks contained inside the IM AF file + +int mainIMAFdecoder(QString outimaf){ + + FILE *imf,*audiotrack; + int d=0,i,j,sizemdat,audiosize; + int chunkoffset[64]; // if you want more than 64 tracks , change this value. + unsigned char dat,dat1,dat2,dat3; + QTextStream out(stdout); + + imf = fopen (outimaf.toStdString().c_str(),"rb"); + + fseek (imf,0,SEEK_SET); + fseek (imf,24,SEEK_CUR); //jump to 'mdat' + + fread(&dat, sizeof(unsigned char), 1, imf); + fread(&dat1, sizeof(unsigned char), 1, imf); + fread(&dat2, sizeof(unsigned char), 1, imf); + fread(&dat3, sizeof(unsigned char), 1, imf); + + sizemdat = (dat<<24) | (dat1<<16) | (dat2<<8) | (dat3); + + if (sizemdat==1){ // if conformance file + fread(&dat, sizeof(unsigned char), 1, imf); + fread(&dat1, sizeof(unsigned char), 1, imf); + fread(&dat2, sizeof(unsigned char), 1, imf); + fread(&dat3, sizeof(unsigned char), 1, imf); + fread(&dat, sizeof(unsigned char), 1, imf); + fread(&dat1, sizeof(unsigned char), 1, imf); + fread(&dat2, sizeof(unsigned char), 1, imf); + fread(&dat3, sizeof(unsigned char), 1, imf); + fread(&dat, sizeof(unsigned char), 1, imf); + fread(&dat1, sizeof(unsigned char), 1, imf); + fread(&dat2, sizeof(unsigned char), 1, imf); + fread(&dat3, sizeof(unsigned char), 1, imf); + sizemdat = (dat<<24) | (dat1<<16) | (dat2<<8) | (dat3); + + fseek(imf,sizemdat-16,SEEK_CUR); + } + else { + + fseek(imf, sizemdat-4, SEEK_CUR); // -4 because we have to sub the 4 bytes of size + } + + fseek (imf,16,SEEK_CUR); + fseek (imf,96,SEEK_CUR); // next track id is placed 96 bytes after the last byte of type 'mvhd' + + fread(&dat, sizeof(unsigned char), 1, imf); + fread(&dat1, sizeof(unsigned char), 1, imf); + fread(&dat2, sizeof(unsigned char), 1, imf); + fread(&dat3, sizeof(unsigned char), 1, imf); + + audiotracks = ((dat<<24) | (dat1<<16) | (dat2<<8) | (dat3)) -1 ; //read the number of audio tracks.It is ´-1´ because the field indicates the number of tracks +1 + + + if (audiotracks == 12345678){ + + audiotracks = 6; // for the conformance file 2 + + } + for (j=1;j<=audiotracks;j++){ + + d=0; + while (d==0){ + + fread(&dat, sizeof(unsigned char), 1, imf); + fread(&dat1, sizeof(unsigned char), 1, imf); + fread(&dat2, sizeof(unsigned char), 1, imf); + fread(&dat3, sizeof(unsigned char), 1, imf); + + + if (dat == 0x68 && dat1 == 0x64 && dat2 == 0x6C && dat3 == 0x72) { // 68646C72 = hdlr + d=1; + } + + else{ + fseek(imf, -3, SEEK_CUR); //if we have not readen ´hdlr´ + } + + } //close while + + for (i=1;i<=8;i++){ //handler type is placed eight bytes after the last byte of type 'hdlr' + + fread(&dat, sizeof(unsigned char), 1, imf); + } + + fread(&dat, sizeof(unsigned char), 1, imf);//dat could be ´s´ (soun) or ´t´(text) + + d=0; + if (dat==0x73){ //73 = ´s´ + + while (d==0){ + + fread(&dat, sizeof(unsigned char), 1, imf); + fread(&dat1, sizeof(unsigned char), 1, imf); + fread(&dat2, sizeof(unsigned char), 1, imf); + fread(&dat3, sizeof(unsigned char), 1, imf); + + if (dat == 0x63 && dat1 == 0x6F && dat2 == 0x36 && dat3 == 0x34) { // 636F3634 = co64 + d=1; + } + else if (dat == 0x73 && dat1 == 0x74 && dat2 == 0x63 && dat3 == 0x6F){ //7374636F = stco + d=2; + } + + else{ + fseek(imf, -3, SEEK_CUR); //if we have not readen ´stco´ + } + + } //close while + if (d==1){ // if co64 + for (i=1;i<=12;i++){ + + fread(&dat, sizeof(unsigned char), 1, imf); + } + } + if (d==2){// if stco + for (i=1;i<=8;i++){ + + fread(&dat, sizeof(unsigned char), 1, imf); + } + } + + + fread(&dat, sizeof(unsigned char), 1, imf); + fread(&dat1, sizeof(unsigned char), 1, imf); + fread(&dat2, sizeof(unsigned char), 1, imf); + fread(&dat3, sizeof(unsigned char), 1, imf); + + chunkoffset[j-1] = (dat<<24) | (dat1<<16) | (dat2<<8) | (dat3); + + + }//close if + + + } //close for +//At this point, we will look for a text track. If d=2 there are no lyrics + d=0; + while (d==0){ + + fread(&dat, sizeof(unsigned char), 1, imf); + fread(&dat1, sizeof(unsigned char), 1, imf); + fread(&dat2, sizeof(unsigned char), 1, imf); + fread(&dat3, sizeof(unsigned char), 1, imf); + + if (feof (imf )){// if end of file -> no lyrics + d=2; + } + else if (dat == 0x68 && dat1 == 0x64 && dat2 == 0x6C && dat3 == 0x72) { // 68646C72 = hdlr + d=1; + } + else{ + fseek(imf, -3, SEEK_CUR); //if we have not readen ´hdlr´ + } + + } //close while + + +// At this point, we know the position of the audio tracks in mdat and the number of tracks. +// Now we will separate the audio tracks in several MP3. + + fseek(imf, 0, SEEK_SET); + for (j=0;j<chunkoffset[0];j++) //advance to the position of the first audio track contained in mdat + { + fread(&dat, sizeof(unsigned char), 1, imf); + } + + for(i=0;i<audiotracks-1;i++){ + + + char buf[2]; + sprintf(buf, "%d", i);// convert int to char + audiotrack =fopen (buf,"wb"); + + for (j=chunkoffset[i];j<chunkoffset[i+1];j++){ + fread(&dat,sizeof(unsigned char),1,imf); + fwrite (&dat,sizeof(unsigned char),1,audiotrack); + } + fclose (audiotrack); + + } // close for + +//last audio track + + char buf[2]; + sprintf(buf, "%d", audiotracks-1); //convert int to char + audiotrack =fopen (buf,"wb"); + audiosize = chunkoffset[2]-chunkoffset[1]; //calculate the size of one audio track. Every audio track must be the same size + for (i=1;i<=audiosize;i++) + { + fread(&dat,sizeof(unsigned char),1,imf); + fwrite (&dat,sizeof(unsigned char),1,audiotrack); + } + + fclose (audiotrack); + fclose (imf); + return d; + + + +}
--- a/sv.pro Mon Nov 04 17:13:35 2013 +0000 +++ b/sv.pro Mon Nov 04 17:15:52 2013 +0000 @@ -47,11 +47,15 @@ RESOURCES += sonic-visualiser.qrc HEADERS += main/MainWindow.h \ - main/PreferencesDialog.h + main/PreferencesDialog.h \ + main/IMAFencoder.h \ + main/checkbox.h SOURCES += main/main.cpp \ main/OSCHandler.cpp \ main/MainWindow.cpp \ - main/PreferencesDialog.cpp + main/PreferencesDialog.cpp \ + main/IMAFencoder.c \ + main/imafdecoder.cpp # for mac integration QMAKE_INFO_PLIST = deploy/osx/Info.plist