view IM_AF Encoder/IM_AM Encoder/main.c @ 1:19490164927c

working version
author Eugenio Oñate Hospital <eo301@eecs.qmul.ac.uk>
date Thu, 26 Jul 2012 16:52:19 +0100
parents 138a3cea9792
children 1636a6250528
line wrap: on
line source
//
//  main.c
//  IM_AM Enco§er
//
//  Created by eugenio oñate hospital on 14/06/12.
//  Copyright (c) 2012 QM. All rights reserved.
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "IM_AF Encoder.h"

/*Prototype*/

void filetypebx(FileTypeBox *ftyp);
int mdatbox(MediaDataBox *mdat, int, FILE *imf, FILE *song, int);
void moovheaderbox(MovieBox *moov, int, int, int, int, int, int);
int trackstructure(MovieBox *moov, int, int, int, int, char name[20]);
int samplecontainer(MovieBox *moov, int, int, char name[20]);
int sampledescription(MovieBox *moov, int);
int presetcontainer(MovieBox *moov, int,nametrack namet);
int rulescontainer(MovieBox *moov);
void writemoovbox(MovieBox moov, int numtrack,int totaltracks, FILE *imf);
//void groupscontainer(MovieBox *moov);
//void metadata(MetaBox *meta);
int readTrack(MovieBox *moov, int, char name[20]);
int byterevers(int);


int main ()
{
    //variables
    FileTypeBox ftyp;
    MediaDataBox mdat;
    MovieBox moov;
//    MetaBox meta;
    nametrack namet;

    FILE *imf;
    int numtrack,totaltracks, sizemdat, durationTrack;
        
    /* Obtain current time as seconds elapsed since the Epoch. */
    time_t clock = time(NULL);
    
    printf("Welcome to the IM_AF encoder\n");
    printf("This program will allow you to create an IM_AF file.\n");
    printf("How many tracks there will be in your IMAF file?\n");
    scanf("%d",&totaltracks); 
    fflush(stdin);
    while (totaltracks > maxtracks) {
        printf("Sorry, for this version the number maximum ot tracks is 10\n");
        printf("How many tracks there will be in your IMAF file:\n");
        scanf("%d",&totaltracks); 
    }
    
    //Create the file
    imf = fopen ("/Users/eugin/Desktop/IM_AF Encoder/IM_AM Encoder/example1.ima","wb"); 
    if (imf == NULL) {
       printf("Error opening input file\n");
       system("pause");
       exit(1);
       }    
    
    //Define the File Type Box
    filetypebx(&ftyp);
    fwrite(&ftyp, sizeof(FileTypeBox),1, imf);

    //Media Data Box - Contains the audio
    FILE *song;
    char nametrack[20], pathdir[60] ="/Users/eugin/Desktop/IM_AF Encoder/Electro/";
    int numtr, ex = 0;
    for (numtr=0; numtr<totaltracks; numtr++) {
        
        printf("Name of the track number: %d\n", numtr+1);
        fflush(stdin);
        scanf("%s", nametrack);
        strcpy(pathdir, "/Users/eugin/Desktop/IM_AF Encoder/Electro/");
        strcat(pathdir, nametrack);
        ex = 0;
        //Check if the track exist and then open it.
        while (ex == 0){
            song = fopen(pathdir, "rb");
            if((song)==NULL) {
                printf("Name does not exist. Try again:\n");
                fflush(stdin);
                scanf("%s", nametrack);
                strcpy(pathdir, "/Users/eugin/Desktop/IM_AF Encoder/Electro/");
                strcat(pathdir, nametrack);
            }else{
                ex = 1;
            }
        }
        strcpy(namet[numtr].title, nametrack);
        sizemdat = mdatbox(&mdat, totaltracks, imf, song, numtr);
        fclose(song);
    }
    
    //For each track write track information
    u32 sizeTRAK = 0;
    char name[20];
    durationTrack = (sizemdat*8)/128;
    printf("Duration: %d\n",durationTrack);
    
    for (numtrack = 0; numtrack < totaltracks; numtrack++) {
        strcpy(name,namet[numtrack].title);
        sizeTRAK =  trackstructure(&moov, numtrack, clock, durationTrack,sizemdat, name)+ sizeTRAK;
    }
    
    //Groups
 //   groupscontainer(&moov);
    
    //Presets
    u32 sizePRCO;
    sizePRCO = presetcontainer(&moov, totaltracks, namet);
    
    //Rules
    u32 sizeRUCO;
    sizeRUCO = rulescontainer(&moov);
    
    //Movie Header - Overall declarations
    moovheaderbox(&moov, clock, sizeTRAK, sizePRCO, totaltracks, durationTrack, sizeRUCO);
    
    writemoovbox(moov,numtrack, totaltracks, imf);
    
    //Metadata
    //metadata(&meta);
    //fwrite(&meta, sizeof(MetaBox),1, imf);
    
    //Close File
    fclose(imf); 
        
    return 0;
}

