📄 decode.c
字号:
flac__analyze_init(aopts); return true;}void DecoderSession_destroy(DecoderSession *d, FLAC__bool error_occurred){ if(0 != d->fout && d->fout != stdout) { fclose(d->fout); if(error_occurred) unlink(d->outfilename); }}FLAC__bool DecoderSession_init_decoder(DecoderSession *decoder_session, decode_options_t decode_options, const char *infilename){ FLAC__uint32 test = 1; is_big_endian_host_ = (*((FLAC__byte*)(&test)))? false : true;#ifdef FLAC__HAS_OGG if(decoder_session->is_ogg) { decoder_session->decoder.ogg.file = OggFLAC__file_decoder_new(); if(0 == decoder_session->decoder.ogg.file) { flac__utils_printf(stderr, 1, "%s: ERROR creating the decoder instance\n", decoder_session->inbasefilename); return false; } OggFLAC__file_decoder_set_md5_checking(decoder_session->decoder.ogg.file, true); OggFLAC__file_decoder_set_filename(decoder_session->decoder.ogg.file, infilename); if(!decode_options.use_first_serial_number) OggFLAC__file_decoder_set_serial_number(decoder_session->decoder.ogg.file, decode_options.serial_number); if (0 != decoder_session->cue_specification) OggFLAC__file_decoder_set_metadata_respond(decoder_session->decoder.ogg.file, FLAC__METADATA_TYPE_CUESHEET); if (decoder_session->replaygain.spec.apply) OggFLAC__file_decoder_set_metadata_respond(decoder_session->decoder.ogg.file, FLAC__METADATA_TYPE_VORBIS_COMMENT); /* * The three ugly casts here are to 'downcast' the 'void *' argument of * the callback down to 'OggFLAC__FileDecoder *'. In C++ this would be * unnecessary but here the cast makes the C compiler happy. */ OggFLAC__file_decoder_set_write_callback(decoder_session->decoder.ogg.file, (FLAC__StreamDecoderWriteStatus (*)(const OggFLAC__FileDecoder *, const FLAC__Frame *, const FLAC__int32 * const [], void *))write_callback); OggFLAC__file_decoder_set_metadata_callback(decoder_session->decoder.ogg.file, (void (*)(const OggFLAC__FileDecoder *, const FLAC__StreamMetadata *, void *))metadata_callback); OggFLAC__file_decoder_set_error_callback(decoder_session->decoder.ogg.file, (void (*)(const OggFLAC__FileDecoder *, FLAC__StreamDecoderErrorStatus, void *))error_callback); OggFLAC__file_decoder_set_client_data(decoder_session->decoder.ogg.file, decoder_session); if(OggFLAC__file_decoder_init(decoder_session->decoder.ogg.file) != OggFLAC__FILE_DECODER_OK) { print_error_with_state(decoder_session, "ERROR initializing decoder"); return false; } } else#else (void)decode_options;#endif { decoder_session->decoder.flac.file = FLAC__file_decoder_new(); if(0 == decoder_session->decoder.flac.file) { flac__utils_printf(stderr, 1, "%s: ERROR creating the decoder instance\n", decoder_session->inbasefilename); return false; } FLAC__file_decoder_set_md5_checking(decoder_session->decoder.flac.file, true); FLAC__file_decoder_set_filename(decoder_session->decoder.flac.file, infilename); if (0 != decoder_session->cue_specification) FLAC__file_decoder_set_metadata_respond(decoder_session->decoder.flac.file, FLAC__METADATA_TYPE_CUESHEET); if (decoder_session->replaygain.spec.apply) FLAC__file_decoder_set_metadata_respond(decoder_session->decoder.flac.file, FLAC__METADATA_TYPE_VORBIS_COMMENT); /* * The three ugly casts here are to 'downcast' the 'void *' argument of * the callback down to 'FLAC__FileDecoder *'. */ FLAC__file_decoder_set_write_callback(decoder_session->decoder.flac.file, (FLAC__StreamDecoderWriteStatus (*)(const FLAC__FileDecoder *, const FLAC__Frame *, const FLAC__int32 * const [], void *))write_callback); FLAC__file_decoder_set_metadata_callback(decoder_session->decoder.flac.file, (void (*)(const FLAC__FileDecoder *, const FLAC__StreamMetadata *, void *))metadata_callback); FLAC__file_decoder_set_error_callback(decoder_session->decoder.flac.file, (void (*)(const FLAC__FileDecoder *, FLAC__StreamDecoderErrorStatus, void *))error_callback); FLAC__file_decoder_set_client_data(decoder_session->decoder.flac.file, decoder_session); if(FLAC__file_decoder_init(decoder_session->decoder.flac.file) != FLAC__FILE_DECODER_OK) { print_error_with_state(decoder_session, "ERROR initializing decoder"); return false; } } return true;}FLAC__bool DecoderSession_process(DecoderSession *d){#ifdef FLAC__HAS_OGG if(d->is_ogg) { if(!OggFLAC__file_decoder_process_until_end_of_metadata(d->decoder.ogg.file)) { flac__utils_printf(stderr, 2, "\n"); print_error_with_state(d, "ERROR while decoding metadata"); return false; } if(OggFLAC__file_decoder_get_state(d->decoder.ogg.file) != OggFLAC__FILE_DECODER_OK && OggFLAC__file_decoder_get_state(d->decoder.ogg.file) != OggFLAC__FILE_DECODER_END_OF_FILE) { flac__utils_printf(stderr, 2, "\n"); print_error_with_state(d, "ERROR during metadata decoding"); return false; } } else#endif { if(!FLAC__file_decoder_process_until_end_of_metadata(d->decoder.flac.file)) { flac__utils_printf(stderr, 2, "\n"); print_error_with_state(d, "ERROR while decoding metadata"); return false; } if(FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_OK && FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_END_OF_FILE) { flac__utils_printf(stderr, 2, "\n"); print_error_with_state(d, "ERROR during metadata decoding"); return false; } } if(d->abort_flag) return false; /* write the WAVE/AIFF headers if necessary */ if(!write_necessary_headers(d)) { d->abort_flag = true; return false; } if(d->skip_specification->value.samples > 0) { const FLAC__uint64 skip = (FLAC__uint64)d->skip_specification->value.samples;#ifdef FLAC__HAS_OGG if(d->is_ogg) { if(!OggFLAC__file_decoder_seek_absolute(d->decoder.ogg.file, skip)) { print_error_with_state(d, "ERROR seeking while skipping bytes"); return false; } if(!OggFLAC__file_decoder_process_until_end_of_file(d->decoder.ogg.file) && !d->aborting_due_to_until) { flac__utils_printf(stderr, 2, "\n"); print_error_with_state(d, "ERROR while decoding frames"); return false; } if(OggFLAC__file_decoder_get_state(d->decoder.ogg.file) != OggFLAC__FILE_DECODER_OK && OggFLAC__file_decoder_get_state(d->decoder.ogg.file) != OggFLAC__FILE_DECODER_END_OF_FILE && !d->aborting_due_to_until) { flac__utils_printf(stderr, 2, "\n"); print_error_with_state(d, "ERROR during decoding"); return false; } } else#endif { if(!FLAC__file_decoder_seek_absolute(d->decoder.flac.file, skip)) { print_error_with_state(d, "ERROR seeking while skipping bytes"); return false; } if(!FLAC__file_decoder_process_until_end_of_file(d->decoder.flac.file) && !d->aborting_due_to_until) { flac__utils_printf(stderr, 2, "\n"); print_error_with_state(d, "ERROR while decoding frames"); return false; } if(FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_OK && FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_END_OF_FILE && !d->aborting_due_to_until) { flac__utils_printf(stderr, 2, "\n"); print_error_with_state(d, "ERROR during decoding"); return false; } } } else {#ifdef FLAC__HAS_OGG if(d->is_ogg) { if(!OggFLAC__file_decoder_process_until_end_of_file(d->decoder.ogg.file) && !d->aborting_due_to_until) { flac__utils_printf(stderr, 2, "\n"); print_error_with_state(d, "ERROR while decoding data"); return false; } if(OggFLAC__file_decoder_get_state(d->decoder.ogg.file) != OggFLAC__FILE_DECODER_OK && OggFLAC__file_decoder_get_state(d->decoder.ogg.file) != OggFLAC__FILE_DECODER_END_OF_FILE && !d->aborting_due_to_until) { flac__utils_printf(stderr, 2, "\n"); print_error_with_state(d, "ERROR during decoding"); return false; } } else#endif { if(!FLAC__file_decoder_process_until_end_of_file(d->decoder.flac.file) && !d->aborting_due_to_until) { flac__utils_printf(stderr, 2, "\n"); print_error_with_state(d, "ERROR while decoding data"); return false; } if(FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_OK && FLAC__file_decoder_get_state(d->decoder.flac.file) != FLAC__FILE_DECODER_END_OF_FILE && !d->aborting_due_to_until) { flac__utils_printf(stderr, 2, "\n"); print_error_with_state(d, "ERROR during decoding"); return false; } } } if((d->is_wave_out || d->is_aiff_out) && ((d->total_samples * d->channels * ((d->bps+7)/8)) & 1)) { if(flac__utils_fwrite("\000", 1, 1, d->fout) != 1) { print_error_with_state(d, d->is_wave_out? "ERROR writing pad byte to WAVE data chunk" : "ERROR writing pad byte to AIFF SSND chunk" ); return false; } } return true;}int DecoderSession_finish_ok(DecoderSession *d){ FLAC__bool md5_failure = false;#ifdef FLAC__HAS_OGG if(d->is_ogg) { if(d->decoder.ogg.file) { md5_failure = !OggFLAC__file_decoder_finish(d->decoder.ogg.file) && !d->aborting_due_to_until; print_stats(d); OggFLAC__file_decoder_delete(d->decoder.ogg.file); } } else#endif { if(d->decoder.flac.file) { md5_failure = !FLAC__file_decoder_finish(d->decoder.flac.file) && !d->aborting_due_to_until; print_stats(d); FLAC__file_decoder_delete(d->decoder.flac.file); } } if(d->analysis_mode) flac__analyze_finish(d->aopts); if(md5_failure) { flac__utils_printf(stderr, 1, "\r%s: WARNING, MD5 signature mismatch\n", d->inbasefilename); } else { flac__utils_printf(stderr, 2, "\r%s: %s \n", d->inbasefilename, d->test_only? "ok ":d->analysis_mode?"done ":"done"); } DecoderSession_destroy(d, /*error_occurred=*/false); if((d->is_wave_out || d->is_aiff_out) && d->wave_chunk_size_fixup.needs_fixup) if(!fixup_wave_chunk_size(d->outfilename, d->is_wave_out, d->wave_chunk_size_fixup.riff_offset, d->wave_chunk_size_fixup.data_offset, d->wave_chunk_size_fixup.frames_offset, (FLAC__uint32)d->samples_processed, d->channels, d->bps)) return 1; return 0;}int DecoderSession_finish_error(DecoderSession *d){#ifdef FLAC__HAS_OGG if(d->is_ogg) { if(d->decoder.ogg.file) { OggFLAC__file_decoder_finish(d->decoder.ogg.file); OggFLAC__file_decoder_delete(d->decoder.ogg.file); } } else#endif { if(d->decoder.flac.file) { FLAC__file_decoder_finish(d->decoder.flac.file); FLAC__file_decoder_delete(d->decoder.flac.file); } } if(d->analysis_mode) flac__analyze_finish(d->aopts); DecoderSession_destroy(d, /*error_occurred=*/true); return 1;}FLAC__bool canonicalize_until_specification(utils__SkipUntilSpecification *spec, const char *inbasefilename, unsigned sample_rate, FLAC__uint64 skip, FLAC__uint64 total_samples_in_input){ /* convert from mm:ss.sss to sample number if necessary */ flac__utils_canonicalize_skip_until_specification(spec, sample_rate); /* special case: if "--until=-0", use the special value '0' to mean "end-of-stream" */ if(spec->is_relative && spec->value.samples == 0) { spec->is_relative = false; return true; } /* in any other case the total samples in the input must be known */ if(total_samples_in_input == 0) { flac__utils_printf(stderr, 1, "%s: ERROR, cannot use --until when FLAC metadata has total sample count of 0\n", inbasefilename); return false; } FLAC__ASSERT(spec->value_is_samples); /* convert relative specifications to absolute */ if(spec->is_relative) { if(spec->value.samples <= 0) spec->value.samples += (FLAC__int64)total_samples_in_input; else spec->value.samples += skip; spec->is_relative = false; } /* error check */ if(spec->value.samples < 0) { flac__utils_printf(stderr, 1, "%s: ERROR, --until value is before beginning of input\n", inbasefilename); return false; } if((FLAC__uint64)spec->value.samples <= skip) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -