Ticket #8000: extract.c

File extract.c, 7.4 KB (added by SF/kirschsaft, 18 years ago)

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