void filetypebx(FileTypeBox *ftyp){
    int swap;

    swap = byterevers (24);
    ftyp->size = swap;
    swap = byterevers ('ftyp');
    ftyp->type = swap;
    swap = byterevers ('im03');
    ftyp->major_brand = swap;
    ftyp->minor_version = 0;
    swap = byterevers ('im03');
    ftyp->compatible_brands[0] = swap;
    swap = byterevers ('isom');
    ftyp->compatible_brands[1] = swap;
}

int mdatbox(MediaDataBox *mdat, int totaltracks, FILE *imf, FILE *song, int numtr){

    int d, cnt, j, find = 0;
    int  dat = 0, dat1 = 0, dat2 = 0, dat3 = 0, num_samples = 0;
    u32 size = 0, swap, sizeMDAT =0;
    
    fseek(song, 0, SEEK_END);
    size = ftell(song);
    fseek(song, 0, SEEK_SET);
    d=0;
    cnt = 0;
    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 ) {
                num_samples ++;
                // printf("Data %d Position: %d\n",dat3, cnt);
                find = 1;
                d=1;
            }
            if (dat1 == 0xFB && dat2 == 146 && dat3 == 96 ) {
                num_samples ++;
                d=1;
                find = 1;
            }
            if (dat1 == 0xFB && dat2 == 144 && dat3 == 64 ) {
                num_samples ++;
                find = 1;
                d=1;
            }
            if (dat1 == 0xFB && dat2 == 144 && dat3 == 96 ) {
                num_samples ++;
                find = 1;
                d=1;
            }     
            if (dat1 == 0xFB && dat2 == 146 && dat3 == 100 ) {
                num_samples ++;
                d=1;
                find = 1;
            }
            if (dat1 == 0xFB && dat2 == 144 && dat3 == 100 ) {
                num_samples ++;
                find = 1;
                d=1;
            }
            if (dat1 == 0xFA && dat2 == 146 && dat3 == 64 ) {
                num_samples ++;
                find = 1;
                d=1;
            }
            if (dat1 == 0xFA && dat2 == 146 && dat3 == 96 ) {
                num_samples ++;
                d=1;
                find = 1;
            }
            if (dat1 == 0xFA && dat2 == 144 && dat3 == 64 ) {
                num_samples ++;
                find = 1;
                d=1;
            }
            if (dat1 == 0xFA && dat2 == 144 && dat3 == 96 ) {
                num_samples ++;
                find = 1;
                d=1;
            }     
            if (dat1 == 0xFA && dat2 == 146 && dat3 == 100 ) {
                num_samples ++;
                d=1;
                find = 1;
            }
            if (dat1 == 0xFA && dat2 == 144 && dat3 == 100 ) {
                num_samples ++;
                find = 1;
                d=1;
            }
            if (find == 0) {
                fseek(song, -3, SEEK_CUR);
                cnt = cnt - 3;
            }
        }
        if (cnt == size) {
            d = 1;
        }
    }
    size =  size - (cnt - 4);
    if (numtr == 0) {
        sizeMDAT = size*totaltracks + 8;
     //   printf("Size file mdat %d\n",sizeMDAT);
        swap = byterevers(sizeMDAT);
        fwrite(&swap, sizeof(u32), 1, imf);
        swap = byterevers('mdat');
        mdat->type = swap;
        fwrite(&mdat->type, sizeof(u32), 1, imf);
    }
    fseek(song, cnt - 4, SEEK_SET);
    for (j=0; j<size; j++) {
        fread(&mdat->data, sizeof(char), 1, song);
        fwrite(&mdat->data, sizeof(char), 1, imf);
    }
    fclose(song);

    return size;
}

