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 &copy; 2005&ndash;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