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; }
FLAC__bool safe_decoder_init_(const char *filename, FLAC__StreamDecoder *decoder) { if(decoder == 0) return false; safe_decoder_finish_(decoder); FLAC__stream_decoder_set_md5_checking(decoder, false); FLAC__stream_decoder_set_metadata_ignore_all(decoder); FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO); FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT); if(stream_data_.is_http_source) { flac_http_open(filename, 0); if(FLAC__stream_decoder_init_stream(decoder, http_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, write_callback_, metadata_callback_, error_callback_, /*client_data=*/&stream_data_) != FLAC__STREAM_DECODER_INIT_STATUS_OK) return false; } else { if(FLAC__stream_decoder_init_file(decoder, filename, write_callback_, metadata_callback_, error_callback_, /*client_data=*/&stream_data_) != FLAC__STREAM_DECODER_INIT_STATUS_OK) return false; } if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder)) return false; return true; }
FLAC__bool EasyFLAC__process_until_end_of_metadata(EasyFLAC__StreamDecoder *decoder) { if (decoder->is_oggflac) return OggFLAC__stream_decoder_process_until_end_of_metadata(decoder->oggflac); else return FLAC__stream_decoder_process_until_end_of_metadata(decoder->flac); }
bool CFlacDec::GetMetaData(FILE *in, const bool /*nice*/, CAudioMetaData* m) { FLAC__StreamDecoder *vf; vf = FLAC__stream_decoder_new(); FLAC__stream_decoder_set_metadata_ignore_all(vf); // we need streaminfo (default on) and FLAC__METADATA_TYPE_VORBIS_COMMENT (default off) for ID3 tags FLAC__stream_decoder_set_metadata_respond(vf, FLAC__METADATA_TYPE_STREAMINFO); FLAC__stream_decoder_set_metadata_respond(vf, FLAC__METADATA_TYPE_VORBIS_COMMENT); if (!Open(in, vf)) { return false; } if (FLAC__stream_decoder_process_until_end_of_metadata(vf)) { // if the metadata callback was called mMetadata should be filled with infos if (mMetadata) { SetMetaData(mMetadata, m); } } // clean up stuff, the mMetadata may be used later again so let the decoder free it FLAC__stream_decoder_finish(vf); FLAC__stream_decoder_delete(vf); return true; }
bool SoundFileReaderFlac::open(InputStream& stream, Info& info) { // Create the decoder m_decoder = FLAC__stream_decoder_new(); if (!m_decoder) { err() << "Failed to open FLAC file (failed to allocate the decoder)" << std::endl; return false; } // Initialize the decoder with our callbacks m_clientData.stream = &stream; FLAC__stream_decoder_init_stream(m_decoder, &streamRead, &streamSeek, &streamTell, &streamLength, &streamEof, &streamWrite, &streamMetadata, &streamError, &m_clientData); // Read the header if (!FLAC__stream_decoder_process_until_end_of_metadata(m_decoder)) { close(); err() << "Failed to open FLAC file (failed to read metadata)" << std::endl; return false; } // Retrieve the sound properties info = m_clientData.info; // was filled in the "metadata" callback // We must keep the channel count for the seek function m_channelCount = info.channelCount; return true; }
static bool flac_decoder_initialize(struct flac_data *data, FLAC__StreamDecoder *sd, FLAC__uint64 duration) { data->total_frames = duration; if (!FLAC__stream_decoder_process_until_end_of_metadata(sd)) { g_warning("problem reading metadata"); return false; } if (data->initialized) { /* done */ decoder_initialized(data->decoder, &data->audio_format, data->input_stream->seekable, (float)data->total_frames / (float)data->audio_format.sample_rate); return true; } if (data->input_stream->seekable) /* allow the workaround below only for nonseekable streams*/ return false; /* no stream_info packet found; try to initialize the decoder from the first frame header */ FLAC__stream_decoder_process_single(sd); return data->initialized; }
bool_t read_metadata(FLAC__StreamDecoder *decoder, callback_info *info) { FLAC__StreamDecoderState ret; reset_info(info); /* Reset the decoder */ if (FLAC__stream_decoder_reset(decoder) == false) { FLACNG_ERROR("Could not reset the decoder!\n"); return FALSE; } /* Try to decode the metadata */ if (FLAC__stream_decoder_process_until_end_of_metadata(decoder) == false) { ret = FLAC__stream_decoder_get_state(decoder); AUDDBG("Could not read the metadata: %s(%d)!\n", FLAC__StreamDecoderStateString[ret], ret); reset_info(info); return FALSE; } return TRUE; }
SoundSource::OpenResult SoundSourceFLAC::tryOpen( OpenMode /*mode*/, const OpenParams& /*config*/) { DEBUG_ASSERT(!m_file.isOpen()); if (!m_file.open(QIODevice::ReadOnly)) { kLogger.warning() << "Failed to open FLAC file:" << m_file.fileName(); return OpenResult::Failed; } m_decoder = FLAC__stream_decoder_new(); if (m_decoder == nullptr) { kLogger.warning() << "Failed to create FLAC decoder!"; return OpenResult::Failed; } FLAC__stream_decoder_set_md5_checking(m_decoder, false); const FLAC__StreamDecoderInitStatus initStatus( FLAC__stream_decoder_init_stream(m_decoder, FLAC_read_cb, FLAC_seek_cb, FLAC_tell_cb, FLAC_length_cb, FLAC_eof_cb, FLAC_write_cb, FLAC_metadata_cb, FLAC_error_cb, this)); if (initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK) { kLogger.warning() << "Failed to initialize FLAC decoder:" << initStatus; return OpenResult::Failed; } if (!FLAC__stream_decoder_process_until_end_of_metadata(m_decoder)) { kLogger.warning() << "Failed to process FLAC metadata:" << FLAC__stream_decoder_get_state(m_decoder); return OpenResult::Failed; } m_curFrameIndex = frameIndexMin(); return OpenResult::Succeeded; }
void play_file_from_filename(const std::string name) { currently_playing = std::string(name); if (audiobuf) linearFree(audiobuf); if (name.rfind(".flac") != std::string::npos) { if (!FLAC_decoder) { FLAC_decoder = FLAC__stream_decoder_new(); FLAC__stream_decoder_set_md5_checking(FLAC_decoder, true); } audiobuf_index = 0; decode_mode = AUDIO_MODE_FLAC; FLAC__StreamDecoderInitStatus init_status = FLAC__stream_decoder_init_file(FLAC_decoder, name.c_str(), FLAC_write_callback, FLAC_metadata_callback, FLAC_error_callback, NULL); if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) { printf("ERROR: initializing decoder: %s\n", FLAC__StreamDecoderInitStatusString[init_status]); } FLAC__stream_decoder_process_until_end_of_metadata(FLAC_decoder); } else { decode_mode = AUDIO_MODE_VORBIS; v = stb_vorbis_open_filename(name.c_str(), &error, NULL); info = stb_vorbis_get_info(v); Samples = info.sample_rate; audiobuf_size = Samples * sizeof(s16) * 2; audiobuf = (s16*)linearAlloc(audiobuf_size); } paused = false; }
Result SoundSourceFLAC::tryOpen(const AudioSourceConfig& /*audioSrcCfg*/) { DEBUG_ASSERT(!m_file.isOpen()); if (!m_file.open(QIODevice::ReadOnly)) { qWarning() << "Failed to open FLAC file:" << m_file.fileName(); return ERR; } m_decoder = FLAC__stream_decoder_new(); if (m_decoder == NULL) { qWarning() << "Failed to create FLAC decoder!"; return ERR; } FLAC__stream_decoder_set_md5_checking(m_decoder, FALSE); const FLAC__StreamDecoderInitStatus initStatus( FLAC__stream_decoder_init_stream(m_decoder, FLAC_read_cb, FLAC_seek_cb, FLAC_tell_cb, FLAC_length_cb, FLAC_eof_cb, FLAC_write_cb, FLAC_metadata_cb, FLAC_error_cb, this)); if (initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK) { qWarning() << "Failed to initialize FLAC decoder:" << initStatus; return ERR; } if (!FLAC__stream_decoder_process_until_end_of_metadata(m_decoder)) { qWarning() << "Failed to process FLAC metadata:" << FLAC__stream_decoder_get_state(m_decoder); return ERR; } m_curFrameIndex = getMinFrameIndex(); return OK; }
bool OAFLACReader::open(const SPtr<DataStream>& stream, AudioFileInfo& info, UINT32 offset) { if (stream == nullptr) return false; stream->seek(offset); mDecoder = FLAC__stream_decoder_new(); if (mDecoder == nullptr) { LOGERR("Failed to open a FLAC file."); return false; } mData.stream = stream; mData.streamOffset = offset; FLAC__stream_decoder_init_stream(mDecoder, &streamRead, &streamSeek, &streamTell, &streamLength, &streamEof, &streamWrite, &streamMetadata, &streamError, &mData); if (!FLAC__stream_decoder_process_until_end_of_metadata(mDecoder)) { close(); LOGERR("Failed to open a FLAC file."); return false; } info = mData.info; return true; }
static status_t HandleFLAC(const char *filename, MediaScannerClient* client) { status_t status = UNKNOWN_ERROR; FLAC__StreamDecoder *decoder; decoder = FLAC__stream_decoder_new(); if (!decoder) return status; FLAC__stream_decoder_set_md5_checking(decoder, false); FLAC__stream_decoder_set_metadata_ignore_all(decoder); FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO); FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT); FLAC__StreamDecoderInitStatus init_status; init_status = FLAC__stream_decoder_init_file(decoder, filename, flac_write, flac_metadata, flac_error, client); if (init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) goto exit; if (!FLAC__stream_decoder_process_until_end_of_metadata(decoder)) goto exit; status = OK; exit: FLAC__stream_decoder_finish(decoder); FLAC__stream_decoder_delete(decoder); return status; }
int read_flac_file (apr_pool_t* pool,void** file_struct, const char* file_path, encoding_options_t* enc_opt){ FLAC__StreamDecoderInitStatus status; FLAC__bool status2; flac_file_t* flac_file = *file_struct = (flac_file_t*) apr_pcalloc(pool, sizeof(flac_file_t)); flac_file->stream_decoder = FLAC__stream_decoder_new(); flac_file->channels = 0; flac_file->samples = 0; flac_file->total_samples = 0; flac_file->rate = 0; flac_file->buf = NULL; status = FLAC__stream_decoder_init_file(flac_file->stream_decoder, file_path, flac_write, flac_metadata, flac_errors, flac_file); if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK){ return -1; } status2 = FLAC__stream_decoder_process_until_end_of_metadata(flac_file->stream_decoder); if (status2 != true){ return -2; } FLAC__stream_decoder_process_single(flac_file->stream_decoder); if (status2 != true){ return -2; } enc_opt->channels = flac_file->channels; enc_opt->rate = flac_file->rate; enc_opt->total_samples_per_channel = flac_file->total_samples; enc_opt->samples_to_request = 1024; return 0; }
FLAC__bool populate_seekpoint_values(const char *filename, FLAC__StreamMetadata *block, FLAC__bool *needs_write) { FLAC__StreamDecoder *decoder; ClientData client_data; FLAC__bool ok = true; FLAC__ASSERT(0 != block); FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_SEEKTABLE); client_data.seektable_template = &block->data.seek_table; client_data.samples_written = 0; /* client_data.audio_offset must be determined later */ client_data.first_seekpoint_to_check = 0; client_data.error_occurred = false; decoder = FLAC__stream_decoder_new(); if(0 == decoder) { fprintf(stderr, "%s: ERROR (--add-seekpoint) creating the decoder instance\n", filename); return false; } FLAC__stream_decoder_set_md5_checking(decoder, false); FLAC__stream_decoder_set_metadata_ignore_all(decoder); if(FLAC__stream_decoder_init_file(decoder, filename, write_callback_, /*metadata_callback=*/0, error_callback_, &client_data) != FLAC__STREAM_DECODER_INIT_STATUS_OK) { fprintf(stderr, "%s: ERROR (--add-seekpoint) initializing the decoder instance (%s)\n", filename, FLAC__stream_decoder_get_resolved_state_string(decoder)); ok = false; } if(ok && !FLAC__stream_decoder_process_until_end_of_metadata(decoder)) { fprintf(stderr, "%s: ERROR (--add-seekpoint) decoding file (%s)\n", filename, FLAC__stream_decoder_get_resolved_state_string(decoder)); ok = false; } if(ok && !FLAC__stream_decoder_get_decode_position(decoder, &client_data.audio_offset)) { fprintf(stderr, "%s: ERROR (--add-seekpoint) decoding file\n", filename); ok = false; } client_data.last_offset = client_data.audio_offset; if(ok && !FLAC__stream_decoder_process_until_end_of_stream(decoder)) { fprintf(stderr, "%s: ERROR (--add-seekpoint) decoding file (%s)\n", filename, FLAC__stream_decoder_get_resolved_state_string(decoder)); ok = false; } if(ok && client_data.error_occurred) { fprintf(stderr, "%s: ERROR (--add-seekpoint) decoding file (%u:%s)\n", filename, (unsigned)client_data.error_status, FLAC__StreamDecoderErrorStatusString[client_data.error_status]); ok = false; } *needs_write = true; FLAC__stream_decoder_delete(decoder); return ok; }
static gboolean gst_flac_dec_set_format (GstAudioDecoder * dec, GstCaps * caps) { const GValue *headers; GstFlacDec *flacdec; GstStructure *s; guint i, num; flacdec = GST_FLAC_DEC (dec); GST_LOG_OBJECT (dec, "sink caps: %" GST_PTR_FORMAT, caps); s = gst_caps_get_structure (caps, 0); headers = gst_structure_get_value (s, "streamheader"); if (headers == NULL || !GST_VALUE_HOLDS_ARRAY (headers)) { GST_WARNING_OBJECT (dec, "no 'streamheader' field in input caps, try " "adding a flacparse element upstream"); return FALSE; } if (gst_adapter_available (flacdec->adapter) > 0) { GST_WARNING_OBJECT (dec, "unexpected data left in adapter"); gst_adapter_clear (flacdec->adapter); } num = gst_value_array_get_size (headers); for (i = 0; i < num; ++i) { const GValue *header_val; GstBuffer *header_buf; header_val = gst_value_array_get_value (headers, i); if (header_val == NULL || !GST_VALUE_HOLDS_BUFFER (header_val)) return FALSE; header_buf = g_value_dup_boxed (header_val); GST_INFO_OBJECT (dec, "pushing header buffer of %" G_GSIZE_FORMAT " bytes " "into adapter", gst_buffer_get_size (header_buf)); gst_adapter_push (flacdec->adapter, header_buf); } GST_DEBUG_OBJECT (dec, "Processing headers and metadata"); if (!FLAC__stream_decoder_process_until_end_of_metadata (flacdec->decoder)) { GST_WARNING_OBJECT (dec, "process_until_end_of_metadata failed"); if (FLAC__stream_decoder_get_state (flacdec->decoder) == FLAC__STREAM_DECODER_ABORTED) { GST_WARNING_OBJECT (flacdec, "Read callback caused internal abort"); /* allow recovery */ gst_adapter_clear (flacdec->adapter); FLAC__stream_decoder_flush (flacdec->decoder); gst_flac_dec_handle_decoder_error (flacdec, TRUE); } } GST_INFO_OBJECT (dec, "headers and metadata are now processed"); return TRUE; }
FLAC__bool FLAC_plugin__decoder_init(FLAC__StreamDecoder *decoder, const char *filename, FLAC__int64 filesize, stream_data_struct *stream_data, output_config_t *config) { FLAC__StreamDecoderInitStatus init_status; FLAC__ASSERT(decoder); FLAC_plugin__decoder_finish(decoder); /* init decoder */ FLAC__stream_decoder_set_md5_checking(decoder, false); FLAC__stream_decoder_set_metadata_ignore_all(decoder); FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO); FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT); if ((init_status = FLAC__stream_decoder_init_file(decoder, filename, write_callback, metadata_callback, error_callback, /*client_data=*/stream_data)) != FLAC__STREAM_DECODER_INIT_STATUS_OK) { FLAC_plugin__show_error("Error while initializing decoder (%s [%s]).", FLAC__StreamDecoderInitStatusString[init_status], FLAC__stream_decoder_get_resolved_state_string(decoder)); return false; } /* process */ cfg = *config; wide_samples_in_reservoir_ = 0; stream_data->is_playing = false; stream_data->abort_flag = false; stream_data->has_replaygain = false; if (!FLAC__stream_decoder_process_until_end_of_metadata(decoder)) { FLAC_plugin__show_error("Error while processing metadata (%s).", FLAC__stream_decoder_get_resolved_state_string(decoder)); return false; } /* check results */ if (stream_data->abort_flag) return false; /* metadata callback already popped up the error dialog */ /* init replaygain */ stream_data->output_bits_per_sample = stream_data->has_replaygain && cfg.replaygain.enable ? cfg.resolution.replaygain.bps_out : cfg.resolution.normal.dither_24_to_16 ? min(stream_data->bits_per_sample, 16) : stream_data->bits_per_sample; if (stream_data->has_replaygain && cfg.replaygain.enable && cfg.resolution.replaygain.dither) FLAC__replaygain_synthesis__init_dither_context(&stream_data->dither_context, stream_data->bits_per_sample, cfg.resolution.replaygain.noise_shaping); /* more inits */ stream_data->eof = false; stream_data->seek_to = -1; stream_data->is_playing = true; stream_data->average_bps = (unsigned)(filesize / (125.*(double)(FLAC__int64)stream_data->total_samples/(double)stream_data->sample_rate)); bh_index_last_w = 0; bh_index_last_o = BITRATE_HIST_SIZE; decode_position = 0; decode_position_last = 0; written_time_last = 0; return true; }
static void flac_get_size (struct cdtoc *t) { FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new (); if (decoder) { FLAC__stream_decoder_set_md5_checking (decoder, false); int init_status = FLAC__stream_decoder_init_stream (decoder, &file_read_callback, &file_seek_callback, &file_tell_callback, &file_len_callback, &file_eof_callback, &flac_write_callback, &flac_metadata_callback, &flac_error_callback, t); FLAC__stream_decoder_process_until_end_of_metadata (decoder); FLAC__stream_decoder_delete (decoder); } }
// soundsource overrides Result SoundSourceFLAC::open() { if (!m_file.open(QIODevice::ReadOnly)) { qWarning() << "SSFLAC: Could not read file!"; return ERR; } m_decoder = FLAC__stream_decoder_new(); if (m_decoder == NULL) { qWarning() << "SSFLAC: decoder allocation failed!"; return ERR; } FLAC__StreamDecoderInitStatus initStatus( FLAC__stream_decoder_init_stream( m_decoder, FLAC_read_cb, FLAC_seek_cb, FLAC_tell_cb, FLAC_length_cb, FLAC_eof_cb, FLAC_write_cb, FLAC_metadata_cb, FLAC_error_cb, (void*) this) ); if (initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK) { qWarning() << "SSFLAC: decoder init failed!"; goto decoderError; } if (!FLAC__stream_decoder_process_until_end_of_metadata(m_decoder)) { qWarning() << "SSFLAC: process to end of meta failed!"; qWarning() << "SSFLAC: decoder state: " << FLAC__stream_decoder_get_state(m_decoder); goto decoderError; } // now number of samples etc. should be populated if (m_flacBuffer == NULL) { // we want 2 samples per frame, see ::flacWrite code -- bkgood m_flacBuffer = new FLAC__int16[m_maxBlocksize * 2 /*m_iChannels*/]; } if (m_leftoverBuffer == NULL) { m_leftoverBuffer = new FLAC__int16[m_maxBlocksize * 2 /*m_iChannels*/]; } // qDebug() << "SSFLAC: Total samples: " << m_samples; // qDebug() << "SSFLAC: Sampling rate: " << m_iSampleRate << " Hz"; // qDebug() << "SSFLAC: Channels: " << m_iChannels; // qDebug() << "SSFLAC: BPS: " << m_bps; return OK; decoderError: FLAC__stream_decoder_finish(m_decoder); FLAC__stream_decoder_delete(m_decoder); m_decoder = NULL; qWarning() << "SSFLAC: Decoder error at file" << m_qFilename; return ERR; }
FLAC_API FLAC__bool FLAC__seekable_stream_decoder_process_until_end_of_metadata(FLAC__SeekableStreamDecoder *decoder) { FLAC__bool ret; FLAC__ASSERT(0 != decoder); if(decoder->private_->stream_decoder->protected_->state == FLAC__STREAM_DECODER_END_OF_STREAM) decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM; if(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM) return true; FLAC__ASSERT(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_OK); ret = FLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->stream_decoder); if(!ret) decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR; return ret; }
bool OAFLACReader::isValid(const SPtr<DataStream>& stream, UINT32 offset) { stream->seek(offset); FLAC__StreamDecoder* decoder = FLAC__stream_decoder_new(); if (!decoder) return false; FLACDecoderData data; data.stream = stream; mData.streamOffset = offset; FLAC__stream_decoder_init_stream(decoder, &streamRead, &streamSeek, &streamTell, &streamLength, &streamEof, &streamWrite, nullptr, &streamError, &data); bool valid = FLAC__stream_decoder_process_until_end_of_metadata(decoder) != 0; FLAC__stream_decoder_finish(decoder); FLAC__stream_decoder_delete(decoder); return valid && !data.error; }
int flac_open(FILE *in,oe_enc_opt *opt,unsigned char *oldbuf,int buflen){ flacfile *flac; /*Ok. At this point, we know we have a FLAC or an OggFLAC file. Set up the FLAC decoder.*/ flac=malloc(sizeof(*flac)); flac->decoder=FLAC__stream_decoder_new(); FLAC__stream_decoder_set_md5_checking(flac->decoder,false); /*We get STREAMINFO packets by default, but not VORBIS_COMMENT or PICTURE.*/ FLAC__stream_decoder_set_metadata_respond(flac->decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT); FLAC__stream_decoder_set_metadata_respond(flac->decoder, FLAC__METADATA_TYPE_PICTURE); flac->inopt=opt; flac->f=in; flac->oldbuf=malloc(buflen*sizeof(*flac->oldbuf)); memcpy(flac->oldbuf,oldbuf,buflen*sizeof(*flac->oldbuf)); flac->bufpos=0; flac->buflen=buflen; flac->block_buf=NULL; if((*(flac_id(oldbuf,buflen)? FLAC__stream_decoder_init_stream:FLAC__stream_decoder_init_ogg_stream))( flac->decoder,read_callback,NULL,NULL,NULL,eof_callback, write_callback,metadata_callback,error_callback,flac)== FLAC__STREAM_DECODER_INIT_STATUS_OK){ /*Decode until we get the file length, sample rate, the number of channels, and the Vorbis comments (if any).*/ if(FLAC__stream_decoder_process_until_end_of_metadata(flac->decoder)){ opt->read_samples=flac_read; opt->readdata=flac; /*FLAC supports 1 to 8 channels only.*/ speex_assert(flac->channels>0&&flac->channels<=8); /*It uses the same channel mappings as WAV.*/ flac->channel_permute=wav_permute_matrix[flac->channels-1]; return 1; } } flac_close(flac); fprintf(stderr,_("ERROR: Could not open FLAC stream.\n")); return 0; }
clFLACDataProvider::clFLACDataProvider( const std::shared_ptr<clBlob>& Data ) : m_Data( Data ) , m_Format() , m_StreamData( std::make_shared<sFLACStreamData>() ) , m_DecodingBuffer() , m_BufferUsed( 0 ) , m_IsEndOfStream( false ) { { FLAC__StreamDecoderInitStatus Status = FLAC__stream_decoder_init_stream( m_StreamData->m_Decoder, &flacRead, &flacSeek, &flacTell, &flacLength, &flacEof, &flacWrite, &flacMeta, &flacError, this ); } FLAC__bool Status = FLAC__stream_decoder_process_until_end_of_metadata( m_StreamData->m_Decoder ); if ( !Status ) return; if ( !FLAC__stream_decoder_process_single( m_StreamData->m_Decoder ) ) return; m_Format.m_NumChannels = FLAC__stream_decoder_get_channels( m_StreamData->m_Decoder ); m_Format.m_SamplesPerSecond = FLAC__stream_decoder_get_sample_rate( m_StreamData->m_Decoder ); m_Format.m_BitsPerSample = FLAC__stream_decoder_get_bits_per_sample( m_StreamData->m_Decoder ); int BufSize = FLAC__stream_decoder_get_blocksize( m_StreamData->m_Decoder ) * m_Format.m_BitsPerSample * 8 * m_Format.m_NumChannels; // store two blocks m_DecodingBuffer.resize( BufSize * 2 ); int TotalSamples = FLAC__stream_decoder_get_total_samples( m_StreamData->m_Decoder ); }
bool SoundFileReaderFlac::check(InputStream& stream) { // Create a decoder FLAC__StreamDecoder* decoder = FLAC__stream_decoder_new(); if (!decoder) return false; // Initialize the decoder with our callbacks ClientData data; data.stream = &stream; data.error = false; FLAC__stream_decoder_init_stream(decoder, &streamRead, &streamSeek, &streamTell, &streamLength, &streamEof, &streamWrite, NULL, &streamError, &data); // Read the header bool valid = FLAC__stream_decoder_process_until_end_of_metadata(decoder) != 0; // Destroy the decoder FLAC__stream_decoder_finish(decoder); FLAC__stream_decoder_delete(decoder); return valid && !data.error; }
bool FlacDecoder::Open(musik::core::sdk::IDataStream *stream){ this->stream = stream; FLAC__StreamDecoderInitStatus init_status = FLAC__stream_decoder_init_stream( this->decoder, FlacDecoder::FlacRead, FlacDecoder::FlacSeek, FlacDecoder::FlacTell, FlacDecoder::FlacFileSize, FlacDecoder::FlacEof, FlacDecoder::FlacWrite, FlacDecoder::FlacMetadata, FlacDecoder::FlacError, this); if (init_status == FLAC__STREAM_DECODER_INIT_STATUS_OK) { FLAC__stream_decoder_process_until_end_of_metadata(this->decoder); return true; } return false; }
FLAC_API FLAC__bool FLAC__seekable_stream_decoder_seek_absolute(FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 sample) { FLAC__uint64 length; FLAC__ASSERT(0 != decoder); FLAC__ASSERT(decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_OK || decoder->protected_->state == FLAC__SEEKABLE_STREAM_DECODER_END_OF_STREAM); decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEKING; /* turn off md5 checking if a seek is attempted */ decoder->private_->do_md5_checking = false; if(!FLAC__stream_decoder_reset(decoder->private_->stream_decoder)) { decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR; return false; } /* get the file length */ if(decoder->private_->length_callback(decoder, &length, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK) { decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR; return false; } /* rewind */ if(decoder->private_->seek_callback(decoder, 0, decoder->private_->client_data) != FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK) { decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR; return false; } if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder->private_->stream_decoder)) { decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_STREAM_DECODER_ERROR; return false; } if(decoder->private_->stream_info.total_samples > 0 && sample >= decoder->private_->stream_info.total_samples) { decoder->protected_->state = FLAC__SEEKABLE_STREAM_DECODER_SEEK_ERROR; return false; } return seek_to_absolute_sample_(decoder, length, sample); }
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 gboolean xmms_flac_init (xmms_xform_t *xform) { xmms_flac_data_t *data; xmms_sample_format_t sample_fmt; FLAC__bool retval; #if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7 FLAC__StreamDecoderState init_status; #else FLAC__StreamDecoderInitStatus init_status; #endif gint filesize; const gchar *metakey; g_return_val_if_fail (xform, FALSE); data = g_new0 (xmms_flac_data_t, 1); xmms_xform_private_data_set (xform, data); data->flacdecoder = FLAC__stream_decoder_new (); /* we don't need to explicitly tell the decoder to respond to * FLAC__METADATA_TYPE_STREAMINFO here, it always does. */ #if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7 FLAC__seekable_stream_decoder_set_metadata_respond (data->flacdecoder, FLAC__METADATA_TYPE_VORBIS_COMMENT); FLAC__seekable_stream_decoder_set_eof_callback (data->flacdecoder, flac_callback_eof); FLAC__seekable_stream_decoder_set_read_callback (data->flacdecoder, flac_callback_read); FLAC__seekable_stream_decoder_set_seek_callback (data->flacdecoder, flac_callback_seek); FLAC__seekable_stream_decoder_set_tell_callback (data->flacdecoder, flac_callback_tell); FLAC__seekable_stream_decoder_set_write_callback (data->flacdecoder, flac_callback_write); FLAC__seekable_stream_decoder_set_error_callback (data->flacdecoder, flac_callback_error); FLAC__seekable_stream_decoder_set_length_callback (data->flacdecoder, flac_callback_length); FLAC__seekable_stream_decoder_set_metadata_callback (data->flacdecoder, flac_callback_metadata); FLAC__seekable_stream_decoder_set_client_data (data->flacdecoder, xform); init_status = FLAC__seekable_stream_decoder_init (data->flacdecoder); if (init_status != FLAC__SEEKABLE_STREAM_DECODER_OK) { const gchar *errmsg = FLAC__seekable_stream_decoder_get_resolved_state_string (data->flacdecoder); XMMS_DBG ("FLAC init failed: %s", errmsg); goto err; } #else FLAC__stream_decoder_set_metadata_respond (data->flacdecoder, FLAC__METADATA_TYPE_VORBIS_COMMENT); FLAC__stream_decoder_set_metadata_respond (data->flacdecoder, FLAC__METADATA_TYPE_PICTURE); init_status = FLAC__stream_decoder_init_stream (data->flacdecoder, flac_callback_read, flac_callback_seek, flac_callback_tell, flac_callback_length, flac_callback_eof, flac_callback_write, flac_callback_metadata, flac_callback_error, xform); if (init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) { XMMS_DBG ("FLAC init failed: %s", FLAC__stream_decoder_get_resolved_state_string (data->flacdecoder)); goto err; } #endif retval = FLAC__stream_decoder_process_until_end_of_metadata (data->flacdecoder); if (!retval) goto err; if (data->vorbiscomment) { handle_comments (xform, data); } metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_BITRATE; xmms_xform_metadata_set_int (xform, metakey, (gint) data->bit_rate); metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_SIZE; if (xmms_xform_metadata_get_int (xform, metakey, &filesize)) { gint32 val = (gint32) data->total_samples / data->sample_rate * 1000; metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION; xmms_xform_metadata_set_int (xform, metakey, val); } if (data->bits_per_sample == 8) { sample_fmt = XMMS_SAMPLE_FORMAT_S8; } else if (data->bits_per_sample == 16) { sample_fmt = XMMS_SAMPLE_FORMAT_S16; } else if (data->bits_per_sample == 24) { sample_fmt = XMMS_SAMPLE_FORMAT_S32; } else if (data->bits_per_sample == 32) { sample_fmt = XMMS_SAMPLE_FORMAT_S32; } else { goto err; } xmms_xform_outdata_type_add (xform, XMMS_STREAM_TYPE_MIMETYPE, "audio/pcm", XMMS_STREAM_TYPE_FMT_FORMAT, sample_fmt, XMMS_STREAM_TYPE_FMT_CHANNELS, data->channels, XMMS_STREAM_TYPE_FMT_SAMPLERATE, data->sample_rate, XMMS_STREAM_TYPE_END); data->buffer = g_string_new (NULL); return TRUE; err: FLAC__stream_decoder_finish (data->flacdecoder); FLAC__stream_decoder_delete (data->flacdecoder); g_free (data); xmms_xform_private_data_set (xform, NULL); return FALSE; }
/* read mode: * 0 - no read after seek * 1 - read 2 frames * 2 - read until end */ static FLAC__bool seek_barrage(FLAC__bool is_ogg, const char *filename, off_t filesize, unsigned count, FLAC__int64 total_samples, unsigned read_mode) { FLAC__StreamDecoder *decoder; DecoderClientData decoder_client_data; unsigned i; long int n; decoder_client_data.got_data = false; decoder_client_data.total_samples = 0; decoder_client_data.quiet = false; decoder_client_data.ignore_errors = false; decoder_client_data.error_occurred = false; printf("\n+++ seek test: FLAC__StreamDecoder (%s FLAC, read_mode=%u)\n\n", is_ogg? "Ogg":"native", read_mode); decoder = FLAC__stream_decoder_new(); if(0 == decoder) return die_("FLAC__stream_decoder_new() FAILED, returned NULL\n"); if(is_ogg) { if(FLAC__stream_decoder_init_ogg_file(decoder, filename, write_callback_, metadata_callback_, error_callback_, &decoder_client_data) != FLAC__STREAM_DECODER_INIT_STATUS_OK) return die_s_("FLAC__stream_decoder_init_file() FAILED", decoder); } else { if(FLAC__stream_decoder_init_file(decoder, filename, write_callback_, metadata_callback_, error_callback_, &decoder_client_data) != FLAC__STREAM_DECODER_INIT_STATUS_OK) return die_s_("FLAC__stream_decoder_init_file() FAILED", decoder); } if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder)) return die_s_("FLAC__stream_decoder_process_until_end_of_metadata() FAILED", decoder); if(!is_ogg) { /* not necessary to do this for Ogg because of its seeking method */ /* process until end of stream to make sure we can still seek in that state */ decoder_client_data.quiet = true; if(!FLAC__stream_decoder_process_until_end_of_stream(decoder)) return die_s_("FLAC__stream_decoder_process_until_end_of_stream() FAILED", decoder); decoder_client_data.quiet = false; printf("stream decoder state is %s\n", FLAC__stream_decoder_get_resolved_state_string(decoder)); if(FLAC__stream_decoder_get_state(decoder) != FLAC__STREAM_DECODER_END_OF_STREAM) return die_s_("expected FLAC__STREAM_DECODER_END_OF_STREAM", decoder); } #ifdef _MSC_VER printf("file's total_samples is %I64u\n", decoder_client_data.total_samples); #else printf("file's total_samples is %llu\n", (unsigned long long)decoder_client_data.total_samples); #endif #if !defined _MSC_VER && !defined __MINGW32__ && !defined __EMX__ if (decoder_client_data.total_samples > (FLAC__uint64)RAND_MAX) { printf("ERROR: must be total_samples < %u\n", (unsigned)RAND_MAX); return false; } #endif n = (long int)decoder_client_data.total_samples; if(n == 0 && total_samples >= 0) n = (long int)total_samples; /* if we don't have a total samples count, just guess based on the file size */ /* @@@ for is_ogg we should get it from last page's granulepos */ if(n == 0) { /* 8 would imply no compression, 9 guarantees that we will get some samples off the end of the stream to test that case */ n = 9 * filesize / (decoder_client_data.channels * decoder_client_data.bits_per_sample); #if !defined _MSC_VER && !defined __MINGW32__ if(n > RAND_MAX) n = RAND_MAX; #endif } printf("Begin seek barrage, count=%u\n", count); for (i = 0; !stop_signal_ && (count == 0 || i < count); i++) { FLAC__uint64 pos; /* for the first 10, seek to the first 10 samples */ if (n >= 10 && i < 10) { pos = i; } /* for the second 10, seek to the last 10 samples */ else if (n >= 10 && i < 20) { pos = n - 1 - (i-10); } /* for the third 10, seek past the end and make sure we fail properly as expected */ else if (i < 30) { pos = n + (i-20); } else { #if !defined _MSC_VER && !defined __MINGW32__ pos = (FLAC__uint64)(random() % n); #else /* RAND_MAX is only 32767 in my MSVC */ pos = (FLAC__uint64)((rand()<<15|rand()) % n); #endif } #ifdef _MSC_VER printf("seek(%I64u)... ", pos); #else printf("seek(%llu)... ", (unsigned long long)pos); #endif fflush(stdout); if(!FLAC__stream_decoder_seek_absolute(decoder, pos)) { if(pos >= (FLAC__uint64)n) printf("seek past end failed as expected... "); else if(decoder_client_data.total_samples == 0 && total_samples <= 0) printf("seek failed, assuming it was past EOF... "); else return die_s_("FLAC__stream_decoder_seek_absolute() FAILED", decoder); if(!FLAC__stream_decoder_flush(decoder)) return die_s_("FLAC__stream_decoder_flush() FAILED", decoder); } else if(read_mode == 1) { printf("decode_frame... "); fflush(stdout); if(!FLAC__stream_decoder_process_single(decoder)) return die_s_("FLAC__stream_decoder_process_single() FAILED", decoder); printf("decode_frame... "); fflush(stdout); if(!FLAC__stream_decoder_process_single(decoder)) return die_s_("FLAC__stream_decoder_process_single() FAILED", decoder); } else if(read_mode == 2) { printf("decode_all... "); fflush(stdout); decoder_client_data.quiet = true; if(!FLAC__stream_decoder_process_until_end_of_stream(decoder)) return die_s_("FLAC__stream_decoder_process_until_end_of_stream() FAILED", decoder); decoder_client_data.quiet = false; } printf("OK\n"); fflush(stdout); } if(FLAC__stream_decoder_get_state(decoder) != FLAC__STREAM_DECODER_UNINITIALIZED) { if(!FLAC__stream_decoder_finish(decoder)) return die_s_("FLAC__stream_decoder_finish() FAILED", decoder); } FLAC__stream_decoder_delete(decoder); printf("\nPASSED!\n"); return true; }
status_t FLACParser::init() { // setup libFLAC parser mDecoder = FLAC__stream_decoder_new(); if (mDecoder == NULL) { // The new should succeed, since probably all it does is a malloc // that always succeeds in Android. But to avoid dependence on the // libFLAC internals, we check and log here. LOGE("new failed"); return NO_INIT; } FLAC__stream_decoder_set_md5_checking(mDecoder, false); FLAC__stream_decoder_set_metadata_ignore_all(mDecoder); FLAC__stream_decoder_set_metadata_respond( mDecoder, FLAC__METADATA_TYPE_STREAMINFO); FLAC__stream_decoder_set_metadata_respond( mDecoder, FLAC__METADATA_TYPE_PICTURE); FLAC__stream_decoder_set_metadata_respond( mDecoder, FLAC__METADATA_TYPE_VORBIS_COMMENT); FLAC__StreamDecoderInitStatus initStatus; initStatus = FLAC__stream_decoder_init_stream( mDecoder, read_callback, seek_callback, tell_callback, length_callback, eof_callback, write_callback, metadata_callback, error_callback, (void *) this); if (initStatus != FLAC__STREAM_DECODER_INIT_STATUS_OK) { // A failure here probably indicates a programming error and so is // unlikely to happen. But we check and log here similarly to above. LOGE("init_stream failed %d", initStatus); return NO_INIT; } // parse all metadata if (!FLAC__stream_decoder_process_until_end_of_metadata(mDecoder)) { LOGE("end_of_metadata failed"); return NO_INIT; } if (mStreamInfoValid) { // check channel count switch (getChannels()) { case 1: case 2: break; default: LOGE("unsupported channel count %u", getChannels()); return NO_INIT; } // check bit depth switch (getBitsPerSample()) { case 8: case 16: case 24: break; default: LOGE("unsupported bits per sample %u", getBitsPerSample()); return NO_INIT; } // check sample rate switch (getSampleRate()) { case 8000: case 11025: case 12000: case 16000: case 22050: case 24000: case 32000: case 44100: case 48000: break; default: // 96000 would require a proper downsampler in AudioFlinger LOGE("unsupported sample rate %u", getSampleRate()); return NO_INIT; } // configure the appropriate copy function, defaulting to trespass static const struct { unsigned mChannels; unsigned mBitsPerSample; void (*mCopy)(short *dst, const int *const *src, unsigned nSamples); } table[] = { { 1, 8, copyMono8 }, { 2, 8, copyStereo8 }, { 1, 16, copyMono16 }, { 2, 16, copyStereo16 }, { 1, 24, copyMono24 }, { 2, 24, copyStereo24 }, }; for (unsigned i = 0; i < sizeof(table)/sizeof(table[0]); ++i) { if (table[i].mChannels == getChannels() && table[i].mBitsPerSample == getBitsPerSample()) { mCopy = table[i].mCopy; break; } } // populate track metadata if (mTrackMetadata != 0) { mTrackMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); mTrackMetadata->setInt32(kKeyChannelCount, getChannels()); mTrackMetadata->setInt32(kKeySampleRate, getSampleRate()); // sample rate is non-zero, so division by zero not possible mTrackMetadata->setInt64(kKeyDuration, (getTotalSamples() * 1000000LL) / getSampleRate()); } } else { LOGE("missing STREAMINFO"); return NO_INIT; } if (mFileMetadata != 0) { mFileMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_FLAC); } return OK; }
bool flac_reader_c::parse_file() { FLAC__StreamDecoderState state; flac_block_t block; uint64_t u, old_pos; int result, progress, old_progress; bool ok; m_in->setFilePointer(0); metadata_parsed = false; mxinfo(Y("+-> Parsing the FLAC file. This can take a LONG time.\n")); init_flac_decoder(); result = FLAC__stream_decoder_process_until_end_of_metadata(m_flac_decoder.get()); mxverb(2, boost::format("flac_reader: extract->metadata, result: %1%, mdp: %2%, num blocks: %3%\n") % result % metadata_parsed % blocks.size()); if (!metadata_parsed) mxerror_fn(m_ti.m_fname, Y("No metadata block found. This file is broken.\n")); FLAC__stream_decoder_get_decode_position(m_flac_decoder.get(), &u); block.type = FLAC_BLOCK_TYPE_HEADERS; block.filepos = 0; block.len = u; old_pos = u; blocks.push_back(block); mxverb(2, boost::format("flac_reader: headers: block at %1% with size %2%\n") % block.filepos % block.len); old_progress = -5; ok = FLAC__stream_decoder_skip_single_frame(m_flac_decoder.get()); while (ok) { state = FLAC__stream_decoder_get_state(m_flac_decoder.get()); progress = m_in->getFilePointer() * 100 / m_size; if ((progress - old_progress) >= 5) { mxinfo(boost::format(Y("+-> Pre-parsing FLAC file: %1%%%%2%")) % progress % "\r"); old_progress = progress; } if (FLAC__stream_decoder_get_decode_position(m_flac_decoder.get(), &u) && (u != old_pos)) { block.type = FLAC_BLOCK_TYPE_DATA; block.filepos = old_pos; block.len = u - old_pos; old_pos = u; blocks.push_back(block); mxverb(2, boost::format("flac_reader: skip/decode frame, block at %1% with size %2%\n") % block.filepos % block.len); } if (state > FLAC__STREAM_DECODER_READ_FRAME) break; ok = FLAC__stream_decoder_skip_single_frame(m_flac_decoder.get()); } if (100 != old_progress) mxinfo(Y("+-> Pre-parsing FLAC file: 100%\n")); else mxinfo("\n"); if ((blocks.size() == 0) || (blocks[0].type != FLAC_BLOCK_TYPE_HEADERS)) mxerror(Y("flac_reader: Could not read all header packets.\n")); m_in->setFilePointer(0); blocks[0].len -= 4; blocks[0].filepos = 4; return metadata_parsed; }