int samplecontainer(MovieBox *moov, int numtrack, int sizemdat, char name[20]){

    u32 sizeSTSD, sizeSTSZ, swap, num_samples, dat=0;

    //Sample Description Box//
    sizeSTSD = sampledescription(moov, numtrack);

    //Sample size box//
    swap = byterevers('stsz');
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    SampleSizeBox.type = swap;
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    SampleSizeBox.version = 0;
    //Read Track: Fram size and Decoder Times// 
    num_samples = readTrack(moov, numtrack, name);
    sizeSTSZ = num_samples*4 + 20;
    swap = byterevers(sizeSTSZ);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    SampleSizeBox.size = swap;

    //Time To Sample Box//
    u32 sizetime, sizeSTTS;
    sizetime = byterevers(moov->TrackBox[numtrack].MediaBox.MediaInformationBox.
                          SampleTableBox.TimeToSampleBox.entry_count);
    sizeSTTS = 16 + sizetime*4*2;
    swap = byterevers(sizeSTTS);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    TimeToSampleBox.size = swap;
    swap = byterevers('stts');
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    TimeToSampleBox.type = swap;
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    TimeToSampleBox.version = 0;
        
    //Sample To Chunk//
    u32 sizeSTSC = 28;
    swap = byterevers(sizeSTSC);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    SampleToChunk.size = swap;
    swap = byterevers('stsc');
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    SampleToChunk.type = swap;
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    SampleToChunk.version = 0;
    swap = byterevers(1);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    SampleToChunk.entry_count = swap;
    swap = byterevers(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 = byterevers(1);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    SampleToChunk.sample_description_index = swap;
    
    //Chunk Offset Box//
    u32 sizeSTCO = 20;
    swap = byterevers(sizeSTCO);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    ChunkOffsetBox.size = swap;
    swap = byterevers('stco');
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    ChunkOffsetBox.type = swap;
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    ChunkOffsetBox.version = 0;
    swap = byterevers(1);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    ChunkOffsetBox.entry_count = swap;
    dat = 32 + sizemdat*numtrack;
    swap = byterevers(dat);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    ChunkOffsetBox.chunk_offset[numtrack] = swap;
    
    //Sample Table Box //
    u32 sizeSTBL = 8 + sizeSTSD + sizeSTSZ + sizeSTSC + sizeSTCO + sizeSTTS;
    swap = byterevers(sizeSTBL);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.size = swap;
    swap = byterevers('stbl');
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.type =swap;

    return  sizeSTBL;
}

int sampledescription(MovieBox *moov, int numtrack){
    u32 swap, sizeESD = 35;
    swap = byterevers(sizeESD);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    SampleDescriptionBox.AudioSampleEntry.ESbox.size = swap;
    swap = byterevers('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 = byterevers(0x150036B0);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.
    DecoderConfigDescriptor.mix = swap;
    swap = byterevers(128);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.
    DecoderConfigDescriptor.maxBitRate = swap;
    swap = byterevers(128);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.
    DecoderConfigDescriptor.avgBitrate = swap;
    
    //Decoder Specific Info//
  /*  moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.
    DecoderConfigDescriptor.DecoderSpecificInfo.tag = 5;
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.
    DecoderConfigDescriptor.DecoderSpecificInfo.length = 2;
    SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.
    DecoderConfigDescriptor.DecoderSpecificInfo.decSpecificInfoData[0] = 0xC;
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    SampleDescriptionBox.AudioSampleEntry.ESbox.ES_Descriptor.
    DecoderConfigDescriptor.DecoderSpecificInfo.decSpecificInfoData[1] = 0x8;
  */  
    //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//
    u32 sizeMP4a = 36 + sizeESD;
    swap = byterevers(sizeMP4a);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    SampleDescriptionBox.AudioSampleEntry.size = swap;
    swap = byterevers('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 = 256;
    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 = byterevers(swap);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    SampleDescriptionBox.AudioSampleEntry.samplerate = swap;
    
    //Sample description box //
    u32 sizeSTSD = 16 + sizeMP4a;
    swap = byterevers(sizeSTSD);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    SampleDescriptionBox.size = swap;
    swap = byterevers('stsd');
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    SampleDescriptionBox.type = swap;
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    SampleDescriptionBox.version = 0; 
    swap = byterevers(1);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    SampleDescriptionBox.entry_count = swap; 

    return sizeSTSD;
}

int readTrack (MovieBox *moov, int numtrack, char name[20]){
    
    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_samples = 0, end =0, pos = 0;
    u32 size[8000];
    char pathdir[60] = "/Users/eugin/Desktop/IM_AF Encoder/Electro/";
  //  printf("Name: %s\n",name);
    strcat(pathdir, name);
    
    song = fopen (pathdir,"rb"); 
    if (song == NULL) {
        printf("Error opening input file\n");
        system("pause");
        exit(1);
    }
    
    fseek(song, 0, SEEK_END);
    end = ftell(song);
    fseek(song, 0, SEEK_SET);
    d=0, i=0;
    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;
                size[num_samples] = pos - cnt2;
                cnt2 = pos;
         //       printf("Data %d Position: %d\n",dat3, num_samples,pos);
                find = 1;
                num_samples ++;
            }
            if (dat1 == 0xFB && dat2 == 146 && dat3 == 96 ) {
                pos = cnt - 4;
                size[num_samples] = pos - cnt2;
                cnt2 = pos;
                find = 1;
                num_samples ++;
            }
            if (dat1 == 0xFB && dat2 == 144 && dat3 == 64 ) {
               pos = cnt - 4;
                size[num_samples] = pos - cnt2;
                cnt2 = pos;
         //       printf("Data %d Position: %d\n",dat3, num_samples,pos);
                find = 1;
                num_samples ++;
            }
            if (dat1 == 0xFB && dat2 == 144 && dat3 == 96 ) {
                pos = cnt - 4;
                size[num_samples] = pos - cnt2;
                cnt2 = pos;
                find = 1;
                num_samples ++;
            }
            if (dat1 == 0xFB && dat2 == 146 && dat3 == 100 ) {
                pos = cnt - 4;
                size[num_samples] = pos - cnt2;
                cnt2 = pos;
                find = 1;
                num_samples ++;
            }
            if (dat1 == 0xFB && dat2 == 144 && dat3 == 100 ) {
                pos = cnt - 4;
                size[num_samples] = pos - cnt2;
                cnt2 = pos;
                find = 1;
                num_samples ++;
            }
            if (dat1 == 0xFA && dat2 == 146 && dat3 == 64 ) {
                pos = cnt - 4;
                size[num_samples] = pos - cnt2;
                cnt2 = pos;
                //       printf("Data %d Position: %d\n",dat3, num_samples,pos);
                find = 1;
                num_samples ++;
            }
            if (dat1 == 0xFA && dat2 == 146 && dat3 == 96 ) {
                pos = cnt - 4;
                size[num_samples] = pos - cnt2;
                cnt2 = pos;
                find = 1;
                num_samples ++;
            }
            if (dat1 == 0xFA && dat2 == 144 && dat3 == 64 ) {
                pos = cnt - 4;
                size[num_samples] = pos - cnt2;
                cnt2 = pos;
                //       printf("Data %d Position: %d\n",dat3, num_samples,pos);
                find = 1;
                num_samples ++;
            }
            if (dat1 == 0xFA && dat2 == 144 && dat3 == 96 ) {
                pos = cnt - 4;
                size[num_samples] = pos - cnt2;
                cnt2 = pos;
                find = 1;
                num_samples ++;
            }
            if (dat1 == 0xFA && dat2 == 146 && dat3 == 100 ) {
                pos = cnt - 4;
                size[num_samples] = pos - cnt2;
                cnt2 = pos;
                find = 1;
                num_samples ++;
            }
            if (dat1 == 0xFA && dat2 == 144 && dat3 == 100 ) {
                pos = cnt - 4;
                size[num_samples] = pos - cnt2;
                cnt2 = pos;
                find = 1;
                num_samples ++;
            }
            if (find == 0) { // Keep reading next data.
                fseek(song, -3, SEEK_CUR);
                cnt = cnt - 3;
            }
        }
        
        if (cnt == end) {
            pos = cnt;
            size[num_samples] = pos - cnt2;
            d = 1;
        }
    }
    
    //Save Samples size//
    swap = byterevers(num_samples);
    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_samples; i++) {
        swap = byterevers(size[i+1]);
        moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
        SampleSizeBox.entry_size[i] = swap;
    }
    
  //  printf("Num of samples %d\n",num_samples);
    
    //Save Decoding Times//

    swap = byterevers(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_samples; i++) {
        if (j == 8 && l == 0) {
            swap = byterevers(7);
            moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
            TimeToSampleBox.sample_count[num_entr] = swap;
            swap = byterevers(26);
            moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
            TimeToSampleBox.sample_delta[num_entr] =swap; 
            num_entr ++;
            
            swap = byterevers(1);
            moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
            TimeToSampleBox.sample_count[num_entr] = swap;
            swap = byterevers(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 = byterevers(8);
            moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
            TimeToSampleBox.sample_count[num_entr] = swap;
            swap = byterevers(26);
            moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
            TimeToSampleBox.sample_delta[num_entr] =swap; 
            num_entr ++;
            
            swap = byterevers(1);
            moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
            TimeToSampleBox.sample_count[num_entr] = swap;
            swap = byterevers(27);
            moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
            TimeToSampleBox.sample_delta[num_entr] =swap;  
            num_entr++;
            j=0;
            dat = i;
            l = 0;
        }
        j++;
    }

    dat = num_samples - dat;
    
    swap = byterevers(dat);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    TimeToSampleBox.sample_count[num_entr] = swap;
    swap = byterevers(26);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    TimeToSampleBox.sample_delta[num_entr] =swap; 
    num_entr++;
 //   printf("Num entries: %d\n", num_entr);
    swap = byterevers(num_entr);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SampleTableBox.
    TimeToSampleBox.entry_count = swap;
    
    fclose(song);
    return num_samples;

}

