Ticket #7978: extract.c

File extract.c, 8.6 KB (added by SF/kirschsaft, 22 years ago)

enhanced extract.c

Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <sys/stat.h>
5//#include <unistd.h>
6
7//define defaults
8#define minBitrDef 24
9#define maxBitrDef 64
10#define abrDef 0
11#define vbrDef 1
12#define algqualDef 2
13#define vbrqualDef 4
14
15FILE *input, *output_idx, *output_snd;
16
17char fbuf_temp[1024];
18unsigned char buf[256];
19
20unsigned char f_hdr[] = {
21 'S', 'O', 'U', ' ', 0, 0, 0, 0, 0
22};
23
24unsigned char v_hdr[] = {
25 'V', 'C', 'T', 'L', 0, 0, 0, 0xA, 0xF, 0xFF
26};
27
28unsigned char c_hdr[] = {
29 'C', 'r', 'e', 'a', 't', 'i', 'v', 'e', ' ', 'V', 'o', 'i', 'c', 'e',
30 ' ', 'F', 'i', 'l', 'e', 0x1a, 0x1a, 0x00, 0x0A, 0x01, 0x29, 0x11
31};
32
33struct lameparams {
34 unsigned int minBitr;
35 unsigned int maxBitr;
36 unsigned int abr;
37 unsigned int vbr;
38 unsigned int algqual;
39 unsigned int vbrqual;
40 unsigned int silent;
41 } encparms = { minBitrDef, maxBitrDef, abrDef, vbrDef, algqualDef, vbrqualDef,0};
42
43
44
45void put_int(unsigned int val);
46
47void end_of_file(void)
48{
49 FILE *in;
50 int idx_size = ftell(output_idx);
51 int size;
52 char buf[2048];
53
54 fclose(output_snd);
55 fclose(output_idx);
56
57 output_idx = fopen("monster.so3", "wb");
58 put_int(idx_size);
59
60 in = fopen("monster.idx", "rb");
61 while ((size = fread(buf, 1, 2048, in)) > 0) {
62 fwrite(buf, 1, size, output_idx);
63 }
64 fclose(in);
65 in = fopen("monster.mp3", "rb");
66 while ((size = fread(buf, 1, 2048, in)) > 0) {
67 fwrite(buf, 1, size, output_idx);
68 }
69 fclose(in);
70 fclose(output_idx);
71
72 exit(-1);
73}
74
75void get_string(int size)
76{
77 int i = 0;
78 while (i < size) {
79 int c = fgetc(input);
80 if (c == EOF)
81 end_of_file();
82 buf[i++] = c;
83 }
84 buf[i] = '\0';
85}
86
87int get_int(int size)
88{
89 int ret = 0;
90 while (size > 0) {
91 int c = fgetc(input);
92 if (c == EOF)
93 end_of_file();
94 ret <<= 8;
95 ret |= c;
96 size--;
97 }
98 return ret;
99}
100void append_byte(int size)
101{
102 int i;
103 int c;
104 for (i = 0; i < (size - 1); i++)
105 buf[i] = buf[i + 1];
106 c = fgetc(input);
107 if (c == EOF)
108 end_of_file();
109 buf[i] = c;
110}
111
112void put_int(unsigned int val)
113{
114 int i;
115 for (i = 0; i < 4; i++) {
116 fputc(val >> 24, output_idx);
117 val <<= 8;
118 }
119}
120
121void get_part(void)
122{
123 int id;
124 int pos = ftell(input);
125 int tags;
126
127 /* The VCTL header */
128 get_string(4);
129 while (strncmp(buf, "VCTL", 4)) {
130 pos++;
131 append_byte(4);
132 }
133 tags = get_int(4);
134 tags -= 8;
135
136 put_int(pos);
137 put_int(ftell(output_snd));
138 if (tags < 0)
139 exit(-1);
140 put_int(tags);
141 while (tags > 0) {
142 fputc(fgetc(input), output_snd);
143 tags--;
144 }
145
146 get_string(8);
147 if (!strncmp(buf, "Creative", 8)) {
148 get_string(18);
149 } else if (!strncmp(buf, "VTLK", 4)) {
150 get_string(26);
151 } else {
152 exit(-1);
153 }
154 printf("Voice file found (pos = %d) :", pos);
155
156 id = fgetc(input);
157 switch (id) {
158 case 0x01:{
159 int length = 0;
160 int i;
161 int sample_rate;
162 int comp;
163 FILE *f;
164 char fbuf[2048];
165 char fbuf_o[4096];
166 int size;
167 int tot_size;
168 int real_samplerate;
169 char rawname[256];
170 char mp3name[256];
171#ifdef DEBUG
172 static int sound_num = 0;
173#endif
174
175 /* Sound Data */
176 printf(" Sound Data\n");
177 for (i = 0; i < 3; i++)
178 length = length | (fgetc(input) << (i * 8));
179 printf(" - length = %d\n", length);
180 sample_rate = fgetc(input);
181 comp = fgetc(input);
182 real_samplerate = 1000000 / (256 - sample_rate);
183 printf(" - sample rate = %d (%02x)\n", 1000000 / (256 - sample_rate), sample_rate);
184 printf(" - compression = %s (%02x)\n",
185 (comp ==
186 0 ? "8bits" : (comp ==
187 1 ? "4bits" : (comp ==
188 2 ? "2.6bits" : (comp ==
189 3 ? "2bits" : "Multi")))), comp);
190
191 /* real_samplerate = (sample_rate == 0xd5 ? 22050 :
192 (sample_rate == 0xd3 ? 22050 :
193 (sample_rate == 0xd2 ? 22050 :
194 (sample_rate == 0xa5 ? 11025 :
195 (sample_rate == 0xa6 ? 11025 :
196 (sample_rate == 0x83 ? 8000 :
197 -1)))))); */
198 if (comp != 0) {
199 exit(-1);
200 }
201#if 1
202#ifdef DEBUG
203 sprintf(rawname, "tempfile_%05d.raw", sound_num);
204 sprintf(mp3name, "tempfile_%05d.mp3", sound_num++);
205#else
206 sprintf(rawname, "tempfile.raw");
207 sprintf(mp3name, "tempfile.mp3");
208#endif
209 f = fopen(rawname, "wb");
210 length -= 2;
211 while (length > 0) {
212 size = fread(fbuf, 1, length > 2048 ? 2048 : length, input);
213 if (size <= 0)
214 break;
215 length -= size;
216 for (i = 0; i < size; i++) {
217 fbuf_o[2 * i] = fbuf[i] ^ 0x80;
218 fbuf_o[2 * i + 1] = 0;
219 }
220 fwrite(fbuf_o, 1, 2 * size, f);
221 }
222 fclose(f);
223#else
224 fseek(input, length - 2, SEEK_CUR);
225#endif
226
227#if 1
228
229 if(encparms.abr==1)
230 sprintf(fbuf_temp,"--abr %i",encparms.minBitr);
231 else
232 sprintf(fbuf_temp,"--vbr-new -b %i",encparms.minBitr);
233 if(encparms.silent==1)
234 strcat(fbuf_temp," --silent");
235 sprintf(fbuf,
236 "lame -t -q %i %s -V %i -B %i --resample 22.05 -m m --bitwidth 16 -r -s %d %s %s",
237 encparms.algqual,fbuf_temp,encparms.vbrqual,
238 encparms.maxBitr,real_samplerate, rawname, mp3name);
239 /*sprintf(fbuf,
240 "lame -h -t -q 0 --vbr-new -V 4 -b 24 -B 64 --resample 22.05 -m m --bitwidth 16 -r -s %d %s %s",
241 real_samplerate, rawname, mp3name);*/
242 system(fbuf);
243
244 f = fopen(mp3name, "rb");
245 tot_size = 0;
246 while ((size = fread(fbuf, 1, 2048, f)) > 0) {
247 tot_size += size;
248 fwrite(fbuf, 1, size, output_snd);
249 }
250 fclose(f);
251 put_int(tot_size);
252#endif
253 }
254 break;
255
256 default:
257 printf("Unknown chunk : %02x\n", id);
258 exit(-1);
259 break;
260 }
261}
262
263void showhelp(char *exename)
264{
265 printf("\nUsage: %s monster.sou <params>\n",exename);
266 printf("\nParams:\n");
267 printf("-b <rate> <rate> is the target bitrate(ABR)/minimal bitrate(VBR)(default:%i)\n",minBitrDef);
268 printf("-B <rate> <rate> is the maximum VBR/ABR bitrate (default:%i)\n",maxBitrDef);
269 printf("--vbr LAME uses the VBR mode (default)\n");
270 printf("--abr LAME uses the ABR mode\n");
271 printf("-V <value> specifies the value (0 - 9) of VBR quality (0=best)(default:%i)\n",vbrqualDef);
272 printf("-q <value> specifies the MPEG algorithm quality (0-9; 0=best) (default:%i)\n",algqualDef);
273 printf("--silent the output of LAME is hidden (default:disabled)\n");
274 printf("\n\nIf a parameter is not given the default value is used\n");
275 printf("If using VBR mode -b and -B must be multiples of 8; the maximum is 160!\n");
276 exit(2);
277}
278
279int main(int argc, char *argv[])
280{
281 int i;
282 if(argc < 2)
283 showhelp(argv[0]);
284 for(i=1;i<argc;i++){
285 if(strcmp(argv[i],"--vbr")==0){
286 encparms.vbr=1;
287 encparms.abr=0;
288 }
289 else if(strcmp(argv[i],"--abr")==0){
290 encparms.vbr=0;
291 encparms.abr=1;
292 }
293 else if(strcmp(argv[i],"-b")==0){
294 encparms.minBitr=atoi(argv[i+1]);
295 if(encparms.minBitr % 8 != 0)
296 encparms.minBitr-=encparms.minBitr % 8;
297 if(encparms.minBitr >160)
298 encparms.minBitr=160;
299 if(encparms.minBitr <8)
300 encparms.minBitr=8;
301 i++;
302 }
303 else if(strcmp(argv[i],"-B")==0){
304 encparms.maxBitr=atoi(argv[i+1]);
305 if(encparms.maxBitr % 8 != 0)
306 encparms.maxBitr -=encparms.minBitr % 8;
307 if(encparms.maxBitr >160)
308 encparms.maxBitr=160;
309 if(encparms.maxBitr <8)
310 encparms.maxBitr=8;
311 i++;
312 }
313 else if(strcmp(argv[i],"-V")==0){
314 encparms.vbrqual=atoi(argv[i+1]);
315 if(encparms.vbrqual<0)
316 encparms.vbrqual=0;
317 if(encparms.vbrqual>9)
318 encparms.vbrqual=9;
319 i++;
320 }
321 else if(strcmp(argv[i],"-q")==0){
322 encparms.algqual=atoi(argv[i+1]);
323 if(encparms.algqual<0)
324 encparms.algqual=0;
325 if(encparms.algqual>9)
326 encparms.algqual=9;
327 i++;
328 }
329 else if(strcmp(argv[i],"--silent")==0)
330 encparms.silent=1;
331 }
332 input = fopen(argv[1], "rb");
333 if (!input) {
334 printf("Cannot open file: %s\n", argv[1]);
335 exit(-1);
336 }
337
338 output_idx = fopen("monster.idx", "wb");
339 output_snd = fopen("monster.mp3", "wb");
340
341 /* Get the 'SOU ....' header */
342 get_string(8);
343 if (strncmp(buf, f_hdr, 8)) {
344 printf("Bad SOU\n");
345 exit(-1);
346 }
347 while (1)
348 get_part();
349
350 fclose(output_idx);
351 fclose(output_snd);
352 fclose(input);
353
354 /* And the final concatenation */
355
356 return 0;
357}