bool FlacDecoder::_open(const string_t& filename) { #if defined(LIBTOOLS_WINDOWS) && defined(string_t_w_available) _file=_wfopen(string_t_to_stdw(filename).c_str(),L"rb"); #else _file=fopen(string_t_to_std(filename).c_str(),"rb"); #endif if (!_file) { #ifndef NDEBUG std::cerr << "FlacDecoder cannot open file: " << string_t_to_std(filename) << std::endl; #endif return false; } _error=false; FLAC__StreamDecoderInitStatus init_status= FLAC__stream_decoder_init_FILE(_streamdecoder,_file, &FlacDecoder::_write_callback, &FlacDecoder::_metadata_callback, &FlacDecoder::_error_callback, (void*) this); assert(init_status==FLAC__STREAM_DECODER_INIT_STATUS_OK); FLAC__stream_decoder_set_metadata_respond(_streamdecoder,FLAC__METADATA_TYPE_STREAMINFO); FLAC__stream_decoder_set_metadata_respond(_streamdecoder,FLAC__METADATA_TYPE_VORBIS_COMMENT); if (!FLAC__stream_decoder_process_until_end_of_metadata(_streamdecoder) || _error) { _error=false; FLAC__stream_decoder_finish(_streamdecoder); init_status= FLAC__stream_decoder_init_ogg_FILE(_streamdecoder,_file, &FlacDecoder::_write_callback, &FlacDecoder::_metadata_callback, &FlacDecoder::_error_callback, (void*) this); assert(init_status==FLAC__STREAM_DECODER_INIT_STATUS_OK); FLAC__stream_decoder_set_metadata_respond(_streamdecoder,FLAC__METADATA_TYPE_STREAMINFO); FLAC__stream_decoder_set_metadata_respond(_streamdecoder,FLAC__METADATA_TYPE_VORBIS_COMMENT); if (!FLAC__stream_decoder_process_until_end_of_metadata(_streamdecoder)||_error) { #ifndef NDEBUG std::cerr << "FlacDecoder file: " << string_t_to_std(filename) << " is not a FLAC or OGG FLAC file" << std::endl; #endif FLAC__stream_decoder_finish(_streamdecoder); fclose(_file); return false; } } uint64_t music_len=FLAC__stream_decoder_get_total_samples(_streamdecoder); _bufferl.reserve(music_len); _bufferr.reserve(music_len); _opened=true; _ended=false; return true; }
static void LongSound_init (LongSound me, MelderFile file) { MelderFile_copy (file, & my file); MelderFile_open (file); // BUG: should be auto, but that requires an implemented .transfer() my f = file -> filePointer; my audioFileType = MelderFile_checkSoundFile (file, & my numberOfChannels, & my encoding, & my sampleRate, & my startOfData, & my nx); if (my audioFileType == 0) Melder_throw (U"File not recognized (LongSound only supports AIFF, AIFC, WAV, NeXT/Sun, NIST and FLAC)."); if (my encoding == Melder_SHORTEN || my encoding == Melder_POLYPHONE) Melder_throw (U"LongSound does not support sound files compressed with \"shorten\"."); if (my nx < 1) Melder_throw (U"Audio file contains 0 samples."); my xmin = 0.0; my dx = 1 / my sampleRate; my xmax = my nx * my dx; my x1 = 0.5 * my dx; my numberOfBytesPerSamplePoint = Melder_bytesPerSamplePoint (my encoding); my bufferLength = prefs_bufferLength; for (;;) { my nmax = my bufferLength * my numberOfChannels * my sampleRate * (1 + 3 * MARGIN); try { my buffer = NUMvector <int16> (0, my nmax * my numberOfChannels); break; } catch (MelderError) { my bufferLength *= 0.5; // try 30, 15, or 7.5 seconds if (my bufferLength < 5.0) // too short to be good throw; Melder_clearError (); // delete out-of-memory message } } my imin = 1; my imax = 0; my flacDecoder = nullptr; if (my audioFileType == Melder_FLAC) { my flacDecoder = FLAC__stream_decoder_new (); FLAC__stream_decoder_init_FILE (my flacDecoder, my f, _LongSound_FLAC_write, nullptr, _LongSound_FLAC_error, me); } my mp3f = nullptr; if (my audioFileType == Melder_MP3) { my mp3f = mp3f_new (); mp3f_set_file (my mp3f, my f); mp3f_set_callback (my mp3f, _LongSound_MP3_convert, me); if (! mp3f_analyze (my mp3f)) Melder_throw (U"Unable to analyze MP3 file."); Melder_warning (U"Time measurements in MP3 files can be off by several tens of milliseconds. " U"Please convert to WAV file if you need time precision or annotation."); } }
static bool DecodeFLAC(FILE *f, FILE *of) { fseek(f, 0, SEEK_SET); FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new(); if(decoder == nullptr) { return false; } FLAC__stream_decoder_set_metadata_respond_all(decoder); FLACClientData client; client.of = of; client.started = false; client.encoder = FLAC__stream_encoder_new(); FLAC__StreamDecoderInitStatus initStatus = FLAC__stream_decoder_init_FILE(decoder, f, write_cb, metadata_cb, error_cb, &client); if(initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK || client.encoder == nullptr) { FLAC__stream_decoder_delete(decoder); return false; } FLAC__stream_decoder_process_until_end_of_stream(decoder); FLAC__stream_decoder_finish(decoder); FLAC__stream_decoder_delete(decoder); FLAC__stream_encoder_finish(client.encoder); FLAC__stream_encoder_delete(client.encoder); for(auto m = client.metadata.begin(); m != client.metadata.end(); m++) { FLAC__metadata_object_delete(*m); } return client.started; }
static int start_read(sox_format_t * const ft) { priv_t * p = (priv_t *)ft->priv; lsx_debug("API version %u", FLAC_API_VERSION_CURRENT); p->decoder = FLAC__stream_decoder_new(); if (p->decoder == NULL) { lsx_fail_errno(ft, SOX_ENOMEM, "FLAC ERROR creating the decoder instance"); return SOX_EOF; } FLAC__stream_decoder_set_md5_checking(p->decoder, sox_true); FLAC__stream_decoder_set_metadata_respond_all(p->decoder); if (FLAC__stream_decoder_init_FILE(p->decoder, ft->fp, /* Not using SoX IO */ FLAC__frame_decode_callback, FLAC__decoder_metadata_callback, FLAC__decoder_error_callback, ft) != FLAC__STREAM_DECODER_INIT_STATUS_OK){ lsx_fail_errno(ft, SOX_EHDR, "FLAC ERROR initialising decoder"); return SOX_EOF; } ft->fp = NULL; /* Transfer ownership of fp to FLAC */ if (!FLAC__stream_decoder_process_until_end_of_metadata(p->decoder)) { lsx_fail_errno(ft, SOX_EHDR, "FLAC ERROR whilst decoding metadata"); return SOX_EOF; } if (FLAC__stream_decoder_get_state(p->decoder) > FLAC__STREAM_DECODER_END_OF_STREAM) { lsx_fail_errno(ft, SOX_EHDR, "FLAC ERROR during metadata decoding"); return SOX_EOF; } ft->encoding.encoding = SOX_ENCODING_FLAC; ft->signal.rate = p->sample_rate; ft->encoding.bits_per_sample = p->bits_per_sample; ft->signal.channels = p->channels; ft->signal.length = p->total_samples * p->channels; return SOX_SUCCESS; }
static FLAC__bool test_stream_decoder(Layer layer, FLAC__bool is_ogg) { FLAC__StreamDecoder *decoder; FLAC__StreamDecoderInitStatus init_status; FLAC__StreamDecoderState state; StreamDecoderClientData decoder_client_data; FLAC__bool expect; decoder_client_data.layer = layer; printf("\n+++ libFLAC unit test: FLAC__StreamDecoder (layer: %s, format: %s)\n\n", LayerString[layer], is_ogg? "Ogg FLAC" : "FLAC"); printf("testing FLAC__stream_decoder_new()... "); decoder = FLAC__stream_decoder_new(); if(0 == decoder) { printf("FAILED, returned NULL\n"); return false; } printf("OK\n"); printf("testing FLAC__stream_decoder_delete()... "); FLAC__stream_decoder_delete(decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_new()... "); decoder = FLAC__stream_decoder_new(); if(0 == decoder) { printf("FAILED, returned NULL\n"); return false; } printf("OK\n"); switch(layer) { case LAYER_STREAM: case LAYER_SEEKABLE_STREAM: printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_stream(decoder, 0, 0, 0, 0, 0, 0, 0, 0, 0) : FLAC__stream_decoder_init_stream(decoder, 0, 0, 0, 0, 0, 0, 0, 0, 0); break; case LAYER_FILE: printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_FILE(decoder, stdin, 0, 0, 0, 0) : FLAC__stream_decoder_init_FILE(decoder, stdin, 0, 0, 0, 0); break; case LAYER_FILENAME: printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_file(decoder, flacfilename(is_ogg), 0, 0, 0, 0) : FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), 0, 0, 0, 0); break; default: die_("internal error 003"); return false; } if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS) return die_s_(0, decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_delete()... "); FLAC__stream_decoder_delete(decoder); printf("OK\n"); num_expected_ = 0; expected_metadata_sequence_[num_expected_++] = &streaminfo_; printf("testing FLAC__stream_decoder_new()... "); decoder = FLAC__stream_decoder_new(); if(0 == decoder) { printf("FAILED, returned NULL\n"); return false; } printf("OK\n"); if(is_ogg) { printf("testing FLAC__stream_decoder_set_ogg_serial_number()... "); if(!FLAC__stream_decoder_set_ogg_serial_number(decoder, file_utils__ogg_serial_number)) return die_s_("returned false", decoder); printf("OK\n"); } printf("testing FLAC__stream_decoder_set_md5_checking()... "); if(!FLAC__stream_decoder_set_md5_checking(decoder, true)) return die_s_("returned false", decoder); printf("OK\n"); if(layer < LAYER_FILENAME) { printf("opening %sFLAC file... ", is_ogg? "Ogg ":""); decoder_client_data.file = fopen(flacfilename(is_ogg), "rb"); if(0 == decoder_client_data.file) { printf("ERROR (%s)\n", strerror(errno)); return false; } printf("OK\n"); } switch(layer) { case LAYER_STREAM: printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_stream(decoder, stream_decoder_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) : FLAC__stream_decoder_init_stream(decoder, stream_decoder_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data); break; case LAYER_SEEKABLE_STREAM: printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_stream(decoder, stream_decoder_read_callback_, stream_decoder_seek_callback_, stream_decoder_tell_callback_, stream_decoder_length_callback_, stream_decoder_eof_callback_, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) : FLAC__stream_decoder_init_stream(decoder, stream_decoder_read_callback_, stream_decoder_seek_callback_, stream_decoder_tell_callback_, stream_decoder_length_callback_, stream_decoder_eof_callback_, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data); break; case LAYER_FILE: printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_FILE(decoder, decoder_client_data.file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) : FLAC__stream_decoder_init_FILE(decoder, decoder_client_data.file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data); break; case LAYER_FILENAME: printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) : FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data); break; default: die_("internal error 009"); return false; } if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) return die_s_(0, decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_get_state()... "); state = FLAC__stream_decoder_get_state(decoder); printf("returned state = %u (%s)... OK\n", state, FLAC__StreamDecoderStateString[state]); decoder_client_data.current_metadata_number = 0; decoder_client_data.ignore_errors = false; decoder_client_data.error_occurred = false; printf("testing FLAC__stream_decoder_get_md5_checking()... "); if(!FLAC__stream_decoder_get_md5_checking(decoder)) { printf("FAILED, returned false, expected true\n"); return false; } printf("OK\n"); printf("testing FLAC__stream_decoder_process_until_end_of_metadata()... "); if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder)) return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_process_single()... "); if(!FLAC__stream_decoder_process_single(decoder)) return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_skip_single_frame()... "); if(!FLAC__stream_decoder_skip_single_frame(decoder)) return die_s_("returned false", decoder); printf("OK\n"); if(layer < LAYER_FILE) { printf("testing FLAC__stream_decoder_flush()... "); if(!FLAC__stream_decoder_flush(decoder)) return die_s_("returned false", decoder); printf("OK\n"); decoder_client_data.ignore_errors = true; printf("testing FLAC__stream_decoder_process_single()... "); if(!FLAC__stream_decoder_process_single(decoder)) return die_s_("returned false", decoder); printf("OK\n"); decoder_client_data.ignore_errors = false; } expect = (layer != LAYER_STREAM); printf("testing FLAC__stream_decoder_seek_absolute()... "); if(FLAC__stream_decoder_seek_absolute(decoder, 0) != expect) return die_s_(expect? "returned false" : "returned true", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_process_until_end_of_stream()... "); if(!FLAC__stream_decoder_process_until_end_of_stream(decoder)) return die_s_("returned false", decoder); printf("OK\n"); expect = (layer != LAYER_STREAM); printf("testing FLAC__stream_decoder_seek_absolute()... "); if(FLAC__stream_decoder_seek_absolute(decoder, 0) != expect) return die_s_(expect? "returned false" : "returned true", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_get_channels()... "); { unsigned channels = FLAC__stream_decoder_get_channels(decoder); if(channels != streaminfo_.data.stream_info.channels) { printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels); return false; } } printf("OK\n"); printf("testing FLAC__stream_decoder_get_bits_per_sample()... "); { unsigned bits_per_sample = FLAC__stream_decoder_get_bits_per_sample(decoder); if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) { printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample); return false; } } printf("OK\n"); printf("testing FLAC__stream_decoder_get_sample_rate()... "); { unsigned sample_rate = FLAC__stream_decoder_get_sample_rate(decoder); if(sample_rate != streaminfo_.data.stream_info.sample_rate) { printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate); return false; } } printf("OK\n"); printf("testing FLAC__stream_decoder_get_blocksize()... "); { unsigned blocksize = FLAC__stream_decoder_get_blocksize(decoder); /* value could be anything since we're at the last block, so accept any reasonable answer */ printf("returned %u... %s\n", blocksize, blocksize>0? "OK" : "FAILED"); if(blocksize == 0) return false; } printf("testing FLAC__stream_decoder_get_channel_assignment()... "); { FLAC__ChannelAssignment ca = FLAC__stream_decoder_get_channel_assignment(decoder); printf("returned %u (%s)... OK\n", (unsigned)ca, FLAC__ChannelAssignmentString[ca]); } if(layer < LAYER_FILE) { printf("testing FLAC__stream_decoder_reset()... "); if(!FLAC__stream_decoder_reset(decoder)) { state = FLAC__stream_decoder_get_state(decoder); printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__StreamDecoderStateString[state]); return false; } printf("OK\n"); if(layer == LAYER_STREAM) { /* after a reset() we have to rewind the input ourselves */ printf("rewinding input... "); if(fseeko(decoder_client_data.file, 0, SEEK_SET) < 0) { printf("FAILED, errno = %d\n", errno); return false; } printf("OK\n"); } decoder_client_data.current_metadata_number = 0; printf("testing FLAC__stream_decoder_process_until_end_of_stream()... "); if(!FLAC__stream_decoder_process_until_end_of_stream(decoder)) return die_s_("returned false", decoder); printf("OK\n"); } printf("testing FLAC__stream_decoder_finish()... "); if(!FLAC__stream_decoder_finish(decoder)) return die_s_("returned false", decoder); printf("OK\n"); /* * respond all */ printf("testing FLAC__stream_decoder_set_metadata_respond_all()... "); if(!FLAC__stream_decoder_set_metadata_respond_all(decoder)) return die_s_("returned false", decoder); printf("OK\n"); num_expected_ = 0; if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */ expected_metadata_sequence_[num_expected_++] = &streaminfo_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &padding_; expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected
static FLAC__bool stream_decoder_test_respond_(FLAC__StreamDecoder *decoder, StreamDecoderClientData *dcd, FLAC__bool is_ogg) { FLAC__StreamDecoderInitStatus init_status; if(!FLAC__stream_decoder_set_md5_checking(decoder, true)) return die_s_("at FLAC__stream_decoder_set_md5_checking(), returned false", decoder); /* for FLAC__stream_encoder_init_FILE(), the FLAC__stream_encoder_finish() closes the file so we have to keep re-opening: */ if(dcd->layer == LAYER_FILE) { printf("opening %sFLAC file... ", is_ogg? "Ogg ":""); dcd->file = fopen(flacfilename(is_ogg), "rb"); if(0 == dcd->file) { printf("ERROR (%s)\n", strerror(errno)); return false; } printf("OK\n"); } switch(dcd->layer) { case LAYER_STREAM: printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_stream(decoder, stream_decoder_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) : FLAC__stream_decoder_init_stream(decoder, stream_decoder_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) ; break; case LAYER_SEEKABLE_STREAM: printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_stream(decoder, stream_decoder_read_callback_, stream_decoder_seek_callback_, stream_decoder_tell_callback_, stream_decoder_length_callback_, stream_decoder_eof_callback_, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) : FLAC__stream_decoder_init_stream(decoder, stream_decoder_read_callback_, stream_decoder_seek_callback_, stream_decoder_tell_callback_, stream_decoder_length_callback_, stream_decoder_eof_callback_, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd); break; case LAYER_FILE: printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_FILE(decoder, dcd->file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) : FLAC__stream_decoder_init_FILE(decoder, dcd->file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd); break; case LAYER_FILENAME: printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":""); init_status = is_ogg? FLAC__stream_decoder_init_ogg_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) : FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd); break; default: die_("internal error 000"); return false; } if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) return die_s_(0, decoder); printf("OK\n"); dcd->current_metadata_number = 0; if(dcd->layer < LAYER_FILE && fseeko(dcd->file, 0, SEEK_SET) < 0) { printf("FAILED rewinding input, errno = %d\n", errno); return false; } printf("testing FLAC__stream_decoder_process_until_end_of_stream()... "); if(!FLAC__stream_decoder_process_until_end_of_stream(decoder)) return die_s_("returned false", decoder); printf("OK\n"); printf("testing FLAC__stream_decoder_finish()... "); if(!FLAC__stream_decoder_finish(decoder)) return die_s_("returned false", decoder); printf("OK\n"); return true; }
int __stdcall WWFlacRW_DecodeAll(const wchar_t *path) { FLAC__bool ok = true; FILE *fp = NULL; errno_t ercd; FLAC__StreamDecoderInitStatus initStatus = FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE; FlacDecodeInfo *fdi = FlacTInfoNew<FlacDecodeInfo>(g_flacDecodeInfoMap); if (NULL == fdi) { return FRT_OtherError; } fdi->errorCode = FRT_Success; fdi->decoder = FLAC__stream_decoder_new(); if(fdi->decoder == NULL) { fdi->errorCode = FRT_FlacStreamDecoderNewFailed; dprintf("%s Flac decode error %d. set complete event.\n", __FUNCTION__, fdi->errorCode); goto end; } wcsncpy_s(fdi->path, path, (sizeof fdi->path)/2-1); FLAC__stream_decoder_set_md5_checking(fdi->decoder, true); FLAC__stream_decoder_set_metadata_respond(fdi->decoder, FLAC__METADATA_TYPE_STREAMINFO); FLAC__stream_decoder_set_metadata_respond(fdi->decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT); FLAC__stream_decoder_set_metadata_respond(fdi->decoder, FLAC__METADATA_TYPE_PICTURE); FLAC__stream_decoder_set_metadata_respond(fdi->decoder, FLAC__METADATA_TYPE_CUESHEET); // Windowsでは、この方法でファイルを開かなければならぬ。 ercd = _wfopen_s(&fp, fdi->path, L"rb"); if (ercd != 0 || NULL == fp) { fdi->errorCode = FRT_FileOpenError; goto end; } initStatus = FLAC__stream_decoder_init_FILE( fdi->decoder, fp, WriteCallback, MetadataCallback, ErrorCallback, fdi); // FLAC__stream_decoder_finish()がfcloseしてくれるので、忘れる。 fp = NULL; if(initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK) { fdi->errorCode = FRT_FlacStreamDecoderInitFailed; dprintf("%s Flac decode error %d. set complete event.\n", __FUNCTION__, fdi->errorCode); goto end; } fdi->errorCode = FRT_Success; ok = FLAC__stream_decoder_process_until_end_of_metadata(fdi->decoder); if (!ok) { if (fdi->errorCode == FRT_Success) { fdi->errorCode = FRT_DecorderProcessFailed; } dprintf("%s Flac metadata process error fdi->errorCode=%d\n", __FUNCTION__, fdi->errorCode); goto end; } ok = FLAC__stream_decoder_process_until_end_of_stream(fdi->decoder); if (!ok) { if (fdi->errorCode == FRT_Success) { fdi->errorCode = FRT_DecorderProcessFailed; } dprintf("%s Flac decode error fdi->errorCode=%d\n", __FUNCTION__, fdi->errorCode); goto end; } fdi->errorCode = FRT_Completed; end: if (fdi->errorCode < 0) { if (NULL != fdi->decoder) { if (initStatus == FLAC__STREAM_DECODER_INIT_STATUS_OK) { FLAC__stream_decoder_finish(fdi->decoder); } FLAC__stream_decoder_delete(fdi->decoder); fdi->decoder = NULL; } int result = fdi->errorCode; FlacTInfoDelete<FlacDecodeInfo>(g_flacDecodeInfoMap, fdi); fdi = NULL; return result; } return fdi->id; }
static int start_read(sox_format_t * const ft) { priv_t * p = (priv_t *)ft->priv; lsx_debug("API version %u", FLAC_API_VERSION_CURRENT); p->decoder = FLAC__stream_decoder_new(); if (p->decoder == NULL) { lsx_fail_errno(ft, SOX_ENOMEM, "FLAC ERROR creating the decoder instance"); return SOX_EOF; } FLAC__stream_decoder_set_md5_checking(p->decoder, sox_true); FLAC__stream_decoder_set_metadata_respond_all(p->decoder); #if FLAC_API_VERSION_CURRENT <= 7 /* This is wrong: not using SoX IO, and there will be 2 FILEs open; * however, it's an old FLAC API, so not worth fixing now. */ FLAC__file_decoder_set_filename(p->decoder, ft->filename); FLAC__file_decoder_set_write_callback(p->decoder, FLAC__frame_decode_callback); FLAC__file_decoder_set_metadata_callback(p->decoder, FLAC__decoder_metadata_callback); FLAC__file_decoder_set_error_callback(p->decoder, FLAC__decoder_error_callback); FLAC__file_decoder_set_client_data(p->decoder, ft); if (FLAC__file_decoder_init(p->decoder) != FLAC__FILE_DECODER_OK) { lsx_fail_errno(ft, SOX_EHDR, "FLAC ERROR initialising decoder"); return SOX_EOF; } #else if (FLAC__stream_decoder_init_FILE(p->decoder, ft->fp, /* Not using SoX IO */ FLAC__frame_decode_callback, FLAC__decoder_metadata_callback, FLAC__decoder_error_callback, ft) != FLAC__STREAM_DECODER_INIT_STATUS_OK){ lsx_fail_errno(ft, SOX_EHDR, "FLAC ERROR initialising decoder"); return SOX_EOF; } ft->fp = NULL; /* Transfer ownership of fp to FLAC */ #endif if (!FLAC__stream_decoder_process_until_end_of_metadata(p->decoder)) { lsx_fail_errno(ft, SOX_EHDR, "FLAC ERROR whilst decoding metadata"); return SOX_EOF; } #if FLAC_API_VERSION_CURRENT <= 7 if (FLAC__file_decoder_get_state(p->decoder) != FLAC__FILE_DECODER_OK && FLAC__file_decoder_get_state(p->decoder) != FLAC__FILE_DECODER_END_OF_FILE) { #else if (FLAC__stream_decoder_get_state(p->decoder) > FLAC__STREAM_DECODER_END_OF_STREAM) { #endif lsx_fail_errno(ft, SOX_EHDR, "FLAC ERROR during metadata decoding"); return SOX_EOF; } ft->encoding.encoding = SOX_ENCODING_FLAC; ft->signal.rate = p->sample_rate; ft->encoding.bits_per_sample = p->bits_per_sample; ft->signal.channels = p->channels; ft->signal.length = p->total_samples * p->channels; return SOX_SUCCESS; } static size_t read_samples(sox_format_t * const ft, sox_sample_t * sampleBuffer, size_t const requested) { priv_t * p = (priv_t *)ft->priv; size_t actual = 0; while (!p->eof && actual < requested) { if (p->wide_sample_number >= p->number_of_wide_samples) FLAC__stream_decoder_process_single(p->decoder); if (p->wide_sample_number >= p->number_of_wide_samples) p->eof = sox_true; else { unsigned channel; for (channel = 0; channel < p->channels; channel++, actual++) { FLAC__int32 d = p->decoded_wide_samples[channel][p->wide_sample_number]; switch (p->bits_per_sample) { case 8: *sampleBuffer++ = SOX_SIGNED_8BIT_TO_SAMPLE(d,); break; case 16: *sampleBuffer++ = SOX_SIGNED_16BIT_TO_SAMPLE(d,); break; case 24: *sampleBuffer++ = SOX_SIGNED_24BIT_TO_SAMPLE(d,); break; case 32: *sampleBuffer++ = SOX_SIGNED_32BIT_TO_SAMPLE(d,); break; } } ++p->wide_sample_number; } } return actual; }