annotate main/imafdecoder.cpp @ 634:ba338234c001 imaf_enc

IMAF load code from Jesus Corral Garcia
author Chris Cannam
date Mon, 04 Nov 2013 17:15:52 +0000
parents
children
rev   line source
Chris@634 1 //Jesús Corral García
Chris@634 2 //Universidad de Málaga
Chris@634 3
Chris@634 4 #include <stdio.h>
Chris@634 5 #include <stdlib.h>
Chris@634 6 #include <string.h>
Chris@634 7 #include <QTextStream>
Chris@634 8 #include <QString>
Chris@634 9 #include "MainWindow.h"
Chris@634 10
Chris@634 11
Chris@634 12 int audiotracks; //number of audio tracks contained inside the IM AF file
Chris@634 13
Chris@634 14 int mainIMAFdecoder(QString outimaf){
Chris@634 15
Chris@634 16 FILE *imf,*audiotrack;
Chris@634 17 int d=0,i,j,sizemdat,audiosize;
Chris@634 18 int chunkoffset[64]; // if you want more than 64 tracks , change this value.
Chris@634 19 unsigned char dat,dat1,dat2,dat3;
Chris@634 20 QTextStream out(stdout);
Chris@634 21
Chris@634 22 imf = fopen (outimaf.toStdString().c_str(),"rb");
Chris@634 23
Chris@634 24 fseek (imf,0,SEEK_SET);
Chris@634 25 fseek (imf,24,SEEK_CUR); //jump to 'mdat'
Chris@634 26
Chris@634 27 fread(&dat, sizeof(unsigned char), 1, imf);
Chris@634 28 fread(&dat1, sizeof(unsigned char), 1, imf);
Chris@634 29 fread(&dat2, sizeof(unsigned char), 1, imf);
Chris@634 30 fread(&dat3, sizeof(unsigned char), 1, imf);
Chris@634 31
Chris@634 32 sizemdat = (dat<<24) | (dat1<<16) | (dat2<<8) | (dat3);
Chris@634 33
Chris@634 34 if (sizemdat==1){ // if conformance file
Chris@634 35 fread(&dat, sizeof(unsigned char), 1, imf);
Chris@634 36 fread(&dat1, sizeof(unsigned char), 1, imf);
Chris@634 37 fread(&dat2, sizeof(unsigned char), 1, imf);
Chris@634 38 fread(&dat3, sizeof(unsigned char), 1, imf);
Chris@634 39 fread(&dat, sizeof(unsigned char), 1, imf);
Chris@634 40 fread(&dat1, sizeof(unsigned char), 1, imf);
Chris@634 41 fread(&dat2, sizeof(unsigned char), 1, imf);
Chris@634 42 fread(&dat3, sizeof(unsigned char), 1, imf);
Chris@634 43 fread(&dat, sizeof(unsigned char), 1, imf);
Chris@634 44 fread(&dat1, sizeof(unsigned char), 1, imf);
Chris@634 45 fread(&dat2, sizeof(unsigned char), 1, imf);
Chris@634 46 fread(&dat3, sizeof(unsigned char), 1, imf);
Chris@634 47 sizemdat = (dat<<24) | (dat1<<16) | (dat2<<8) | (dat3);
Chris@634 48
Chris@634 49 fseek(imf,sizemdat-16,SEEK_CUR);
Chris@634 50 }
Chris@634 51 else {
Chris@634 52
Chris@634 53 fseek(imf, sizemdat-4, SEEK_CUR); // -4 because we have to sub the 4 bytes of size
Chris@634 54 }
Chris@634 55
Chris@634 56 fseek (imf,16,SEEK_CUR);
Chris@634 57 fseek (imf,96,SEEK_CUR); // next track id is placed 96 bytes after the last byte of type 'mvhd'
Chris@634 58
Chris@634 59 fread(&dat, sizeof(unsigned char), 1, imf);
Chris@634 60 fread(&dat1, sizeof(unsigned char), 1, imf);
Chris@634 61 fread(&dat2, sizeof(unsigned char), 1, imf);
Chris@634 62 fread(&dat3, sizeof(unsigned char), 1, imf);
Chris@634 63
Chris@634 64 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
Chris@634 65
Chris@634 66
Chris@634 67 if (audiotracks == 12345678){
Chris@634 68
Chris@634 69 audiotracks = 6; // for the conformance file 2
Chris@634 70
Chris@634 71 }
Chris@634 72 for (j=1;j<=audiotracks;j++){
Chris@634 73
Chris@634 74 d=0;
Chris@634 75 while (d==0){
Chris@634 76
Chris@634 77 fread(&dat, sizeof(unsigned char), 1, imf);
Chris@634 78 fread(&dat1, sizeof(unsigned char), 1, imf);
Chris@634 79 fread(&dat2, sizeof(unsigned char), 1, imf);
Chris@634 80 fread(&dat3, sizeof(unsigned char), 1, imf);
Chris@634 81
Chris@634 82
Chris@634 83 if (dat == 0x68 && dat1 == 0x64 && dat2 == 0x6C && dat3 == 0x72) { // 68646C72 = hdlr
Chris@634 84 d=1;
Chris@634 85 }
Chris@634 86
Chris@634 87 else{
Chris@634 88 fseek(imf, -3, SEEK_CUR); //if we have not readen ´hdlr´
Chris@634 89 }
Chris@634 90
Chris@634 91 } //close while
Chris@634 92
Chris@634 93 for (i=1;i<=8;i++){ //handler type is placed eight bytes after the last byte of type 'hdlr'
Chris@634 94
Chris@634 95 fread(&dat, sizeof(unsigned char), 1, imf);
Chris@634 96 }
Chris@634 97
Chris@634 98 fread(&dat, sizeof(unsigned char), 1, imf);//dat could be ´s´ (soun) or ´t´(text)
Chris@634 99
Chris@634 100 d=0;
Chris@634 101 if (dat==0x73){ //73 = ´s´
Chris@634 102
Chris@634 103 while (d==0){
Chris@634 104
Chris@634 105 fread(&dat, sizeof(unsigned char), 1, imf);
Chris@634 106 fread(&dat1, sizeof(unsigned char), 1, imf);
Chris@634 107 fread(&dat2, sizeof(unsigned char), 1, imf);
Chris@634 108 fread(&dat3, sizeof(unsigned char), 1, imf);
Chris@634 109
Chris@634 110 if (dat == 0x63 && dat1 == 0x6F && dat2 == 0x36 && dat3 == 0x34) { // 636F3634 = co64
Chris@634 111 d=1;
Chris@634 112 }
Chris@634 113 else if (dat == 0x73 && dat1 == 0x74 && dat2 == 0x63 && dat3 == 0x6F){ //7374636F = stco
Chris@634 114 d=2;
Chris@634 115 }
Chris@634 116
Chris@634 117 else{
Chris@634 118 fseek(imf, -3, SEEK_CUR); //if we have not readen ´stco´
Chris@634 119 }
Chris@634 120
Chris@634 121 } //close while
Chris@634 122 if (d==1){ // if co64
Chris@634 123 for (i=1;i<=12;i++){
Chris@634 124
Chris@634 125 fread(&dat, sizeof(unsigned char), 1, imf);
Chris@634 126 }
Chris@634 127 }
Chris@634 128 if (d==2){// if stco
Chris@634 129 for (i=1;i<=8;i++){
Chris@634 130
Chris@634 131 fread(&dat, sizeof(unsigned char), 1, imf);
Chris@634 132 }
Chris@634 133 }
Chris@634 134
Chris@634 135
Chris@634 136 fread(&dat, sizeof(unsigned char), 1, imf);
Chris@634 137 fread(&dat1, sizeof(unsigned char), 1, imf);
Chris@634 138 fread(&dat2, sizeof(unsigned char), 1, imf);
Chris@634 139 fread(&dat3, sizeof(unsigned char), 1, imf);
Chris@634 140
Chris@634 141 chunkoffset[j-1] = (dat<<24) | (dat1<<16) | (dat2<<8) | (dat3);
Chris@634 142
Chris@634 143
Chris@634 144 }//close if
Chris@634 145
Chris@634 146
Chris@634 147 } //close for
Chris@634 148 //At this point, we will look for a text track. If d=2 there are no lyrics
Chris@634 149 d=0;
Chris@634 150 while (d==0){
Chris@634 151
Chris@634 152 fread(&dat, sizeof(unsigned char), 1, imf);
Chris@634 153 fread(&dat1, sizeof(unsigned char), 1, imf);
Chris@634 154 fread(&dat2, sizeof(unsigned char), 1, imf);
Chris@634 155 fread(&dat3, sizeof(unsigned char), 1, imf);
Chris@634 156
Chris@634 157 if (feof (imf )){// if end of file -> no lyrics
Chris@634 158 d=2;
Chris@634 159 }
Chris@634 160 else if (dat == 0x68 && dat1 == 0x64 && dat2 == 0x6C && dat3 == 0x72) { // 68646C72 = hdlr
Chris@634 161 d=1;
Chris@634 162 }
Chris@634 163 else{
Chris@634 164 fseek(imf, -3, SEEK_CUR); //if we have not readen ´hdlr´
Chris@634 165 }
Chris@634 166
Chris@634 167 } //close while
Chris@634 168
Chris@634 169
Chris@634 170 // At this point, we know the position of the audio tracks in mdat and the number of tracks.
Chris@634 171 // Now we will separate the audio tracks in several MP3.
Chris@634 172
Chris@634 173 fseek(imf, 0, SEEK_SET);
Chris@634 174 for (j=0;j<chunkoffset[0];j++) //advance to the position of the first audio track contained in mdat
Chris@634 175 {
Chris@634 176 fread(&dat, sizeof(unsigned char), 1, imf);
Chris@634 177 }
Chris@634 178
Chris@634 179 for(i=0;i<audiotracks-1;i++){
Chris@634 180
Chris@634 181
Chris@634 182 char buf[2];
Chris@634 183 sprintf(buf, "%d", i);// convert int to char
Chris@634 184 audiotrack =fopen (buf,"wb");
Chris@634 185
Chris@634 186 for (j=chunkoffset[i];j<chunkoffset[i+1];j++){
Chris@634 187 fread(&dat,sizeof(unsigned char),1,imf);
Chris@634 188 fwrite (&dat,sizeof(unsigned char),1,audiotrack);
Chris@634 189 }
Chris@634 190 fclose (audiotrack);
Chris@634 191
Chris@634 192 } // close for
Chris@634 193
Chris@634 194 //last audio track
Chris@634 195
Chris@634 196 char buf[2];
Chris@634 197 sprintf(buf, "%d", audiotracks-1); //convert int to char
Chris@634 198 audiotrack =fopen (buf,"wb");
Chris@634 199 audiosize = chunkoffset[2]-chunkoffset[1]; //calculate the size of one audio track. Every audio track must be the same size
Chris@634 200 for (i=1;i<=audiosize;i++)
Chris@634 201 {
Chris@634 202 fread(&dat,sizeof(unsigned char),1,imf);
Chris@634 203 fwrite (&dat,sizeof(unsigned char),1,audiotrack);
Chris@634 204 }
Chris@634 205
Chris@634 206 fclose (audiotrack);
Chris@634 207 fclose (imf);
Chris@634 208 return d;
Chris@634 209
Chris@634 210
Chris@634 211
Chris@634 212 }