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 }
|