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