trunk/src/lib/util/chdcd.c
| r20099 | r20100 | |
| 154 | 154 | filerr = osd_open(filename, OPEN_FLAG_READ, &file, &fsize); |
| 155 | 155 | if (filerr != FILERR_NONE) |
| 156 | 156 | { |
| 157 | | osd_close(file); |
| 157 | printf("ERROR: could not open (%s)\n", filename); |
| 158 | 158 | return 0; |
| 159 | 159 | } |
| 160 | 160 | |
| r20099 | r20100 | |
| 162 | 162 | osd_read(file, buf, 0, 4, &actual); |
| 163 | 163 | offset += actual; |
| 164 | 164 | if (offset < 4) |
| 165 | { |
| 166 | osd_close(file); |
| 167 | printf("ERROR: unexpected offset %d (%s)\n", actual, filename); |
| 165 | 168 | return 0; |
| 169 | } |
| 166 | 170 | if (memcmp(&buf[0], "RIFF", 4) != 0) |
| 171 | { |
| 172 | osd_close(file); |
| 173 | printf("ERROR: could not find RIFF header (%s)\n", filename); |
| 167 | 174 | return 0; |
| 175 | } |
| 168 | 176 | |
| 169 | 177 | /* get the total size */ |
| 170 | 178 | osd_read(file, &filesize, offset, 4, &actual); |
| 171 | 179 | offset += actual; |
| 172 | 180 | if (offset < 8) |
| 181 | { |
| 182 | osd_close(file); |
| 183 | printf("ERROR: unexpected offset %d (%s)\n", actual, filename); |
| 173 | 184 | return 0; |
| 185 | } |
| 174 | 186 | filesize = LITTLE_ENDIANIZE_INT32(filesize); |
| 175 | 187 | |
| 176 | 188 | /* read the RIFF file type and make sure it's a WAVE file */ |
| 177 | 189 | osd_read(file, buf, offset, 4, &actual); |
| 178 | 190 | offset += actual; |
| 179 | 191 | if (offset < 12) |
| 192 | { |
| 193 | osd_close(file); |
| 194 | printf("ERROR: unexpected offset %d (%s)\n", actual, filename); |
| 180 | 195 | return 0; |
| 196 | } |
| 181 | 197 | if (memcmp(&buf[0], "WAVE", 4) != 0) |
| 198 | { |
| 199 | osd_close(file); |
| 200 | printf("ERROR:could not find WAVE header (%s)\n", filename); |
| 182 | 201 | return 0; |
| 202 | } |
| 183 | 203 | |
| 184 | 204 | /* seek until we find a format tag */ |
| 185 | 205 | while (1) |
| r20099 | r20100 | |
| 195 | 215 | /* seek to the next block */ |
| 196 | 216 | offset += length; |
| 197 | 217 | if (offset >= filesize) |
| 218 | { |
| 219 | osd_close(file); |
| 220 | printf("ERROR:could not find fmt tag (%s)\n", filename); |
| 198 | 221 | return 0; |
| 222 | } |
| 199 | 223 | } |
| 200 | 224 | |
| 201 | 225 | /* read the format -- make sure it is PCM */ |
| r20099 | r20100 | |
| 203 | 227 | offset += actual; |
| 204 | 228 | temp16 = LITTLE_ENDIANIZE_INT16(temp16); |
| 205 | 229 | if (temp16 != 1) |
| 230 | { |
| 231 | osd_close(file); |
| 232 | printf("ERROR: unsupported format %d - only PCM is supported (%s)\n", temp16, filename); |
| 206 | 233 | return 0; |
| 234 | } |
| 207 | 235 | |
| 208 | 236 | /* number of channels -- only mono is supported */ |
| 209 | 237 | osd_read(file, &temp16, offset, 2, &actual); |
| 210 | 238 | offset += actual; |
| 211 | 239 | temp16 = LITTLE_ENDIANIZE_INT16(temp16); |
| 212 | 240 | if (temp16 != 2) |
| 241 | { |
| 242 | osd_close(file); |
| 243 | printf("ERROR: unsupported number of channels %d - only mono is supported (%s)\n", temp16, filename); |
| 213 | 244 | return 0; |
| 245 | } |
| 214 | 246 | |
| 215 | 247 | /* sample rate */ |
| 216 | 248 | osd_read(file, &rate, offset, 4, &actual); |
| 217 | 249 | offset += actual; |
| 218 | 250 | rate = LITTLE_ENDIANIZE_INT32(rate); |
| 219 | 251 | if (rate != 44100) |
| 252 | { |
| 253 | osd_close(file); |
| 254 | printf("ERROR: unsupported samplerate %d - only 44100 is supported (%s)\n", rate, filename); |
| 220 | 255 | return 0; |
| 256 | } |
| 221 | 257 | |
| 222 | 258 | /* bytes/second and block alignment are ignored */ |
| 223 | 259 | osd_read(file, buf, offset, 6, &actual); |
| r20099 | r20100 | |
| 227 | 263 | osd_read(file, &bits, offset, 2, &actual); |
| 228 | 264 | offset += actual; |
| 229 | 265 | if (bits != 16) |
| 266 | { |
| 267 | osd_close(file); |
| 268 | printf("ERROR: unsupported bits/sample %d - only 16 is supported (%s)\n", bits, filename); |
| 230 | 269 | return 0; |
| 270 | } |
| 231 | 271 | |
| 232 | 272 | /* seek past any extra data */ |
| 233 | 273 | offset += length - 16; |
| r20099 | r20100 | |
| 246 | 286 | /* seek to the next block */ |
| 247 | 287 | offset += length; |
| 248 | 288 | if (offset >= filesize) |
| 289 | { |
| 290 | osd_close(file); |
| 291 | printf("ERROR: could not find data tag (%s)\n", filename); |
| 249 | 292 | return 0; |
| 293 | } |
| 250 | 294 | } |
| 251 | 295 | |
| 296 | osd_close(file); |
| 297 | |
| 252 | 298 | /* if there was a 0 length data block, we're done */ |
| 253 | 299 | if (length == 0) |
| 254 | 300 | return 0; |
| 255 | 301 | |
| 256 | | osd_close(file); |
| 257 | | |
| 258 | 302 | *dataoffs = offset; |
| 259 | 303 | |
| 260 | 304 | return length; |
| r20099 | r20100 | |
| 333 | 377 | { |
| 334 | 378 | printf("ERROR: Not a Nero 5.5 or later image!\n"); |
| 335 | 379 | fclose(infile); |
| 336 | | return CHDERR_FILE_NOT_FOUND; |
| 380 | return CHDERR_UNSUPPORTED_VERSION; |
| 337 | 381 | } |
| 338 | 382 | |
| 339 | 383 | chain_offs = buffer[11] | (buffer[10]<<8) | (buffer[9]<<16) | (buffer[8]<<24); |
| r20099 | r20100 | |
| 342 | 386 | { |
| 343 | 387 | printf("ERROR: File size is > 4GB, this version of CHDMAN cannot handle it."); |
| 344 | 388 | fclose(infile); |
| 345 | | return CHDERR_FILE_NOT_FOUND; |
| 389 | return CHDERR_UNSUPPORTED_FORMAT; |
| 346 | 390 | } |
| 347 | 391 | |
| 348 | 392 | // printf("NER5 detected, chain offset: %x\n", chain_offs); |
| r20099 | r20100 | |
| 403 | 447 | case 0x0300: // Mode 2 Form 1 |
| 404 | 448 | printf("ERROR: Mode 2 Form 1 tracks not supported\n"); |
| 405 | 449 | fclose(infile); |
| 406 | | return CHDERR_NOT_SUPPORTED; |
| 450 | return CHDERR_UNSUPPORTED_FORMAT; |
| 407 | 451 | |
| 408 | 452 | case 0x0500: // raw data |
| 409 | 453 | printf("ERROR: Raw data tracks not supported\n"); |
| 410 | 454 | fclose(infile); |
| 411 | | return CHDERR_NOT_SUPPORTED; |
| 455 | return CHDERR_UNSUPPORTED_FORMAT; |
| 412 | 456 | |
| 413 | 457 | case 0x0600: // 2352 byte mode 2 raw |
| 414 | 458 | outtoc.tracks[track-1].trktype = CD_TRACK_MODE2_RAW; |
| r20099 | r20100 | |
| 423 | 467 | case 0x0f00: // raw data with sub-channel |
| 424 | 468 | printf("ERROR: Raw data tracks with sub-channel not supported\n"); |
| 425 | 469 | fclose(infile); |
| 426 | | return CHDERR_NOT_SUPPORTED; |
| 470 | return CHDERR_UNSUPPORTED_FORMAT; |
| 427 | 471 | |
| 428 | 472 | case 0x1000: // audio with sub-channel |
| 429 | 473 | printf("ERROR: Audio tracks with sub-channel not supported\n"); |
| 430 | 474 | fclose(infile); |
| 431 | | return CHDERR_NOT_SUPPORTED; |
| 475 | return CHDERR_UNSUPPORTED_FORMAT; |
| 432 | 476 | |
| 433 | 477 | case 0x1100: // raw Mode 2 Form 1 with sub-channel |
| 434 | 478 | printf("ERROR: Raw Mode 2 Form 1 tracks with sub-channel not supported\n"); |
| 435 | 479 | fclose(infile); |
| 436 | | return CHDERR_NOT_SUPPORTED; |
| 480 | return CHDERR_UNSUPPORTED_FORMAT; |
| 437 | 481 | |
| 438 | 482 | default: |
| 439 | 483 | printf("ERROR: Unknown track type %x, contact MAMEDEV!\n", mode); |
| 440 | 484 | fclose(infile); |
| 441 | | return CHDERR_NOT_SUPPORTED; |
| 485 | return CHDERR_UNSUPPORTED_FORMAT; |
| 442 | 486 | } |
| 443 | 487 | |
| 444 | 488 | outtoc.tracks[track-1].datasize = size; |
| r20099 | r20100 | |
| 520 | 564 | outinfo.track[0].swap = false; |
| 521 | 565 | } else { |
| 522 | 566 | printf("ERROR: Unrecognized track type\n"); |
| 523 | | return CHDERR_FILE_NOT_FOUND; |
| 567 | return CHDERR_UNSUPPORTED_FORMAT; |
| 524 | 568 | } |
| 525 | 569 | |
| 526 | 570 | outtoc.tracks[0].subtype = CD_SUB_NONE; |
| r20099 | r20100 | |
| 720 | 764 | wavlen = parse_wav_sample(lastfname, &wavoffs); |
| 721 | 765 | if (!wavlen) |
| 722 | 766 | { |
| 723 | | file_error err; |
| 724 | | core_file *fhand; |
| 725 | | |
| 726 | | err = core_fopen(lastfname, OPEN_FLAG_READ, &fhand); |
| 727 | | if (err != FILERR_NONE) printf("holy moley!\n"); |
| 728 | | else core_fclose(fhand); |
| 729 | | |
| 730 | 767 | printf("ERROR: couldn't read [%s] or not a valid .WAV\n", lastfname.cstr()); |
| 731 | | return CHDERR_FILE_NOT_FOUND; |
| 768 | return CHDERR_INVALID_DATA; |
| 732 | 769 | } |
| 733 | 770 | } |
| 734 | 771 | else |
| 735 | 772 | { |
| 736 | 773 | printf("ERROR: Unhandled track type %s\n", token); |
| 737 | | return CHDERR_FILE_NOT_FOUND; |
| 774 | return CHDERR_UNSUPPORTED_FORMAT; |
| 738 | 775 | } |
| 739 | 776 | } |
| 740 | 777 | else if (!strcmp(token, "TRACK")) |
| r20099 | r20100 | |
| 774 | 811 | if (outtoc.tracks[trknum].datasize == 0) |
| 775 | 812 | { |
| 776 | 813 | printf("ERROR: Unknown track type [%s]. Contact MAMEDEV.\n", token); |
| 777 | | return CHDERR_FILE_NOT_FOUND; |
| 814 | return CHDERR_UNSUPPORTED_FORMAT; |
| 778 | 815 | } |
| 779 | 816 | |
| 780 | 817 | /* next (optional) token on the line is the subcode type */ |
| r20099 | r20100 | |
| 897 | 934 | if (!outtoc.tracks[trknum].frames) |
| 898 | 935 | { |
| 899 | 936 | printf("ERROR: unable to determine size of track %d, missing INDEX 01 markers?\n", trknum+1); |
| 900 | | return CHDERR_FILE_NOT_FOUND; |
| 937 | return CHDERR_INVALID_DATA; |
| 901 | 938 | } |
| 902 | 939 | } |
| 903 | 940 | else /* data files are different */ |
| r20099 | r20100 | |
| 1079 | 1116 | if (outtoc.tracks[trknum].datasize == 0) |
| 1080 | 1117 | { |
| 1081 | 1118 | printf("ERROR: Unknown track type [%s]. Contact MAMEDEV.\n", token); |
| 1082 | | return CHDERR_FILE_NOT_FOUND; |
| 1119 | return CHDERR_UNSUPPORTED_FORMAT; |
| 1083 | 1120 | } |
| 1084 | 1121 | |
| 1085 | 1122 | /* next (optional) token on the line is the subcode type */ |