diff --git a/src/decoder/Client.hxx b/src/decoder/Client.hxx index 610c90bb4..15710a3ca 100644 --- a/src/decoder/Client.hxx +++ b/src/decoder/Client.hxx @@ -28,6 +28,10 @@ #include struct AudioFormat; +struct Tag; +struct ReplayGainInfo; +class MixRampInfo; +class InputStream; /** * An interface between the decoder plugin and the MPD core. @@ -84,6 +88,64 @@ public: * failed. */ virtual void SeekError() = 0; + + /** + * Sets the time stamp for the next data chunk [seconds]. The MPD + * core automatically counts it up, and a decoder plugin only needs to + * use this function if it thinks that adding to the time stamp based + * on the buffer size won't work. + */ + virtual void SubmitTimestamp(double t) = 0; + + /** + * This function is called by the decoder plugin when it has + * successfully decoded block of input data. + * + * @param is an input stream which is buffering while we are waiting + * for the player + * @param data the source buffer + * @param length the number of bytes in the buffer + * @return the current command, or DecoderCommand::NONE if there is no + * command pending + */ + virtual DecoderCommand SubmitData(InputStream *is, + const void *data, size_t length, + uint16_t kbit_rate) = 0; + + DecoderCommand SubmitData(InputStream &is, + const void *data, size_t length, + uint16_t kbit_rate) { + return SubmitData(&is, data, length, kbit_rate); + } + + /** + * This function is called by the decoder plugin when it has + * successfully decoded a tag. + * + * @param is an input stream which is buffering while we are waiting + * for the player + * @param tag the tag to send + * @return the current command, or DecoderCommand::NONE if there is no + * command pending + */ + virtual DecoderCommand SubmitTag(InputStream *is, Tag &&tag) = 0 ; + + DecoderCommand SubmitTag(InputStream &is, Tag &&tag) { + return SubmitTag(&is, std::move(tag)); + } + + /** + * Set replay gain values for the following chunks. + * + * @param replay_gain_info the replay_gain_info object; may be nullptr + * to invalidate the previous replay gain values + */ + virtual void SubmitReplayGain(const ReplayGainInfo *replay_gain_info) = 0; + + /** + * Store MixRamp tags. + */ + virtual void SubmitMixRamp(MixRampInfo &&mix_ramp) = 0; }; #endif diff --git a/src/decoder/DecoderAPI.cxx b/src/decoder/DecoderAPI.cxx index da637a0b1..362df4e03 100644 --- a/src/decoder/DecoderAPI.cxx +++ b/src/decoder/DecoderAPI.cxx @@ -382,12 +382,11 @@ decoder_skip(DecoderClient *client, InputStream &is, size_t size) } void -decoder_timestamp(DecoderClient &client, double t) +Decoder::SubmitTimestamp(double t) { assert(t >= 0); - auto &decoder = (Decoder &)client; - decoder.timestamp = t; + timestamp = t; } /** @@ -446,56 +445,52 @@ update_stream_tag(DecoderClient &client, InputStream *is) } DecoderCommand -decoder_data(DecoderClient &client, - InputStream *is, - const void *data, size_t length, - uint16_t kbit_rate) +Decoder::SubmitData(InputStream *is, + const void *data, size_t length, + uint16_t kbit_rate) { - auto &decoder = (Decoder &)client; - DecoderControl &dc = decoder.dc; - assert(dc.state == DecoderState::DECODE); assert(dc.pipe != nullptr); assert(length % dc.in_audio_format.GetFrameSize() == 0); - DecoderCommand cmd = decoder_lock_get_virtual_command(decoder); + DecoderCommand cmd = decoder_lock_get_virtual_command(*this); if (cmd == DecoderCommand::STOP || cmd == DecoderCommand::SEEK || length == 0) return cmd; - assert(!decoder.initial_seek_pending); - assert(!decoder.initial_seek_running); + assert(!initial_seek_pending); + assert(!initial_seek_running); /* send stream tags */ - if (update_stream_tag(decoder, is)) { - if (decoder.decoder_tag != nullptr) { + if (update_stream_tag(*this, is)) { + if (decoder_tag != nullptr) { /* merge with tag from decoder plugin */ - Tag *tag = Tag::Merge(*decoder.decoder_tag, - *decoder.stream_tag); - cmd = do_send_tag(decoder, *tag); + Tag *tag = Tag::Merge(*decoder_tag, + *stream_tag); + cmd = do_send_tag(*this, *tag); delete tag; } else /* send only the stream tag */ - cmd = do_send_tag(decoder, *decoder.stream_tag); + cmd = do_send_tag(*this, *stream_tag); if (cmd != DecoderCommand::NONE) return cmd; } - if (decoder.convert != nullptr) { + if (convert != nullptr) { assert(dc.in_audio_format != dc.out_audio_format); try { - auto result = decoder.convert->Convert({data, length}); + auto result = convert->Convert({data, length}); data = result.data; length = result.size; } catch (const std::runtime_error &e) { /* the PCM conversion has failed - stop playback, since we have no better way to bail out */ - decoder.error = std::current_exception(); + error = std::current_exception(); return DecoderCommand::STOP; } } else { @@ -503,10 +498,9 @@ decoder_data(DecoderClient &client, } while (length > 0) { - MusicChunk *chunk; bool full; - chunk = decoder.GetChunk(); + auto *chunk = GetChunk(); if (chunk == nullptr) { assert(dc.command != DecoderCommand::NONE); return dc.command; @@ -514,12 +508,12 @@ decoder_data(DecoderClient &client, const auto dest = chunk->Write(dc.out_audio_format, - SongTime::FromS(decoder.timestamp) - + SongTime::FromS(timestamp) - dc.song->GetStartTime(), kbit_rate); if (dest.IsEmpty()) { /* the chunk is full, flush it */ - decoder.FlushChunk(); + FlushChunk(); continue; } @@ -534,17 +528,17 @@ decoder_data(DecoderClient &client, full = chunk->Expand(dc.out_audio_format, nbytes); if (full) { /* the chunk is full, flush it */ - decoder.FlushChunk(); + FlushChunk(); } data = (const uint8_t *)data + nbytes; length -= nbytes; - decoder.timestamp += (double)nbytes / + timestamp += (double)nbytes / dc.out_audio_format.GetTimeToSize(); if (dc.end_time.IsPositive() && - decoder.timestamp >= dc.end_time.ToDoubleS()) + timestamp >= dc.end_time.ToDoubleS()) /* the end of this range has been reached: stop decoding */ return DecoderCommand::STOP; @@ -554,11 +548,8 @@ decoder_data(DecoderClient &client, } DecoderCommand -decoder_tag(DecoderClient &client, InputStream *is, - Tag &&tag) +Decoder::SubmitTag(InputStream *is, Tag &&tag) { - auto &decoder = (Decoder &)client; - gcc_unused const DecoderControl &dc = decoder.dc; DecoderCommand cmd; assert(dc.state == DecoderState::DECODE); @@ -566,16 +557,16 @@ decoder_tag(DecoderClient &client, InputStream *is, /* save the tag */ - delete decoder.decoder_tag; - decoder.decoder_tag = new Tag(std::move(tag)); + delete decoder_tag; + decoder_tag = new Tag(std::move(tag)); /* check for a new stream tag */ - update_stream_tag(decoder, is); + update_stream_tag(*this, is); /* check if we're seeking */ - if (decoder_prepare_initial_seek(decoder)) + if (decoder_prepare_initial_seek(*this)) /* during initial seek, no music chunk must be created until seeking is finished; skip the rest of the function here */ @@ -583,28 +574,24 @@ decoder_tag(DecoderClient &client, InputStream *is, /* send tag to music pipe */ - if (decoder.stream_tag != nullptr) { + if (stream_tag != nullptr) { /* merge with tag from input stream */ Tag *merged; - merged = Tag::Merge(*decoder.stream_tag, - *decoder.decoder_tag); - cmd = do_send_tag(decoder, *merged); + merged = Tag::Merge(*stream_tag, *decoder_tag); + cmd = do_send_tag(*this, *merged); delete merged; } else /* send only the decoder tag */ - cmd = do_send_tag(decoder, *decoder.decoder_tag); + cmd = do_send_tag(*this, *decoder_tag); return cmd; } void -decoder_replay_gain(DecoderClient &client, - const ReplayGainInfo *replay_gain_info) +Decoder::SubmitReplayGain(const ReplayGainInfo *new_replay_gain_info) { - auto &decoder = (Decoder &)client; - - if (replay_gain_info != nullptr) { + if (new_replay_gain_info != nullptr) { static unsigned serial; if (++serial == 0) serial = 1; @@ -614,32 +601,29 @@ decoder_replay_gain(DecoderClient &client, if (rgm != REPLAY_GAIN_ALBUM) rgm = REPLAY_GAIN_TRACK; - const auto &tuple = replay_gain_info->tuples[rgm]; + const auto &tuple = new_replay_gain_info->tuples[rgm]; const auto scale = tuple.CalculateScale(replay_gain_preamp, replay_gain_missing_preamp, replay_gain_limit); - decoder.dc.replay_gain_db = 20.0 * log10f(scale); + dc.replay_gain_db = 20.0 * log10f(scale); } - decoder.replay_gain_info = *replay_gain_info; - decoder.replay_gain_serial = serial; + replay_gain_info = *new_replay_gain_info; + replay_gain_serial = serial; - if (decoder.current_chunk != nullptr) { + if (current_chunk != nullptr) { /* flush the current chunk because the new replay gain values affect the following samples */ - decoder.FlushChunk(); + FlushChunk(); } } else - decoder.replay_gain_serial = 0; + replay_gain_serial = 0; } void -decoder_mixramp(DecoderClient &client, MixRampInfo &&mix_ramp) +Decoder::SubmitMixRamp(MixRampInfo &&mix_ramp) { - auto &decoder = (Decoder &)client; - DecoderControl &dc = decoder.dc; - dc.SetMixRamp(std::move(mix_ramp)); } diff --git a/src/decoder/DecoderAPI.hxx b/src/decoder/DecoderAPI.hxx index 5f682e81c..f2d010c16 100644 --- a/src/decoder/DecoderAPI.hxx +++ b/src/decoder/DecoderAPI.hxx @@ -104,73 +104,4 @@ decoder_read_full(DecoderClient *decoder, InputStream &is, bool decoder_skip(DecoderClient *decoder, InputStream &is, size_t size); -/** - * Sets the time stamp for the next data chunk [seconds]. The MPD - * core automatically counts it up, and a decoder plugin only needs to - * use this function if it thinks that adding to the time stamp based - * on the buffer size won't work. - */ -void -decoder_timestamp(DecoderClient &decoder, double t); - -/** - * This function is called by the decoder plugin when it has - * successfully decoded block of input data. - * - * @param decoder the decoder object - * @param is an input stream which is buffering while we are waiting - * for the player - * @param data the source buffer - * @param length the number of bytes in the buffer - * @return the current command, or DecoderCommand::NONE if there is no - * command pending - */ -DecoderCommand -decoder_data(DecoderClient &decoder, InputStream *is, - const void *data, size_t length, - uint16_t kbit_rate); - -static inline DecoderCommand -decoder_data(DecoderClient &decoder, InputStream &is, - const void *data, size_t length, - uint16_t kbit_rate) -{ - return decoder_data(decoder, &is, data, length, kbit_rate); -} - -/** - * This function is called by the decoder plugin when it has - * successfully decoded a tag. - * - * @param is an input stream which is buffering while we are waiting - * for the player - * @param tag the tag to send - * @return the current command, or DecoderCommand::NONE if there is no - * command pending - */ -DecoderCommand -decoder_tag(DecoderClient &decoder, InputStream *is, Tag &&tag); - -static inline DecoderCommand -decoder_tag(DecoderClient &decoder, InputStream &is, Tag &&tag) -{ - return decoder_tag(decoder, &is, std::move(tag)); -} - -/** - * Set replay gain values for the following chunks. - * - * @param replay_gain_info the replay_gain_info object; may be nullptr - * to invalidate the previous replay gain values - */ -void -decoder_replay_gain(DecoderClient &decoder, - const ReplayGainInfo *replay_gain_info); - -/** - * Store MixRamp tags. - */ -void -decoder_mixramp(DecoderClient &decoder, MixRampInfo &&mix_ramp); - #endif diff --git a/src/decoder/DecoderInternal.hxx b/src/decoder/DecoderInternal.hxx index b6801e758..61576bd32 100644 --- a/src/decoder/DecoderInternal.hxx +++ b/src/decoder/DecoderInternal.hxx @@ -124,6 +124,13 @@ struct Decoder final : DecoderClient { SongTime GetSeekTime() override; uint64_t GetSeekFrame() override; void SeekError() override; + void SubmitTimestamp(double t) override; + DecoderCommand SubmitData(InputStream *is, + const void *data, size_t length, + uint16_t kbit_rate) override; + DecoderCommand SubmitTag(InputStream *is, Tag &&tag) override ; + void SubmitReplayGain(const ReplayGainInfo *replay_gain_info) override; + void SubmitMixRamp(MixRampInfo &&mix_ramp) override; }; #endif diff --git a/src/decoder/DecoderThread.cxx b/src/decoder/DecoderThread.cxx index 61c02f558..2d42c5763 100644 --- a/src/decoder/DecoderThread.cxx +++ b/src/decoder/DecoderThread.cxx @@ -245,14 +245,14 @@ decoder_run_stream_fallback(Decoder &decoder, InputStream &is) /** * Attempt to load replay gain data, and pass it to - * decoder_replay_gain(). + * DecoderClient::SubmitReplayGain(). */ static void -LoadReplayGain(Decoder &decoder, InputStream &is) +LoadReplayGain(DecoderClient &client, InputStream &is) { ReplayGainInfo info; if (replay_gain_ape_read(is, info)) - decoder_replay_gain(decoder, &info); + client.SubmitReplayGain(&info); } /** diff --git a/src/decoder/plugins/AdPlugDecoderPlugin.cxx b/src/decoder/plugins/AdPlugDecoderPlugin.cxx index d3077ce5e..4a43cc64b 100644 --- a/src/decoder/plugins/AdPlugDecoderPlugin.cxx +++ b/src/decoder/plugins/AdPlugDecoderPlugin.cxx @@ -73,9 +73,9 @@ adplug_file_decode(DecoderClient &client, Path path_fs) int16_t buffer[2048]; constexpr unsigned frames_per_buffer = ARRAY_SIZE(buffer) / 2; opl.update(buffer, frames_per_buffer); - cmd = decoder_data(client, nullptr, - buffer, sizeof(buffer), - 0); + cmd = client.SubmitData(nullptr, + buffer, sizeof(buffer), + 0); } while (cmd == DecoderCommand::NONE); delete player; diff --git a/src/decoder/plugins/AudiofileDecoderPlugin.cxx b/src/decoder/plugins/AudiofileDecoderPlugin.cxx index 552116673..d664fa6e0 100644 --- a/src/decoder/plugins/AudiofileDecoderPlugin.cxx +++ b/src/decoder/plugins/AudiofileDecoderPlugin.cxx @@ -223,9 +223,9 @@ audiofile_stream_decode(DecoderClient &client, InputStream &is) if (nframes <= 0) break; - cmd = decoder_data(client, nullptr, - chunk, nframes * frame_size, - kbit_rate); + cmd = client.SubmitData(nullptr, + chunk, nframes * frame_size, + kbit_rate); if (cmd == DecoderCommand::SEEK) { AFframecount frame = client.GetSeekFrame(); diff --git a/src/decoder/plugins/DsdiffDecoderPlugin.cxx b/src/decoder/plugins/DsdiffDecoderPlugin.cxx index 4f705cc30..615b0010c 100644 --- a/src/decoder/plugins/DsdiffDecoderPlugin.cxx +++ b/src/decoder/plugins/DsdiffDecoderPlugin.cxx @@ -408,8 +408,8 @@ dsdiff_decode_chunk(DecoderClient &client, InputStream &is, if (lsbitfirst) bit_reverse_buffer(buffer, buffer + nbytes); - cmd = decoder_data(client, is, buffer, nbytes, - sample_rate / 1000); + cmd = client.SubmitData(is, buffer, nbytes, + sample_rate / 1000); } return true; diff --git a/src/decoder/plugins/DsfDecoderPlugin.cxx b/src/decoder/plugins/DsfDecoderPlugin.cxx index e34144883..02d67ca05 100644 --- a/src/decoder/plugins/DsfDecoderPlugin.cxx +++ b/src/decoder/plugins/DsfDecoderPlugin.cxx @@ -289,9 +289,9 @@ dsf_decode_chunk(DecoderClient &client, InputStream &is, uint8_t interleaved_buffer[MAX_CHANNELS * DSF_BLOCK_SIZE]; InterleaveDsfBlock(interleaved_buffer, buffer, channels); - cmd = decoder_data(client, is, - interleaved_buffer, block_size, - sample_rate / 1000); + cmd = client.SubmitData(is, + interleaved_buffer, block_size, + sample_rate / 1000); ++i; } diff --git a/src/decoder/plugins/FaadDecoderPlugin.cxx b/src/decoder/plugins/FaadDecoderPlugin.cxx index 8dc0d2d95..236b260f3 100644 --- a/src/decoder/plugins/FaadDecoderPlugin.cxx +++ b/src/decoder/plugins/FaadDecoderPlugin.cxx @@ -393,9 +393,9 @@ faad_stream_decode(DecoderClient &client, InputStream &is, /* send PCM samples to MPD */ - cmd = decoder_data(client, is, decoded, - (size_t)frame_info.samples * 2, - bit_rate); + cmd = client.SubmitData(is, decoded, + (size_t)frame_info.samples * 2, + bit_rate); } while (cmd != DecoderCommand::STOP); } diff --git a/src/decoder/plugins/FfmpegDecoderPlugin.cxx b/src/decoder/plugins/FfmpegDecoderPlugin.cxx index 57c86c549..d6f8f5e72 100644 --- a/src/decoder/plugins/FfmpegDecoderPlugin.cxx +++ b/src/decoder/plugins/FfmpegDecoderPlugin.cxx @@ -218,7 +218,8 @@ PtsToPcmFrame(uint64_t pts, const AVStream &stream, } /** - * Invoke decoder_data() with the contents of an #AVFrame. + * Invoke DecoderClient::SubmitData() with the contents of an + * #AVFrame. */ static DecoderCommand FfmpegSendFrame(DecoderClient &client, InputStream &is, @@ -250,9 +251,9 @@ FfmpegSendFrame(DecoderClient &client, InputStream &is, skip_bytes = 0; } - return decoder_data(client, is, - output_buffer.data, output_buffer.size, - codec_context.bit_rate / 1000); + return client.SubmitData(is, + output_buffer.data, output_buffer.size, + codec_context.bit_rate / 1000); } #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 37, 0) @@ -330,9 +331,8 @@ ffmpeg_send_packet(DecoderClient &client, InputStream &is, if (cur_frame < min_frame) skip_bytes = pcm_frame_size * (min_frame - cur_frame); } else - decoder_timestamp(client, - FfmpegTimeToDouble(pts, - stream.time_base)); + client.SubmitTimestamp(FfmpegTimeToDouble(pts, + stream.time_base)); } #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 37, 0) @@ -540,10 +540,10 @@ FfmpegParseMetaData(DecoderClient &client, FfmpegParseMetaData(format_context, audio_stream, rg, mr); if (rg.IsDefined()) - decoder_replay_gain(client, &rg); + client.SubmitReplayGain(&rg); if (mr.IsDefined()) - decoder_mixramp(client, std::move(mr)); + client.SubmitMixRamp(std::move(mr)); } static void @@ -576,7 +576,7 @@ FfmpegScanTag(const AVFormatContext &format_context, int audio_stream, /** * Check if a new stream tag was received and pass it to - * decoder_tag(). + * DecoderClient::SubmitTag(). */ static void FfmpegCheckTag(DecoderClient &client, InputStream &is, @@ -593,7 +593,7 @@ FfmpegCheckTag(DecoderClient &client, InputStream &is, TagBuilder tag; FfmpegScanTag(format_context, audio_stream, tag); if (!tag.IsEmpty()) - decoder_tag(client, is, tag.Commit()); + client.SubmitTag(is, tag.Commit()); } #endif diff --git a/src/decoder/plugins/FlacCommon.cxx b/src/decoder/plugins/FlacCommon.cxx index 59d160e65..024a1c8f8 100644 --- a/src/decoder/plugins/FlacCommon.cxx +++ b/src/decoder/plugins/FlacCommon.cxx @@ -77,9 +77,9 @@ FlacDecoder::OnVorbisComment(const FLAC__StreamMetadata_VorbisComment &vc) { ReplayGainInfo rgi; if (flac_parse_replay_gain(rgi, vc)) - decoder_replay_gain(*GetClient(), &rgi); + GetClient()->SubmitReplayGain(&rgi); - decoder_mixramp(*GetClient(), flac_parse_mixramp(vc)); + GetClient()->SubmitMixRamp(flac_parse_mixramp(vc)); tag = flac_vorbis_comments_to_tag(&vc); } @@ -148,9 +148,9 @@ FlacDecoder::OnWrite(const FLAC__Frame &frame, unsigned bit_rate = nbytes * 8 * frame.header.sample_rate / (1000 * frame.header.blocksize); - auto cmd = decoder_data(*GetClient(), GetInputStream(), - data.data, data.size, - bit_rate); + auto cmd = GetClient()->SubmitData(GetInputStream(), + data.data, data.size, + bit_rate); switch (cmd) { case DecoderCommand::NONE: case DecoderCommand::START: diff --git a/src/decoder/plugins/FlacDecoderPlugin.cxx b/src/decoder/plugins/FlacDecoderPlugin.cxx index e865fee9d..ae3b14e48 100644 --- a/src/decoder/plugins/FlacDecoderPlugin.cxx +++ b/src/decoder/plugins/FlacDecoderPlugin.cxx @@ -147,8 +147,8 @@ flac_decoder_loop(FlacDecoder *data, FLAC__StreamDecoder *flac_dec) while (true) { DecoderCommand cmd; if (!data->tag.IsEmpty()) { - cmd = decoder_tag(client, data->GetInputStream(), - std::move(data->tag)); + cmd = client.SubmitTag(data->GetInputStream(), + std::move(data->tag)); data->tag.Clear(); } else cmd = client.GetCommand(); diff --git a/src/decoder/plugins/FluidsynthDecoderPlugin.cxx b/src/decoder/plugins/FluidsynthDecoderPlugin.cxx index 9a64a8013..51330ae21 100644 --- a/src/decoder/plugins/FluidsynthDecoderPlugin.cxx +++ b/src/decoder/plugins/FluidsynthDecoderPlugin.cxx @@ -176,8 +176,7 @@ fluidsynth_file_decode(DecoderClient &client, Path path_fs) if (ret != 0) break; - cmd = decoder_data(client, nullptr, buffer, sizeof(buffer), - 0); + cmd = client.SubmitData(nullptr, buffer, sizeof(buffer), 0); if (cmd != DecoderCommand::NONE) break; } diff --git a/src/decoder/plugins/GmeDecoderPlugin.cxx b/src/decoder/plugins/GmeDecoderPlugin.cxx index 133e4a628..dd7d58a73 100644 --- a/src/decoder/plugins/GmeDecoderPlugin.cxx +++ b/src/decoder/plugins/GmeDecoderPlugin.cxx @@ -190,7 +190,7 @@ gme_file_decode(DecoderClient &client, Path path_fs) return; } - cmd = decoder_data(client, nullptr, buf, sizeof(buf), 0); + cmd = client.SubmitData(nullptr, buf, sizeof(buf), 0); if (cmd == DecoderCommand::SEEK) { unsigned where = client.GetSeekTime().ToMS(); gme_err = gme_seek(emu, where); diff --git a/src/decoder/plugins/MadDecoderPlugin.cxx b/src/decoder/plugins/MadDecoderPlugin.cxx index 19d462464..729decb37 100644 --- a/src/decoder/plugins/MadDecoderPlugin.cxx +++ b/src/decoder/plugins/MadDecoderPlugin.cxx @@ -182,13 +182,14 @@ struct MadDecoder { void UpdateTimerNextFrame(); /** - * Sends the synthesized current frame via decoder_data(). + * Sends the synthesized current frame via + * DecoderClient::SubmitData(). */ DecoderCommand SendPCM(unsigned i, unsigned pcm_length); /** * Synthesize the current frame and send it via - * decoder_data(). + * DecoderClient::SubmitData(). */ DecoderCommand SyncAndSend(); @@ -361,11 +362,11 @@ MadDecoder::ParseId3(size_t tagsize, Tag **mpd_tag) ReplayGainInfo rgi; if (parse_id3_replay_gain_info(rgi, id3_tag)) { - decoder_replay_gain(*client, &rgi); + client->SubmitReplayGain(&rgi); found_replay_gain = true; } - decoder_mixramp(*client, parse_id3_mixramp(id3_tag)); + client->SubmitMixRamp(parse_id3_mixramp(id3_tag)); } id3_tag_delete(id3_tag); @@ -806,7 +807,7 @@ MadDecoder::DecodeFirstFrame(Tag **tag) rgi.Clear(); rgi.tuples[REPLAY_GAIN_TRACK].gain = lame.track_gain; rgi.tuples[REPLAY_GAIN_TRACK].peak = lame.peak; - decoder_replay_gain(*client, &rgi); + client->SubmitReplayGain(&rgi); } } } @@ -903,9 +904,9 @@ MadDecoder::SendPCM(unsigned i, unsigned pcm_length) MAD_NCHANNELS(&frame.header)); num_samples *= MAD_NCHANNELS(&frame.header); - auto cmd = decoder_data(*client, input_stream, output_buffer, - sizeof(output_buffer[0]) * num_samples, - bit_rate / 1000); + auto cmd = client->SubmitData(input_stream, output_buffer, + sizeof(output_buffer[0]) * num_samples, + bit_rate / 1000); if (cmd != DecoderCommand::NONE) return cmd; } @@ -1010,8 +1011,8 @@ MadDecoder::Read() ret = DecodeNextFrameHeader(&tag); if (tag != nullptr) { - decoder_tag(*client, input_stream, - std::move(*tag)); + client->SubmitTag(input_stream, + std::move(*tag)); delete tag; } } while (ret == DECODE_CONT); @@ -1057,7 +1058,7 @@ mp3_decode(DecoderClient &client, InputStream &input_stream) data.total_time); if (tag != nullptr) { - decoder_tag(client, input_stream, std::move(*tag)); + client.SubmitTag(input_stream, std::move(*tag)); delete tag; } diff --git a/src/decoder/plugins/MikmodDecoderPlugin.cxx b/src/decoder/plugins/MikmodDecoderPlugin.cxx index f91be1726..c01408ccf 100644 --- a/src/decoder/plugins/MikmodDecoderPlugin.cxx +++ b/src/decoder/plugins/MikmodDecoderPlugin.cxx @@ -177,7 +177,7 @@ mikmod_decoder_file_decode(DecoderClient &client, Path path_fs) DecoderCommand cmd = DecoderCommand::NONE; while (cmd == DecoderCommand::NONE && Player_Active()) { ret = VC_WriteBytes(buffer, sizeof(buffer)); - cmd = decoder_data(client, nullptr, buffer, ret, 0); + cmd = client.SubmitData(nullptr, buffer, ret, 0); } Player_Stop(); diff --git a/src/decoder/plugins/ModplugDecoderPlugin.cxx b/src/decoder/plugins/ModplugDecoderPlugin.cxx index b7e3e5cc0..7e114c05a 100644 --- a/src/decoder/plugins/ModplugDecoderPlugin.cxx +++ b/src/decoder/plugins/ModplugDecoderPlugin.cxx @@ -160,9 +160,9 @@ mod_decode(DecoderClient &client, InputStream &is) if (ret <= 0) break; - cmd = decoder_data(client, nullptr, - audio_buffer, ret, - 0); + cmd = client.SubmitData(nullptr, + audio_buffer, ret, + 0); if (cmd == DecoderCommand::SEEK) { ModPlug_Seek(f, client.GetSeekTime().ToMS()); diff --git a/src/decoder/plugins/MpcdecDecoderPlugin.cxx b/src/decoder/plugins/MpcdecDecoderPlugin.cxx index 9bfb1f3f1..2922daca9 100644 --- a/src/decoder/plugins/MpcdecDecoderPlugin.cxx +++ b/src/decoder/plugins/MpcdecDecoderPlugin.cxx @@ -172,7 +172,7 @@ mpcdec_decode(DecoderClient &client, InputStream &is) rgi.tuples[REPLAY_GAIN_TRACK].gain = MPC_OLD_GAIN_REF - (info.gain_title / 256.); rgi.tuples[REPLAY_GAIN_TRACK].peak = pow(10, info.peak_title / 256. / 20) / 32767; - decoder_replay_gain(client, &rgi); + client.SubmitReplayGain(&rgi); client.Ready(audio_format, is.IsSeekable(), SongTime::FromS(mpc_streaminfo_get_length(&info))); @@ -213,9 +213,9 @@ mpcdec_decode(DecoderClient &client, InputStream &is) long bit_rate = unsigned(frame.bits) * audio_format.sample_rate / (1000 * frame.samples); - cmd = decoder_data(client, is, - chunk, ret * sizeof(chunk[0]), - bit_rate); + cmd = client.SubmitData(is, + chunk, ret * sizeof(chunk[0]), + bit_rate); } while (cmd != DecoderCommand::STOP); mpc_demux_exit(demux); diff --git a/src/decoder/plugins/Mpg123DecoderPlugin.cxx b/src/decoder/plugins/Mpg123DecoderPlugin.cxx index ffd899dad..ddfcb153e 100644 --- a/src/decoder/plugins/Mpg123DecoderPlugin.cxx +++ b/src/decoder/plugins/Mpg123DecoderPlugin.cxx @@ -129,7 +129,7 @@ mpd_mpg123_id3v2_tag(DecoderClient &client, const mpg123_id3v2 &id3v2) for (size_t i = 0, n = id3v2.comments; i < n; ++i) AddTagItem(tag, TAG_COMMENT, id3v2.comment_list[i].text); - decoder_tag(client, nullptr, tag.Commit()); + client.SubmitTag(nullptr, tag.Commit()); } static void @@ -154,10 +154,10 @@ mpd_mpg123_id3v2_extras(DecoderClient &client, const mpg123_id3v2 &id3v2) } if (found_replay_gain) - decoder_replay_gain(client, &replay_gain); + client.SubmitReplayGain(&replay_gain); if (found_mixramp) - decoder_mixramp(client, std::move(mix_ramp)); + client.SubmitMixRamp(std::move(mix_ramp)); } static void @@ -257,7 +257,7 @@ mpd_mpg123_file_decode(DecoderClient &client, Path path_fs) /* send to MPD */ - cmd = decoder_data(client, nullptr, buffer, nbytes, info.bitrate); + cmd = client.SubmitData(nullptr, buffer, nbytes, info.bitrate); if (cmd == DecoderCommand::SEEK) { off_t c = client.GetSeekFrame(); @@ -266,7 +266,7 @@ mpd_mpg123_file_decode(DecoderClient &client, Path path_fs) client.SeekError(); else { client.CommandFinished(); - decoder_timestamp(client, c/(double)audio_format.sample_rate); + client.SubmitTimestamp(c / (double)audio_format.sample_rate); } cmd = DecoderCommand::NONE; diff --git a/src/decoder/plugins/OpusDecoderPlugin.cxx b/src/decoder/plugins/OpusDecoderPlugin.cxx index 78bacb1db..0f8dcc2a2 100644 --- a/src/decoder/plugins/OpusDecoderPlugin.cxx +++ b/src/decoder/plugins/OpusDecoderPlugin.cxx @@ -212,10 +212,10 @@ MPDOpusDecoder::HandleTags(const ogg_packet &packet) &rgi, add_tag_handler, &tag_builder) && !tag_builder.IsEmpty()) { - decoder_replay_gain(client, &rgi); + client.SubmitReplayGain(&rgi); Tag tag = tag_builder.Commit(); - auto cmd = decoder_tag(client, input_stream, std::move(tag)); + auto cmd = client.SubmitTag(input_stream, std::move(tag)); if (cmd != DecoderCommand::NONE) throw cmd; } @@ -237,16 +237,15 @@ MPDOpusDecoder::HandleAudio(const ogg_packet &packet) if (nframes > 0) { const size_t nbytes = nframes * frame_size; - auto cmd = decoder_data(client, input_stream, - output_buffer, nbytes, - 0); + auto cmd = client.SubmitData(input_stream, + output_buffer, nbytes, + 0); if (cmd != DecoderCommand::NONE) throw cmd; if (packet.granulepos > 0) - decoder_timestamp(client, - double(packet.granulepos) - / opus_sample_rate); + client.SubmitTimestamp(double(packet.granulepos) + / opus_sample_rate); } } diff --git a/src/decoder/plugins/PcmDecoderPlugin.cxx b/src/decoder/plugins/PcmDecoderPlugin.cxx index 4215d62ba..7c93b87fb 100644 --- a/src/decoder/plugins/PcmDecoderPlugin.cxx +++ b/src/decoder/plugins/PcmDecoderPlugin.cxx @@ -154,7 +154,8 @@ pcm_stream_decode(DecoderClient &client, InputStream &is) auto r = buffer.Read(); /* round down to the nearest frame size, because we - must not pass partial frames to decoder_data() */ + must not pass partial frames to + DecoderClient::SubmitData() */ r.size -= r.size % frame_size; buffer.Consume(r.size); @@ -165,7 +166,7 @@ pcm_stream_decode(DecoderClient &client, InputStream &is) (uint16_t *)(r.data + r.size)); cmd = !r.IsEmpty() - ? decoder_data(client, is, r.data, r.size, 0) + ? client.SubmitData(is, r.data, r.size, 0) : client.GetCommand(); if (cmd == DecoderCommand::SEEK) { uint64_t frame = client.GetSeekFrame(); diff --git a/src/decoder/plugins/SidplayDecoderPlugin.cxx b/src/decoder/plugins/SidplayDecoderPlugin.cxx index 53799f6a3..b3b122ac3 100644 --- a/src/decoder/plugins/SidplayDecoderPlugin.cxx +++ b/src/decoder/plugins/SidplayDecoderPlugin.cxx @@ -366,9 +366,9 @@ sidplay_file_decode(DecoderClient &client, Path path_fs) const size_t nbytes = result; #endif - decoder_timestamp(client, (double)player.time() / timebase); + client.SubmitTimestamp((double)player.time() / timebase); - cmd = decoder_data(client, nullptr, buffer, nbytes, 0); + cmd = client.SubmitData(nullptr, buffer, nbytes, 0); if (cmd == DecoderCommand::SEEK) { unsigned data_time = player.time(); diff --git a/src/decoder/plugins/SndfileDecoderPlugin.cxx b/src/decoder/plugins/SndfileDecoderPlugin.cxx index 1a2b1cc8c..674573227 100644 --- a/src/decoder/plugins/SndfileDecoderPlugin.cxx +++ b/src/decoder/plugins/SndfileDecoderPlugin.cxx @@ -221,9 +221,9 @@ sndfile_stream_decode(DecoderClient &client, InputStream &is) if (num_frames <= 0) break; - cmd = decoder_data(client, is, - buffer, num_frames * frame_size, - 0); + cmd = client.SubmitData(is, + buffer, num_frames * frame_size, + 0); if (cmd == DecoderCommand::SEEK) { sf_count_t c = client.GetSeekFrame(); c = sf_seek(sf, c, SEEK_SET); diff --git a/src/decoder/plugins/VorbisDecoderPlugin.cxx b/src/decoder/plugins/VorbisDecoderPlugin.cxx index 41e13906d..a73f0e995 100644 --- a/src/decoder/plugins/VorbisDecoderPlugin.cxx +++ b/src/decoder/plugins/VorbisDecoderPlugin.cxx @@ -156,7 +156,7 @@ vorbis_send_comments(DecoderClient &client, InputStream &is, if (!tag) return; - decoder_tag(client, is, std::move(*tag)); + client.SubmitTag(is, std::move(*tag)); delete tag; } @@ -211,9 +211,9 @@ VorbisDecoder::SubmitSomePcm() vorbis_synthesis_read(&dsp, n_frames); const size_t nbytes = n_frames * frame_size; - auto cmd = decoder_data(client, input_stream, - buffer, nbytes, - 0); + auto cmd = client.SubmitData(input_stream, + buffer, nbytes, + 0); if (cmd != DecoderCommand::NONE) throw cmd; @@ -252,7 +252,7 @@ VorbisDecoder::OnOggPacket(const ogg_packet &_packet) ReplayGainInfo rgi; if (vorbis_comments_to_replay_gain(rgi, vc.user_comments)) - decoder_replay_gain(client, &rgi); + client.SubmitReplayGain(&rgi); } else { if (!dsp_initialized) { dsp_initialized = true; @@ -277,8 +277,7 @@ VorbisDecoder::OnOggPacket(const ogg_packet &_packet) #ifndef HAVE_TREMOR if (packet.granulepos > 0) - decoder_timestamp(client, - vorbis_granule_time(&dsp, packet.granulepos)); + client.SubmitTimestamp(vorbis_granule_time(&dsp, packet.granulepos)); #endif } } diff --git a/src/decoder/plugins/WavpackDecoderPlugin.cxx b/src/decoder/plugins/WavpackDecoderPlugin.cxx index 55d0376c2..685c1b66d 100644 --- a/src/decoder/plugins/WavpackDecoderPlugin.cxx +++ b/src/decoder/plugins/WavpackDecoderPlugin.cxx @@ -196,9 +196,9 @@ wavpack_decode(DecoderClient &client, WavpackContext *wpc, bool can_seek) format_samples(bytes_per_sample, chunk, samples_got * audio_format.channels); - cmd = decoder_data(client, nullptr, chunk, - samples_got * output_sample_size, - bitrate); + cmd = client.SubmitData(nullptr, chunk, + samples_got * output_sample_size, + bitrate); } } @@ -563,7 +563,7 @@ wavpack_filedecode(DecoderClient &client, Path path_fs) ReplayGainInfo rgi; if (wavpack_replaygain(rgi, wpc)) - decoder_replay_gain(client, &rgi); + client.SubmitReplayGain(&rgi); wavpack_decode(client, wpc, true); diff --git a/src/decoder/plugins/WildmidiDecoderPlugin.cxx b/src/decoder/plugins/WildmidiDecoderPlugin.cxx index 4f3de8018..a8db10dec 100644 --- a/src/decoder/plugins/WildmidiDecoderPlugin.cxx +++ b/src/decoder/plugins/WildmidiDecoderPlugin.cxx @@ -75,7 +75,7 @@ wildmidi_output(DecoderClient &client, midi *wm) if (length <= 0) return DecoderCommand::STOP; - return decoder_data(client, nullptr, buffer, length, 0); + return client.SubmitData(nullptr, buffer, length, 0); } static void diff --git a/test/FakeDecoderAPI.cxx b/test/FakeDecoderAPI.cxx index ad3d37071..3c4539af1 100644 --- a/test/FakeDecoderAPI.cxx +++ b/test/FakeDecoderAPI.cxx @@ -127,16 +127,14 @@ decoder_skip(DecoderClient *client, InputStream &is, size_t size) } void -decoder_timestamp(gcc_unused DecoderClient &client, - gcc_unused double t) +FakeDecoder::SubmitTimestamp(gcc_unused double t) { } DecoderCommand -decoder_data(gcc_unused DecoderClient &client, - gcc_unused InputStream *is, - const void *data, size_t datalen, - gcc_unused uint16_t kbit_rate) +FakeDecoder::SubmitData(gcc_unused InputStream *is, + const void *data, size_t datalen, + gcc_unused uint16_t kbit_rate) { static uint16_t prev_kbit_rate; if (kbit_rate != prev_kbit_rate) { @@ -149,9 +147,8 @@ decoder_data(gcc_unused DecoderClient &client, } DecoderCommand -decoder_tag(gcc_unused DecoderClient &client, - gcc_unused InputStream *is, - Tag &&tag) +FakeDecoder::SubmitTag(gcc_unused InputStream *is, + Tag &&tag) { fprintf(stderr, "TAG: duration=%f\n", tag.duration.ToDoubleS()); @@ -162,8 +159,7 @@ decoder_tag(gcc_unused DecoderClient &client, } void -decoder_replay_gain(gcc_unused DecoderClient &client, - const ReplayGainInfo *rgi) +FakeDecoder::SubmitReplayGain(const ReplayGainInfo *rgi) { const ReplayGainTuple *tuple = &rgi->tuples[REPLAY_GAIN_ALBUM]; if (tuple->IsDefined()) @@ -177,7 +173,7 @@ decoder_replay_gain(gcc_unused DecoderClient &client, } void -decoder_mixramp(gcc_unused DecoderClient &client, gcc_unused MixRampInfo &&mix_ramp) +FakeDecoder::SubmitMixRamp(gcc_unused MixRampInfo &&mix_ramp) { fprintf(stderr, "MixRamp: start='%s' end='%s'\n", mix_ramp.GetStart(), mix_ramp.GetEnd()); diff --git a/test/FakeDecoderAPI.hxx b/test/FakeDecoderAPI.hxx index b05e31404..d21d1615d 100644 --- a/test/FakeDecoderAPI.hxx +++ b/test/FakeDecoderAPI.hxx @@ -39,6 +39,13 @@ struct FakeDecoder final : DecoderClient { SongTime GetSeekTime() override; uint64_t GetSeekFrame() override; void SeekError() override; + void SubmitTimestamp(double t) override; + DecoderCommand SubmitData(InputStream *is, + const void *data, size_t length, + uint16_t kbit_rate) override; + DecoderCommand SubmitTag(InputStream *is, Tag &&tag) override ; + void SubmitReplayGain(const ReplayGainInfo *replay_gain_info) override; + void SubmitMixRamp(MixRampInfo &&mix_ramp) override; }; #endif