bin_to_cso_mp3 improved
[picodrive.git] / tools / bin_to_cso_mp3 / bin_to_cso_mp3.c
CommitLineData
c0fcf293 1/*\r
2 * bin_to_cso_mp3\r
3 * originally written by Exophase as "bin_to_iso_ogg"\r
4 * updated for cso/mp3 by notaz\r
f8a64101 5 * v2\r
c0fcf293 6 */\r
7#include <stdio.h>\r
8#include <stdlib.h>\r
9#include <unistd.h>\r
10#include <sys/stat.h>\r
11#include <string.h>\r
f8a64101 12#include <ctype.h>\r
c0fcf293 13\r
14#ifndef MAX_PATH\r
15#define MAX_PATH 1024\r
16#endif\r
17\r
18#ifdef _WIN32\r
19#include <windows.h>\r
20\r
21#define DIR_SEPARATOR_CHAR '\\'\r
22#define PATH_SEPARATOR_CHAR ';'\r
23#define LAME_BINARY "lame.exe"\r
24#define CISO_BINARY "ciso.exe"\r
25#define NULL_REDIR "> NUL 2>&1"\r
26#else\r
27#define DIR_SEPARATOR_CHAR '/'\r
28#define PATH_SEPARATOR_CHAR ':'\r
29#define LAME_BINARY "lame"\r
30#define CISO_BINARY "ciso"\r
31#define NULL_REDIR "> /dev/null 2>&1"\r
32#define mkdir(x) mkdir(x, S_IRWXU)\r
33#endif\r
34\r
35#define LAME_OPTIONS "-h --cbr"\r
36\r
37typedef unsigned char u8;\r
38typedef unsigned short int u16;\r
39typedef unsigned int u32;\r
40typedef unsigned long long int u64;\r
41typedef signed char s8;\r
42typedef signed short int s16;\r
43typedef signed int s32;\r
44typedef signed long long int s64;\r
45\r
46typedef enum\r
47{\r
48 TRACK_FILE_TYPE_BINARY,\r
49 TRACK_FILE_TYPE_WAVE,\r
50} track_file_type_enum;\r
51\r
52typedef struct\r
53{\r
54 u32 file_number;\r
55 u32 physical_offset;\r
56\r
57 u32 sector_offset;\r
58 u32 sector_count;\r
59 u32 pregap_offset;\r
60\r
61 u32 sector_size;\r
62 u32 format_type;\r
63} cd_track_struct;\r
64\r
65typedef struct\r
66{\r
67 track_file_type_enum type;\r
68 FILE *file_handle;\r
69\r
70 u32 current_offset;\r
71} cd_track_file_struct;\r
72\r
73typedef struct\r
74{\r
75 FILE *bin_file;\r
76 cd_track_file_struct track_files[100];\r
77 u32 num_files;\r
78\r
79 s32 first_track;\r
80 s32 last_track;\r
81 u32 num_physical_tracks;\r
82 u32 num_sectors;\r
83 s32 last_seek_track;\r
84\r
85 cd_track_struct physical_tracks[100];\r
86 cd_track_struct *logical_tracks[100];\r
87} cd_bin_struct;\r
88\r
89\r
90cd_bin_struct cd_bin;\r
91int opt_use_mp3 = 1;\r
92int opt_mp3_bitrate = 128;\r
93int opt_use_cso = 1;\r
94\r
95static void myexit(int code)\r
96{\r
97#ifdef _WIN32\r
98 system("pause");\r
99#endif\r
100 exit(code);\r
101}\r
102\r
103char *skip_whitespace(char *str)\r
104{\r
f8a64101 105 while (isspace(*str))\r
c0fcf293 106 str++;\r
107\r
108 return str;\r
109}\r
110\r
f8a64101 111char *skip_whitespace_rev(char *str)\r
112{\r
113 while (isspace(*str))\r
114 str--;\r
115\r
116 return str;\r
117}\r
118\r
119char *skip_nonspace_rev(char *str)\r
120{\r
121 while (!isspace(*str))\r
122 str--;\r
123\r
124 return str;\r
125}\r
126\r
c0fcf293 127s32 load_bin_cue(char *cue_file_name)\r
128{\r
129 FILE *cue_file = fopen(cue_file_name, "rb");\r
130\r
131 printf("loading cue file %s\n", cue_file_name);\r
132\r
133 if(cue_file)\r
134 {\r
135 char line_buffer[256];\r
136 char *line_buffer_ptr;\r
f8a64101 137 char *tmp;\r
c0fcf293 138\r
139 char bin_file_name[MAX_PATH];\r
140 char *separator_pos;\r
141 s32 current_physical_track_number = -1;\r
142 u32 current_physical_offset;\r
143 u32 current_pregap = 0;\r
144 u32 bin_file_size;\r
145\r
146 cd_track_struct *current_physical_track = NULL;\r
147\r
148 u32 i;\r
149\r
150 // First, get filename. Only support binary right now.\r
f8a64101 151 tmp = fgets(line_buffer, 255, cue_file);\r
152 if (tmp == NULL) goto invalid;\r
153 separator_pos = line_buffer + strlen(line_buffer) - 1;\r
154 separator_pos = skip_whitespace_rev(separator_pos);\r
155 if (separator_pos <= line_buffer) goto invalid;\r
156 separator_pos = skip_nonspace_rev(separator_pos);\r
157 if (separator_pos <= line_buffer) goto invalid;\r
158 separator_pos = skip_whitespace_rev(separator_pos);\r
159 if (separator_pos <= line_buffer) goto invalid;\r
160 // see if what's there is a quote.\r
161 if(*separator_pos == '"')\r
162 {\r
163 separator_pos[0] = 0;\r
164 separator_pos = strrchr(line_buffer, '"');\r
165 if (separator_pos == NULL) goto invalid;\r
166 strcpy(bin_file_name, separator_pos + 1);\r
167 }\r
168 else\r
169 {\r
170 // Otherwise go to the next space.\r
171 separator_pos[1] = 0;\r
172 separator_pos = strrchr(line_buffer, ' ');\r
173 if (separator_pos == NULL) goto invalid;\r
174 strcpy(bin_file_name, separator_pos + 1);\r
175 }\r
c0fcf293 176\r
177 // Might have to change directory first.\r
178 separator_pos = strrchr(cue_file_name, DIR_SEPARATOR_CHAR);\r
179\r
180 if(separator_pos)\r
181 {\r
182 char current_dir[MAX_PATH];\r
183 getcwd(current_dir, MAX_PATH);\r
184\r
185 *separator_pos = 0;\r
186\r
187 chdir(cue_file_name);\r
188\r
189#ifdef GP2X_BUILD\r
190 cd_bin.bin_file = open(bin_file_name, O_RDONLY);\r
191#else\r
192 cd_bin.bin_file = fopen(bin_file_name, "rb");\r
193#endif\r
194\r
c0fcf293 195 *separator_pos = DIR_SEPARATOR_CHAR;\r
196 chdir(current_dir);\r
197 }\r
198 else\r
199 {\r
200#ifdef GP2X_BUILD\r
201 cd_bin.bin_file = open(bin_file_name, O_RDONLY);\r
202#else\r
203 cd_bin.bin_file = fopen(bin_file_name, "rb");\r
204#endif\r
205 }\r
206\r
f8a64101 207 if (cd_bin.bin_file == NULL)\r
208 {\r
209 printf("can't open bin file: \"%s\"\n", bin_file_name);\r
210 return -1;\r
211 }\r
212 else\r
213 {\r
214 printf("found bin file: %s\n", bin_file_name);\r
215 }\r
216\r
c0fcf293 217 for(i = 0; i < 100; i++)\r
218 {\r
219 cd_bin.logical_tracks[i] = NULL;\r
220 }\r
221\r
222 cd_bin.first_track = -1;\r
223 cd_bin.last_track = -1;\r
224 cd_bin.num_physical_tracks = 0;\r
225 cd_bin.num_sectors = 0;\r
226\r
227 // Get line\r
228 while(fgets(line_buffer, 256, cue_file))\r
229 {\r
230 // Skip trailing whitespace\r
231 line_buffer_ptr = skip_whitespace(line_buffer);\r
232\r
233 // Dirty, but should work - switch on first character.\r
234 switch(line_buffer_ptr[0])\r
235 {\r
236 // New track number\r
237 case 'T':\r
238 {\r
239 u32 new_track_number;\r
240 char track_type[64];\r
241\r
242 sscanf(line_buffer_ptr, "TRACK %d %s", &new_track_number,\r
243 track_type);\r
244\r
245 current_physical_track_number++;\r
246 current_physical_track =\r
247 cd_bin.physical_tracks + current_physical_track_number;\r
248\r
249 current_physical_track->sector_size = 2352;\r
250\r
251 if(!strcmp(track_type, "AUDIO"))\r
252 {\r
253 current_physical_track->format_type = 0;\r
254 current_physical_track->sector_size = 2352;\r
255 }\r
256\r
257 if(!strcmp(track_type, "MODE1/2352"))\r
258 {\r
259 current_physical_track->format_type = 4;\r
260 current_physical_track->sector_size = 2352;\r
261 }\r
262\r
263 if(!strcmp(track_type, "MODE1/2048"))\r
264 {\r
265 current_physical_track->format_type = 4;\r
266 current_physical_track->sector_size = 2048;\r
267 }\r
268\r
269 cd_bin.logical_tracks[new_track_number] = current_physical_track;\r
270 cd_bin.num_physical_tracks++;\r
271\r
272 if((cd_bin.first_track == -1) ||\r
273 (new_track_number < cd_bin.first_track))\r
274 {\r
275 cd_bin.first_track = new_track_number;\r
276 }\r
277\r
278 if((cd_bin.last_track == -1) ||\r
279 (new_track_number > cd_bin.last_track))\r
280 {\r
281 cd_bin.last_track = new_track_number;\r
282 }\r
283\r
284 break;\r
285 }\r
286\r
287 // Pregap\r
288 case 'P':\r
289 {\r
290 u32 minutes, seconds, frames;\r
291\r
292 sscanf(line_buffer_ptr, "PREGAP %d:%d:%d", &minutes,\r
293 &seconds, &frames);\r
294\r
295 current_pregap += frames + (seconds * 75) + (minutes * 75 * 60);\r
296 break;\r
297 }\r
298\r
299 // Index\r
300 case 'I':\r
301 {\r
302 u32 index_number;\r
303 u32 minutes, seconds, frames;\r
304 u32 sector_offset;\r
305\r
306 sscanf(line_buffer_ptr, "INDEX %d %d:%d:%d", &index_number,\r
307 &minutes, &seconds, &frames);\r
308\r
309 sector_offset = frames + (seconds * 75) + (minutes * 75 * 60);\r
310\r
311 if(index_number == 1)\r
312 {\r
313 current_physical_track->pregap_offset = current_pregap;\r
314 current_physical_track->sector_offset = sector_offset;\r
315 }\r
316\r
317 break;\r
318 }\r
319 }\r
320 }\r
321\r
322 current_physical_offset = 0;\r
323\r
324 for(i = 0; i < cd_bin.num_physical_tracks - 1; i++)\r
325 {\r
326 cd_bin.physical_tracks[i].sector_count =\r
327 cd_bin.physical_tracks[i + 1].sector_offset -\r
328 cd_bin.physical_tracks[i].sector_offset;\r
329\r
330 cd_bin.physical_tracks[i].physical_offset = current_physical_offset;\r
331 current_physical_offset += (cd_bin.physical_tracks[i].sector_count *\r
332 cd_bin.physical_tracks[i].sector_size);\r
333\r
334 cd_bin.physical_tracks[i].sector_offset +=\r
335 cd_bin.physical_tracks[i].pregap_offset;\r
336\r
337 cd_bin.num_sectors += cd_bin.physical_tracks[i].sector_count;\r
338 }\r
339\r
340#ifdef GP2X_BUILD\r
341 bin_file_size = lseek(cd_bin.bin_file, 0, SEEK_END);\r
342 lseek(cd_bin.bin_file, 0, SEEK_SET);\r
343#else\r
344 fseek(cd_bin.bin_file, 0, SEEK_END);\r
345 bin_file_size = ftell(cd_bin.bin_file);\r
346 fseek(cd_bin.bin_file, 0, SEEK_SET);\r
347#endif\r
348\r
349 // Set the last track data\r
350 cd_bin.physical_tracks[i].physical_offset = current_physical_offset;\r
351 cd_bin.physical_tracks[i].sector_offset +=\r
352 cd_bin.physical_tracks[i].pregap_offset;\r
353 cd_bin.physical_tracks[i].sector_count =\r
354 (bin_file_size - current_physical_offset) /\r
355 cd_bin.physical_tracks[i].sector_size;\r
356\r
357 cd_bin.num_sectors += cd_bin.physical_tracks[i].sector_count;\r
358\r
359 printf("finished loading cue %s\n", cue_file_name);\r
360 printf("bin file: %s (%p)\n", bin_file_name, cd_bin.bin_file);\r
361 printf("first track: %d, last track: %d\n", cd_bin.first_track,\r
362 cd_bin.last_track);\r
363\r
364 for(i = cd_bin.first_track; i <= cd_bin.last_track; i++)\r
365 {\r
366 printf("track %d (%p):\n", i, cd_bin.logical_tracks[i]);\r
367 if(cd_bin.logical_tracks[i] == NULL)\r
368 {\r
369 printf(" (invalid)\n");\r
370 }\r
371 else\r
372 {\r
373 printf(" physical offset 0x%x\n",\r
374 cd_bin.logical_tracks[i]->physical_offset);\r
375 printf(" sector offset 0x%x\n",\r
376 cd_bin.logical_tracks[i]->sector_offset);\r
377 printf(" sector size %d\n",\r
378 cd_bin.logical_tracks[i]->sector_size);\r
379 }\r
380 }\r
381\r
382 cd_bin.last_seek_track = 0;\r
383\r
384 fclose(cue_file);\r
385 return 0;\r
386 }\r
387\r
f8a64101 388 return -1;\r
389invalid:\r
390 printf("error: invalid/unsupported .cue file\n");\r
c0fcf293 391 return -1;\r
392}\r
393\r
394#define address8(base, offset) \\r
395 *((u8 *)((u8 *)base + (offset))) \\r
396\r
397#define address16(base, offset) \\r
398 *((u16 *)((u8 *)base + (offset))) \\r
399\r
400#define address32(base, offset) \\r
401 *((u32 *)((u8 *)base + (offset))) \\r
402\r
403// This will only work on little endian platforms for now.\r
404\r
405s32 convert_bin_to_wav(FILE *bin_file, char *output_dir, char *wav_file_name,\r
406 u32 sector_count)\r
407{\r
408 FILE *wav_file;\r
409 u8 wav_header[36];\r
410 u8 *riff_header = wav_header + 0;\r
411 u8 *fmt_header = wav_header + 0x0C;\r
412 u8 sector_buffer[2352];\r
413 u32 byte_length = sector_count * 2352;\r
414 u32 i;\r
415\r
416 chdir(output_dir);\r
417 wav_file = fopen(wav_file_name, "wb");\r
418\r
419 printf("writing wav %s, %x sectors\n", wav_file_name, sector_count);\r
420\r
421 // RIFF type chunk\r
422 memcpy(riff_header + 0x00, "RIFF", 4);\r
423 address32(riff_header, 0x04) = byte_length + 44 - 8;\r
424 memcpy(riff_header + 0x08, "WAVE", 4);\r
425\r
426 // WAVE file chunk: format\r
427 memcpy(fmt_header + 0x00, "fmt ", 4);\r
428 // Chunk data size\r
429 address32(fmt_header, 0x04) = 16;\r
430 // Compression code: PCM\r
431 address16(fmt_header, 0x08) = 1;\r
432 // Number of channels: Stereo\r
433 address16(fmt_header, 0x0a) = 2;\r
434 // Sample rate: 44100Hz\r
435 address32(fmt_header, 0x0c) = 44100;\r
436 // Average bytes per second: sample rate * 4\r
437 address32(fmt_header, 0x10) = 44100 * 4;\r
438 // Block align (bytes per sample)\r
439 address16(fmt_header, 0x14) = 4;\r
440 // Bit depth\r
441 address16(fmt_header, 0x16) = 16;\r
442\r
443 // Write out header\r
444 fwrite(wav_header, 36, 1, wav_file);\r
445\r
446 // DATA chunk\r
447 fprintf(wav_file, "data");\r
448 // length\r
449 fwrite(&byte_length, 4, 1, wav_file);\r
450\r
451 // Write out sectors\r
452 for(i = 0; i < sector_count; i++)\r
453 {\r
454 printf("\b\b\b%3i", i*100 / sector_count);\r
455 fflush(stdout);\r
456 fread(sector_buffer, 2352, 1, bin_file);\r
457 fwrite(sector_buffer, 2352, 1, wav_file);\r
458 }\r
459 printf("\b\b\b100\n");\r
460\r
461 fclose(wav_file);\r
462 chdir("..");\r
463 return 0;\r
464}\r
465\r
466void convert_wav_to_ogg(char *wav_file_name, char *output_dir,\r
467 char *ogg_file_name)\r
468{\r
469 char cmd_string[(MAX_PATH * 2) + 16];\r
470\r
471 chdir(output_dir);\r
472 sprintf(cmd_string, "oggenc %s", wav_file_name);\r
473 system(cmd_string);\r
474\r
475 unlink(wav_file_name);\r
476 chdir("..");\r
477}\r
478\r
479void convert_wav_to_mp3(char *wav_file_name, char *output_dir,\r
480 char *mp3_file_name)\r
481{\r
482 char cmd_string[(MAX_PATH * 2) + 16];\r
483\r
484 chdir(output_dir);\r
485 sprintf(cmd_string, LAME_BINARY " " LAME_OPTIONS " -b %i \"%s\" \"%s\"",\r
486 opt_mp3_bitrate, wav_file_name, mp3_file_name);\r
487 if (system(cmd_string) != 0)\r
488 {\r
489 printf("failed to encode mp3\n");\r
490 myexit(1);\r
491 }\r
492\r
493 unlink(wav_file_name);\r
494 chdir("..");\r
495}\r
496\r
497s32 convert_bin_to_iso(FILE *bin_file, char *output_dir, char *iso_file_name,\r
498 u32 sector_count)\r
499{\r
500 FILE *iso_file;\r
501 u8 sector_buffer[2352];\r
502 u32 i;\r
503\r
504 chdir(output_dir);\r
505 iso_file = fopen(iso_file_name, "wb");\r
506 if (iso_file == NULL)\r
507 {\r
508 printf("failed to open: %s\n", iso_file_name);\r
509 myexit(1);\r
510 }\r
511 printf("writing iso %s, %x sectors\n", iso_file_name, sector_count);\r
512\r
513 for(i = 0; i < sector_count; i++)\r
514 {\r
515 printf("\b\b\b%3i", i*100 / sector_count);\r
516 fflush(stdout);\r
517 fread(sector_buffer, 2352, 1, bin_file);\r
518 fwrite(sector_buffer + 16, 2048, 1, iso_file);\r
519 }\r
520 printf("\b\b\b100\n");\r
521\r
522 fclose(iso_file);\r
523 chdir("..");\r
524 return 0;\r
525}\r
526\r
527void convert_iso_to_cso(char *output_dir, char *iso_file_name, char *cso_file_name)\r
528{\r
529 char cmd_string[(MAX_PATH * 2) + 16];\r
530\r
531 chdir(output_dir);\r
532 sprintf(cmd_string, CISO_BINARY " 9 \"%s\" \"%s\"", iso_file_name, cso_file_name);\r
533 if (system(cmd_string) != 0)\r
534 {\r
535 printf("failed to convert iso to cso\n");\r
536 myexit(1);\r
537 }\r
538\r
539 unlink(iso_file_name);\r
540 chdir("..");\r
541}\r
542\r
543\r
544#define sector_offset_to_msf(offset, minutes, seconds, frames) \\r
545{ \\r
546 u32 _offset = offset; \\r
547 minutes = (_offset / 75) / 60; \\r
548 seconds = (_offset / 75) % 60; \\r
549 frames = _offset % 75; \\r
550} \\r
551\r
552\r
553s32 convert_bin_cue(char *output_name_base)\r
554{\r
555 char output_file_name[MAX_PATH];\r
556 FILE *output_cue_file;\r
557 FILE *bin_file = cd_bin.bin_file;\r
558 cd_track_struct *current_track;\r
559 u32 m, s, f;\r
560 u32 current_pregap = 0;\r
561 u32 last_pregap = 0;\r
562 u32 i;\r
563 struct stat sb;\r
564\r
565 if(stat(output_name_base, &sb))\r
566 mkdir(output_name_base);\r
567\r
568 sprintf(output_file_name, "%s.cue", output_name_base);\r
569 chdir(output_name_base);\r
570 output_cue_file = fopen(output_file_name, "wb");\r
571 chdir("..");\r
572\r
573 // Every track gets its own file. It's either going to be of type ISO\r
574 // or of type WAV.\r
575\r
576 for(i = 0; i < 100; i++)\r
577 {\r
578 current_track = cd_bin.logical_tracks[i];\r
579 if(current_track != NULL)\r
580 {\r
581 switch(current_track->format_type)\r
582 {\r
583 char output_name_tmp[MAX_PATH];\r
584\r
585 // Audio\r
586 case 0:\r
587 {\r
588 sprintf(output_file_name, "%s_%02d.mp3", output_name_base, i);\r
589 sprintf(output_name_tmp, "%s_%02d.wav", output_name_base, i);\r
590\r
591 fprintf(output_cue_file, "FILE \"%s\" %s\n",\r
592 opt_use_mp3 ? output_file_name : output_name_tmp,\r
593 opt_use_mp3 ? "MP3" : "WAVE");\r
594 fprintf(output_cue_file, " TRACK %02d AUDIO\n", i);\r
595 current_pregap = current_track->pregap_offset - last_pregap;\r
596 last_pregap = current_track->pregap_offset;\r
597 if(current_pregap > 0)\r
598 {\r
599 sector_offset_to_msf(current_pregap, m, s, f);\r
600 fprintf(output_cue_file, " PREGAP %02d:%02d:%02d\n", m, s, f);\r
601 }\r
602 fprintf(output_cue_file, " INDEX 01 00:00:00\n");\r
603 sector_offset_to_msf(current_track->sector_count, m, s, f);\r
604 fprintf(output_cue_file, " REM LENGTH %02d:%02d:%02d\n", m, s, f);\r
605\r
606 fseek(bin_file, current_track->physical_offset, SEEK_SET);\r
607 convert_bin_to_wav(bin_file, output_name_base, output_name_tmp,\r
608 current_track->sector_count);\r
609 if(opt_use_mp3)\r
610 {\r
611 convert_wav_to_mp3(output_name_tmp, output_name_base,\r
612 output_file_name);\r
613 }\r
614 break;\r
615 }\r
616\r
617 // Data\r
618 default:\r
619 sprintf(output_file_name, "%s_%02d.cso", output_name_base, i);\r
620 sprintf(output_name_tmp, "%s_%02d.iso", output_name_base, i);\r
621 fprintf(output_cue_file, "FILE \"%s\" BINARY\n",\r
622 opt_use_cso ? output_file_name : output_name_tmp);\r
623 fprintf(output_cue_file, " TRACK %02d MODE1/2048\n", i);\r
624 current_pregap = current_track->pregap_offset - last_pregap;\r
625 last_pregap = current_track->pregap_offset;\r
626 if(current_pregap > 0)\r
627 {\r
628 sector_offset_to_msf(current_pregap, m, s, f);\r
629 fprintf(output_cue_file, " PREGAP %02d:%02d:%02d\n", m, s, f);\r
630 }\r
631 fprintf(output_cue_file, " INDEX 01 00:00:00\n");\r
632\r
633 fseek(bin_file, current_track->physical_offset, SEEK_SET);\r
634 convert_bin_to_iso(bin_file, output_name_base, output_name_tmp,\r
635 current_track->sector_count);\r
636 if(opt_use_cso)\r
637 {\r
638 convert_iso_to_cso(output_name_base, output_name_tmp, output_file_name);\r
639 }\r
640 break;\r
641 }\r
642 }\r
643 }\r
644\r
645 fclose(output_cue_file);\r
646\r
647 return 0;\r
648}\r
649\r
650#ifdef _WIN32\r
651static void update_path(void)\r
652{\r
f8a64101 653 char buff1[MAX_PATH*4], *buff2;\r
c0fcf293 654 char *path;\r
f8a64101 655 int size, i;\r
c0fcf293 656\r
657 path = getenv("PATH");\r
658 GetModuleFileNameA(NULL, buff1, sizeof(buff1));\r
659 for (i = strlen(buff1)-1; i > 0; i--)\r
660 if (buff1[i] == '\\') break;\r
661 buff1[i] = 0;\r
662\r
f8a64101 663 size = strlen(path) + strlen(buff1) + 3;\r
664 buff2 = malloc(size);\r
665 if (buff2 == NULL) return;\r
666\r
667 snprintf(buff2, size, "%s;%s", path, buff1);\r
c0fcf293 668 SetEnvironmentVariableA("PATH", buff2);\r
f8a64101 669 free(buff2);\r
c0fcf293 670}\r
671#endif\r
672\r
673int main(int argc, char *argv[])\r
674{\r
675 char out_buff[MAX_PATH], *cue_file, *out_base;\r
676 int a;\r
677\r
678 if(argc < 2)\r
679 {\r
680 printf("bin/cue to cso/mp3 converter\n");\r
681 printf("usage: %s [options] <input cue> [output base]\n", argv[0]);\r
682 printf("options:\n"\r
683 " -m output mp3 files for audio (default) (lame required)\n"\r
684 " -b <rate> mp3 bitrate to use (default is 128)\n"\r
685 " -w output wav files for audio\n"\r
686 " -c output cso as data track (default) (ciso required)\n"\r
687 " -i output iso as data track\n");\r
688 return 0;\r
689 }\r
690\r
691 for (a = 1; a < argc - 1; a++)\r
692 {\r
693 if (strcmp(argv[a], "-m") == 0)\r
694 opt_use_mp3 = 1;\r
695 else if (strcmp(argv[a], "-w") == 0)\r
696 opt_use_mp3 = 0;\r
697 else if (strcmp(argv[a], "-c") == 0)\r
698 opt_use_cso = 1;\r
699 else if (strcmp(argv[a], "-i") == 0)\r
700 opt_use_cso = 0;\r
701 else if (strcmp(argv[a], "-b") == 0)\r
702 {\r
703 opt_mp3_bitrate = atoi(argv[++a]);\r
704 }\r
705 else\r
706 break;\r
707 }\r
708 cue_file = argv[a];\r
709 out_base = argv[a+1];\r
710\r
711 /* some sanity checks */\r
712 if(strlen(cue_file) < 4 || strcasecmp(cue_file + strlen(cue_file) - 4, ".cue") != 0)\r
713 {\r
714 printf("error: not a cue file specified?\n");\r
715 myexit(1);\r
716 }\r
717\r
718#ifdef _WIN32\r
719 update_path();\r
720#endif\r
721\r
722 if(opt_use_mp3 && system(LAME_BINARY " --help " NULL_REDIR) != 0)\r
723 {\r
724 printf("LAME seems to be missing.\n"\r
725#ifdef _WIN32\r
726 "Download from http://lame.sourceforge.net/links.php#Binaries and extract\n"\r
727 "lame.exe to the same directory as %s\n", argv[0]\r
728#else\r
729 "Install lame using your packet manager, obtain binaries or build from\n"\r
730 "sources at http://lame.sourceforge.net/\n"\r
731#endif\r
732 );\r
733 myexit(1);\r
734 }\r
735\r
736 if(opt_use_cso && system(CISO_BINARY " " NULL_REDIR) != 0)\r
737 {\r
738 printf("CISO seems to be missing.\n"\r
739#ifdef _WIN32\r
740 "Download ciso.exe and extract to the same directory as %s\n"\r
741 "You can take ciso.exe from yacc at http://yacc.pspgen.com/\n", argv[0]\r
742#else\r
743 "Install ciso using your packet manager, obtain binaries or build from\n"\r
744 "sources at http://ciso.tenshu.fr/\n"\r
745#endif\r
746 );\r
747 myexit(1);\r
748 }\r
749\r
750 if(load_bin_cue(cue_file) == 0)\r
751 {\r
752 if(out_base == NULL)\r
753 {\r
754 char *p;\r
755 strncpy(out_buff, cue_file, sizeof(out_buff));\r
756 out_buff[sizeof(out_buff)-1] = 0;\r
757 p = strrchr(out_buff, DIR_SEPARATOR_CHAR);\r
758 if (p != NULL)\r
759 {\r
760 *p++ = 0;\r
761 chdir(out_buff);\r
762 memmove(out_buff, p, strlen(p)+1);\r
763 }\r
764 out_buff[strlen(out_buff)-4] = 0;\r
765 out_base = out_buff;\r
766 }\r
767 if(convert_bin_cue(out_base) != 0)\r
768 myexit(1);\r
769 }\r
770 else\r
771 {\r
772 printf("error: could not load cue file %s\n", cue_file);\r
773 myexit(1);\r
774 }\r
775\r
776 return 0;\r
777}\r
778\r