int trackstructure (MovieBox *moov, int numtrack, int clock, 
                    int durationTrack, int sizemdat, char name[20]){
    int swap;

    //Sample Table Box
    int sizeSTBL = 0;
    sizeSTBL = samplecontainer(moov, numtrack,sizemdat, name);
    
    //Data Entry Url Box
    u32 sizeURL = 12;
    swap = byterevers(sizeURL);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.
    DataReferenceBox.DataEntryUrlBox.size = swap;
    swap = byterevers('url ');
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.
    DataReferenceBox.DataEntryUrlBox.type = swap;
    swap = byterevers(1);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.
    DataReferenceBox.DataEntryUrlBox.flags = swap; // =1 Track in same file as movie atom.
    
    //Data Reference
    u32 sizeDREF = sizeURL+ 16;
    swap = byterevers(sizeDREF);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.
    DataReferenceBox.size = swap;
    swap = byterevers('dref');
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.
    DataReferenceBox.type = swap;
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.
    DataReferenceBox.flags = 0;
    swap = byterevers(1);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.
    DataReferenceBox.entry_count = swap;
    
    //Data information Box//
    u32 sizeDINF = sizeDREF + 8;
    swap = byterevers(sizeDINF);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.size = swap;
    swap = byterevers('dinf');
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.DataInformationBox.type = swap;
    
    //Sound Header Box //
    u32 sizeSMHD = 16;
    swap = byterevers(sizeSMHD);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.SoundMediaHeaderBox.size = swap;
    swap = byterevers('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//
    u32 sizeMINF = sizeDINF + sizeSMHD + sizeSTBL + 8;
    swap = byterevers(sizeMINF);
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.size = swap;
    swap = byterevers('minf');
    moov->TrackBox[numtrack].MediaBox.MediaInformationBox.type = swap;
    
    //Handler Box//
    u32 sizeHDLR = 37;
    swap = byterevers(sizeHDLR); 
    moov->TrackBox[numtrack].MediaBox.HandlerBox.size = swap;
    swap = byterevers('hdlr');
    moov->TrackBox[numtrack].MediaBox.HandlerBox.type = swap;
    moov->TrackBox[numtrack].MediaBox.HandlerBox.version = 0;
    moov->TrackBox[numtrack].MediaBox.HandlerBox.pre_defined = 0;
    swap = byterevers('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 = byterevers('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//
    u32 sizeMDHD = 32;
    swap = byterevers(sizeMDHD);
    moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.size = swap;
    swap = byterevers('mdhd');
    moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.type = swap;
    moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.version = 0;
    swap = byterevers(clock);
    moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.creation_time = swap;
    moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.modification_time = swap;
    swap = byterevers(1000);
    moov->TrackBox[numtrack].MediaBox.MediaHeaderBox.timescale = swap;
    swap = byterevers(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//
    u32 sizeMDIA = sizeMDHD + sizeHDLR + sizeMINF + 8;
    swap = byterevers(sizeMDIA);
    moov->TrackBox[numtrack].MediaBox.size = swap;
    swap = byterevers('mdia');
    moov->TrackBox[numtrack].MediaBox.type = swap;
    
    //Track Header//
    u32 sizeTKHD = 92;
    swap = byterevers (sizeTKHD);
    moov->TrackBox[numtrack].TrackHeaderBox.size = swap;
    swap = byterevers ('tkhd');
    moov->TrackBox[numtrack].TrackHeaderBox.type = swap ;
    swap = byterevers (0x00000006);
    moov->TrackBox[numtrack].TrackHeaderBox.version = swap;
    swap = byterevers (clock);
    moov->TrackBox[numtrack].TrackHeaderBox.creation_time = swap;
    moov->TrackBox[numtrack].TrackHeaderBox.modification_time = swap;
    swap = byterevers (numtrack+1);
    moov->TrackBox[numtrack].TrackHeaderBox.track_ID = swap; //From 0x00000001 - 0x7FFFFFFF (dec 2147483647)
    moov->TrackBox[numtrack].TrackHeaderBox.reserved = 0;
    swap = byterevers (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 = byterevers (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 = byterevers(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
    u32 sizeTRAK = sizeTKHD + sizeMDIA + 8;
    swap = byterevers (sizeTRAK); // Size of one track
    moov->TrackBox[numtrack].size = swap; 
    swap = byterevers ('trak');
    moov->TrackBox[numtrack].type = swap;
    return sizeTRAK;

}

int presetcontainer(MovieBox *moov, int totaltracks, nametrack namet){
    
    int swap, i,j,flag, vol=0; 
//    char num_output_channel = 2; // Stereo
    unsigned char numpres=0, prestype=0,defaultPreset;
    char namepres1[14] = "static_track "; // 13  
    u32 sizePRST = 0;

    printf("Presets:\n");
    printf("Static track volume preset: invariant volume related to each track \n");
    printf("          --------------------------------------\n");
    numpres = 1;
    //Preset Box//
    for (i=0; i<numpres; i++) {
        printf("Preset number %d: %s\n",i+1,namepres1);
        strcpy(moov->PresetContainerBox.PresetBox[i].preset_name, namepres1);
        sizePRST = 16 + 14 + 4*totaltracks + totaltracks;
        swap = byterevers(sizePRST);
        moov->PresetContainerBox.PresetBox[i].size = swap;
        prestype = 0;

  /*      if (i == 1) {
            printf("Preset number %d: %s\n",i+1,namepres2);
            strcpy(moov->PresetContainerBox.PresetBox[i].preset_name, namepres2);
            sizePRST2 = 16 + 14 + 4*totaltracks + 2 + 2*5*totaltracks;
            swap = byterevers(sizePRST2);
            moov->PresetContainerBox.PresetBox[i].size = swap;
            prestype = 2;
            
        }
 */     
        moov->PresetContainerBox.PresetBox[i].num_preset_elements = totaltracks;
        swap = byterevers('prst');
        moov->PresetContainerBox.PresetBox[i].type = swap;
    
        flag = 0x02; // Display Enable Edit Disable
        swap = byterevers(flag);
        moov->PresetContainerBox.PresetBox[i].flags = swap;
        
        moov->PresetContainerBox.PresetBox[i].preset_ID = i+1;
        
        moov->PresetContainerBox.PresetBox[i].preset_type = prestype;
        moov->PresetContainerBox.PresetBox[i].preset_global_volume = 100;
        
        for (j=0; j<totaltracks; j++) {
            swap = byterevers(j+1);
            moov->PresetContainerBox.PresetBox[i].presElemId[j].preset_element_ID = swap;
        }
        
        for (j=0; j<totaltracks; j++) {
            printf("Enter volume for %s\n",namet[j].title);
        //     scanf("%d",&vol);
        //     printf("Vol: %d\n",vol);
            vol = 100;
            moov->PresetContainerBox.PresetBox[i].presVolumElem[j].preset_volume_element = vol; //*0.02 
        }

 /*       if(prestype == 2){ // dynamic track volume preset
            moov->PresetContainerBox.PresetBox[i].num_updates = 5; 
            ups = 1;
            for(l=0; l<moov->PresetContainerBox.PresetBox[i].num_updates; l++){
                moov->PresetContainerBox.PresetBox[i].updateSample[l].update_sample_number = ups;
                for(j=0; j<totaltracks; j++){
                    printf("Sample position: %d\n",ups);
                    printf("Enter volume for %s\n",namet[j].title);
             //       scanf("%d",&vol);
                    moov->PresetContainerBox.PresetBox[i].updateSample[l].presVolumElem2[j].
                    preset_volume_element2 = 0x64;
                }
                ups = ups + 200; 
            }
         }
  */  
    }
    
    //Preset Container//
    u32 sizePRCO = sizePRST + 10;
    swap = byterevers(sizePRCO);
    moov->PresetContainerBox.size = swap; 
    swap = byterevers('prco');
    moov->PresetContainerBox.type = swap;
    defaultPreset = 1;
    moov->PresetContainerBox.default_preset_ID = defaultPreset; // Indicates initial preset activated.
    moov->PresetContainerBox.num_preset = numpres;
    
    return sizePRCO;
}

int rulescontainer(MovieBox *moov){
    int swap;
    u32 sizeRUSC, elementID, key_elem, sizeRUMX;
    
    moov->RulesContainer.num_selection_rules = 256; //u16 invert
    moov->RulesContainer.num_mixing_rules = 256;
    
    //Selection Rules
    sizeRUSC = 19 + 14;
    swap = byterevers(sizeRUSC);
    moov->RulesContainer.SelectionRules.size = swap; 
    swap = byterevers('rusc');
    moov->RulesContainer.SelectionRules.type = swap;
    moov->RulesContainer.SelectionRules.version = 0;
    moov->RulesContainer.SelectionRules.selection_rule_ID = 256;
    moov->RulesContainer.SelectionRules.selection_rule_type = 2; 
    elementID = 1;
    swap = byterevers(elementID);
    moov->RulesContainer.SelectionRules.element_ID = swap;  
    strcpy(moov->RulesContainer.SelectionRules.rule_description,"Not mute rule");
    
    //Mixing Rule
    sizeRUMX = 23 + 11;
    swap = byterevers(sizeRUMX);
    moov->RulesContainer.MixingRules.size = swap;
    swap = byterevers('rumx');
    moov->RulesContainer.MixingRules.type = swap;
    moov->RulesContainer.MixingRules.version = 0;
    moov->RulesContainer.MixingRules.mixing_rule_ID = 512; // Upper rule
    moov->RulesContainer.MixingRules.mixing_type = 1;
    elementID = 1;
    swap = byterevers(elementID);
    moov->RulesContainer.MixingRules.element_ID = swap;
    key_elem = 2;
    swap = byterevers(key_elem);
    moov->RulesContainer.MixingRules.key_elem_ID = swap;
    strcpy(moov->RulesContainer.MixingRules.mix_description, "Upper rule");
    
    //Rule container
    u32 sizeRUCO = 12 + sizeRUSC + sizeRUMX;
    swap = byterevers(sizeRUCO);
    moov->RulesContainer.size = swap;
    swap = byterevers('ruco');
    moov->RulesContainer.type = swap;
    
    return sizeRUCO;
}

void moovheaderbox (MovieBox *moov,int clock, int sizeTRAK, int sizePRCO, int totaltracks, 
                    int durationTrack, int sizeRUCO){
    int swap;

    //MovieHeader
    u32 sizeMVHD = 108;
    swap = byterevers (sizeMVHD);
    moov->MovieHeaderBox.size = swap;
    swap = byterevers ('mvhd');
    moov->MovieHeaderBox.type = swap;
    moov->MovieHeaderBox.version = 0;
    swap = byterevers (clock);
    moov->MovieHeaderBox.creation_time = swap;
    moov->MovieHeaderBox.modification_time = swap;
    swap = byterevers (1000);
    moov->MovieHeaderBox.timescale = swap;
    swap = byterevers (durationTrack);
    moov->MovieHeaderBox.duration = swap;
    swap = byterevers (0x00010000);
    moov->MovieHeaderBox.rate = swap;
    swap = byterevers (1);
    moov->MovieHeaderBox.volume = 1;
    moov->MovieHeaderBox.reserved=0;
    moov->MovieHeaderBox.reserved2[0] = 0;
    moov->MovieHeaderBox.reserved2[1] = 0;
    swap = byterevers (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 = byterevers (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;
    //    moov->MovieHeaderBox.next_track_ID = getnextID();
    swap = byterevers (totaltracks + 1);
    moov->MovieHeaderBox.next_track_ID = swap;
    
    //MovieBox
    u32 sizeMOOV = sizeMVHD + sizeTRAK + sizePRCO + sizeRUCO + 8;
    printf("Size moovie: %d, size trak: %d\n",sizeMOOV, sizeTRAK);
    swap = byterevers (sizeMOOV); //Size movie: Taking into account number tracks
    moov->size = swap;
    swap = byterevers ('moov');
    moov->type = swap;
}
/*
void groupscontainer(MovieBox *moov){
    
    int num, flg, i, j, numelem;
    char selectmode, groupname[30];
    char* fmt = "%[^\n]%*c";
    
    printf("Define the number of groups:\n");
    fflush(stdin);
    scanf("%d",&num);
    
    moov->GroupContainerBox.num_groups = num;
    
    for (i=0; i<num; i++) {
        
        printf("Select mode of group %d:\n",i+1);
        printf("Mode |   Display  |   Edit\n");
        printf("---- |   -------  |   ----\n");
        printf(" 1   |   disable  |   disable\n");
        printf(" 2   |   enable   |   disable\n");
        scanf("%d",&flg);
        getchar();
        fflush(stdin);
        
        moov->GroupContainerBox.GroupBox[i].flags = flg;  
        moov->GroupContainerBox.GroupBox[i].group_ID = 2147483648 + 1; // From 0x80000000 to 0xFFFFFFFF

        printf("Enter the name for group %d:\n", i+1);
        scanf(fmt,moov->GroupContainerBox.GroupBox[i].group_name);
        strcpy(groupname,moov->GroupContainerBox.GroupBox[i].group_name);
        
        printf("Enter a brief description for group %s:\n", groupname);
        scanf(fmt,moov->GroupContainerBox.GroupBox[i].group_description);
        moov->GroupContainerBox.GroupBox[i].num_elements = numelem;
        
        printf("Number of elements involved in group %d:\n", i+1);
        fflush(stdin);
        scanf("%d",&numelem);

                
        for (j=0; j<numelem; j++) {
            printf("Enter name for element %d of group %s\n",j+1,groupname);
            scanf("%s",moov->GroupContainerBox.GroupBox[i].element_ID[j]);
           // moov->GroupContainerBox.GroupBox[i].element_ID[j] = getelemID(); //Can be track or group
        }
        //printf("Select group activation mode:\n");
        //scanf("%d",selectmode);
        selectmode = 0;
        moov->GroupContainerBox.GroupBox[i].group_activation_mode = selectmode; //Depends on rules. For now just 0.
     //   if (selectmode == 2) {
     //       moov->GroupContainerBox.GroupBox[i].group_activation_elements_number = 0;
     //   }
        moov->GroupContainerBox.GroupBox[i].group_reference_volume = 1;
    }

}
*/
/*
void metadata(MetaBox *meta){

    int find = 0, i, j;
    char coc[4]; 
    
    meta->theHandler.pre_defined = 0;
    printf("Enter type of metadata:\n");
    printf("'soun' 'hint' 'meta'\n");
    fflush(stdin);
    scanf("%s", &coc);
    while (find == 0) {
        if (strcmp("soun", coc)==0) {
            meta->theHandler.handler_type = 'soun';
            find = 1;
        }
        if (strcmp("hint", coc)==0) {
            meta->theHandler.handler_type = 'hint';
            find = 1;
        }
        if (strcmp("meta", coc)==0) {
            meta->theHandler.handler_type = 'meta';
            find = 1;
        }
        if (find == 0) {
            printf("Type unknown, please enter type:\n");
            printf("'soun' 'hint' 'meta'\n");
            scanf("%s", &coc);
        }
    }
    printf("%d\n", meta->theHandler.handler_type);
    meta->theHandler.reserved[0] = 0;
    meta->theHandler.reserved[1] = 0;
    meta->theHandler.reserved[2] = 0;
    printf("Name:\n");
    fflush(stdin);
    scanf("%s", meta->theHandler.name);
    //In case items are stored online: 
    //meta->dinfo = ....;
    
    //Item location box
    //Size = Index_Size(4), base_offset_size(4),length(4),offset(4) = 16 bits
    //Each one has size 0, 4 or 8.
    //Assume same size for all = 8.It can be different
    meta->ItemLocationBox.Size = 0x4444;
    meta->ItemLocationBox.item_count = 0;
    for (i=0; i<meta->ItemLocationBox.item_count; i++) {
        //Check the value!!! I don't understand.
        meta->ItemLocationBox.c_method = 0x0001; //=0 Taken from field, 1(idat) or 2(item)
    }
    //These values have to be rechecked 
    meta->ItemLocationBox.data_reference_index = 0; //In this file
    meta->ItemLocationBox.base_offset = 0; //Check value!!!
    meta->ItemLocationBox.extent_count = 1; 
    for (j=0; j<meta->ItemLocationBox.extent_count; j++) {
        meta->ItemLocationBox.extent_index = 1;
    }
    meta->ItemLocationBox.extent_offset = 0;
    meta->ItemLocationBox.extent_length = 0;
    
    //Rest of the parameters
}
*/

void writemoovbox(MovieBox moov, int numtrack,int totaltracks, FILE *imf){
    //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);
        
        int i, swap, pos;
        //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 = byterevers(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 = byterevers(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);
    }
    
    //Preset Container//
    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
    int j,i;
    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);
        for (j=0; j< moov.PresetContainerBox.PresetBox[i].num_preset_elements; j++) {
            fwrite(&moov.PresetContainerBox.PresetBox[i].presVolumElem[j].
                    preset_volume_element,sizeof(unsigned char), 1, imf);
        }
        for (j=0; j<14; j++) {
            fwrite(&moov.PresetContainerBox.PresetBox[i].preset_name[j], sizeof(char), 1, imf);
        }
    }
    
    //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);
    for(i=0; i<14; 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);
    fwrite(&moov.RulesContainer.MixingRules.key_elem_ID, sizeof(u32), 1, imf);
    for(i=0; i<11; i++){
        fwrite(&moov.RulesContainer.MixingRules.mix_description[i],
               sizeof(char), 1, imf);
    }
    
}

int byterevers(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;
}