int main(int argc, char **argv) { int flags = DCADEC_FLAG_STRICT; bool parse_only = false; bool no_progress = false; bool quiet = false; bool no_strip = false; int opt; while ((opt = getopt(argc, argv, "26bcfhlnPqSsx")) != -1) { switch (opt) { case '2': flags |= DCADEC_FLAG_KEEP_DMIX_2CH; break; case '6': flags |= DCADEC_FLAG_KEEP_DMIX_6CH; break; case 'b': flags |= DCADEC_FLAG_CORE_BIT_EXACT; break; case 'c': flags |= DCADEC_FLAG_CORE_ONLY; break; case 'f': flags |= DCADEC_FLAG_CORE_LFE_FIR; break; case 'h': print_help(argv[0]); return 0; case 'l': flags &= ~DCADEC_FLAG_STRICT; break; case 'n': parse_only = true; break; case 'P': no_progress = true; break; case 'q': quiet = true; break; case 'S': no_strip = true; break; case 's': flags |= DCADEC_FLAG_CORE_SOURCE_PCM_RES; break; case 'x': flags |= DCADEC_FLAG_CORE_SYNTH_X96; break; default: print_help(argv[0]); return 1; } } no_progress |= quiet; if (optind >= argc) { print_help(argv[0]); return 1; } char *fn = argv[optind]; struct dcadec_stream *stream = dcadec_stream_open(strcmp(fn, "-") ? fn : NULL); if (!stream) { fprintf(stderr, "Couldn't open input file\n"); return 1; } uint8_t *packet; size_t size; int ret; if ((ret = dcadec_stream_read(stream, &packet, &size)) < 0) { fprintf(stderr, "Error reading packet: %s\n", dcadec_strerror(ret)); dcadec_stream_close(stream); return 1; } if (ret == 0) { fprintf(stderr, "This doesn't look like a valid DTS bit stream\n"); dcadec_stream_close(stream); return 1; } struct dcadec_context *context = dcadec_context_create(flags); if (!context) { fprintf(stderr, "Couldn't create decoder context\n"); dcadec_stream_close(stream); return 1; } if ((ret = dcadec_context_parse(context, packet, size)) < 0) { fprintf(stderr, "Error parsing packet: %s\n", dcadec_strerror(ret)); dcadec_context_destroy(context); dcadec_stream_close(stream); return 1; } if (!quiet) print_info(context); struct dcadec_waveout *waveout = NULL; if (!parse_only) { if (optind + 1 >= argc) { dcadec_context_destroy(context); dcadec_stream_close(stream); return 0; } fn = argv[optind + 1]; waveout = dcadec_waveout_open(strcmp(fn, "-") ? fn : NULL); if (!waveout) { fprintf(stderr, "Couldn't open output file\n"); dcadec_context_destroy(context); dcadec_stream_close(stream); return 1; } } int last_progress = -1; #ifdef _WIN32 SetConsoleCtrlHandler(&console_ctrl_handler, TRUE); #else signal(SIGINT, &signal_handler); #endif uint32_t ndelayframes = 0; uint64_t npcmsamples = UINT64_MAX; if (!parse_only && !no_strip) { struct dcadec_stream_info *info = dcadec_stream_get_info(stream); if (info) { if (info->nframesamples) ndelayframes = info->ndelaysamples / info->nframesamples; if (info->npcmsamples) npcmsamples = info->npcmsamples; dcadec_stream_free_info(info); } } if (!quiet) { if (waveout) { if (flags & DCADEC_FLAG_CORE_ONLY) fprintf(stderr, "Decoding (core only)...\n"); else fprintf(stderr, "Decoding...\n"); } else { if (flags & DCADEC_FLAG_CORE_ONLY) fprintf(stderr, "Parsing (core only)...\n"); else fprintf(stderr, "Parsing...\n"); } } while (!interrupted) { if (waveout) { int **samples, nsamples, channel_mask, sample_rate, bits_per_sample; if ((ret = dcadec_context_filter(context, &samples, &nsamples, &channel_mask, &sample_rate, &bits_per_sample, NULL)) < 0) { fprintf(stderr, "Error filtering frame: %s\n", dcadec_strerror(ret)); if (flags & DCADEC_FLAG_STRICT) break; else goto next_packet; } if (ndelayframes) { ndelayframes--; goto next_packet; } if ((uint64_t)nsamples > npcmsamples) nsamples = npcmsamples; if ((ret = dcadec_waveout_write(waveout, samples, nsamples, channel_mask, sample_rate, bits_per_sample)) < 0) { fprintf(stderr, "Error writing WAV file: %s\n", dcadec_strerror(ret)); if ((flags & DCADEC_FLAG_STRICT) || ret == -DCADEC_EIO) break; } npcmsamples -= nsamples; } next_packet: if ((ret = dcadec_stream_read(stream, &packet, &size)) < 0) { fprintf(stderr, "Error reading packet: %s\n", dcadec_strerror(ret)); break; } if (!no_progress) { int progress = dcadec_stream_progress(stream); if (progress != last_progress) { fprintf(stderr, "Progress: %d%%\r", progress); last_progress = progress; } } if (ret == 0) break; if ((ret = dcadec_context_parse(context, packet, size)) < 0) { fprintf(stderr, "Error parsing packet: %s\n", dcadec_strerror(ret)); if (flags & DCADEC_FLAG_STRICT) break; else goto next_packet; } } if (!quiet) { if (last_progress != -1) fprintf(stderr, "\n"); if (interrupted) fprintf(stderr, "Interrupted.\n"); else if (ret == 0) fprintf(stderr, "Completed.\n"); } dcadec_waveout_close(waveout); dcadec_context_destroy(context); dcadec_stream_close(stream); return !!ret; }
int main(int argc, char **argv) { if (argc < 3) { fprintf(stderr, "Usage: %s <input.dts> <output.dts> [first] [last]\n", argv[0]); return 1; } unsigned long first_packet = 0; unsigned long last_packet = ULONG_MAX; if (argc > 3) first_packet = strtoul(argv[3], NULL, 0); if (argc > 4) last_packet = strtoul(argv[4], NULL, 0); if (last_packet < first_packet) { fprintf(stderr, "Invalid packet range\n"); return 1; } struct dcadec_stream *stream = dcadec_stream_open(argv[1], 0); if (!stream) { fprintf(stderr, "Couldn't open input file\n"); return 1; } FILE *fp = fopen(argv[2], "wb"); if (!fp) { fprintf(stderr, "Couldn't open output file\n"); dcadec_stream_close(stream); return 1; } unsigned long packet_in = 0; unsigned long packet_out = 0; int ret; while (true) { uint8_t *packet; size_t size; ret = dcadec_stream_read(stream, &packet, &size); if (ret < 0) { fprintf(stderr, "Error %d reading packet\n", ret); break; } if (ret == 0) break; if (packet_in >= first_packet) { if (fwrite(packet, size, 1, fp) != 1) { fprintf(stderr, "Error %d writing packet\n", errno); ret = -1; break; } packet_out++; } if (++packet_in > last_packet) break; } if (packet_out) { fprintf(stderr, "Wrote %lu packets\n", packet_out); } else { fprintf(stderr, "Didn't write a single packet!\n"); ret = -1; } fclose(fp); dcadec_stream_close(stream); return !!ret; }