diff --git a/src/decoder/Bridge.cxx b/src/decoder/Bridge.cxx index b4d9fd076..98227a794 100644 --- a/src/decoder/Bridge.cxx +++ b/src/decoder/Bridge.cxx @@ -451,18 +451,18 @@ DecoderBridge::SubmitTimestamp(FloatDuration t) noexcept } DecoderCommand -DecoderBridge::SubmitData(InputStream *is, - const void *data, size_t length, - uint16_t kbit_rate) noexcept +DecoderBridge::SubmitAudio(InputStream *is, + std::span audio, + uint16_t kbit_rate) noexcept { assert(dc.state == DecoderState::DECODE); assert(dc.pipe != nullptr); - assert(length % dc.in_audio_format.GetFrameSize() == 0); + assert(audio.size() % dc.in_audio_format.GetFrameSize() == 0); DecoderCommand cmd = LockGetVirtualCommand(); if (cmd == DecoderCommand::STOP || cmd == DecoderCommand::SEEK || - length == 0) + audio.empty()) return cmd; assert(!initial_seek_pending); @@ -486,7 +486,7 @@ DecoderBridge::SubmitData(InputStream *is, cmd = DecoderCommand::NONE; const size_t frame_size = dc.in_audio_format.GetFrameSize(); - size_t data_frames = length / frame_size; + size_t data_frames = audio.size() / frame_size; if (dc.end_time.IsPositive()) { /* enforce the given end time */ @@ -501,7 +501,7 @@ DecoderBridge::SubmitData(InputStream *is, /* past the end of the range: truncate this data submission and stop the decoder */ data_frames = remaining_frames; - length = data_frames * frame_size; + audio = audio.first(data_frames * frame_size); cmd = DecoderCommand::STOP; } } @@ -510,9 +510,7 @@ DecoderBridge::SubmitData(InputStream *is, assert(dc.in_audio_format != dc.out_audio_format); try { - auto result = convert->Convert({(const std::byte *)data, length}); - data = result.data(); - length = result.size(); + audio = convert->Convert(audio); } catch (...) { /* the PCM conversion has failed - stop playback, since we have no better way to @@ -524,7 +522,7 @@ DecoderBridge::SubmitData(InputStream *is, assert(dc.in_audio_format == dc.out_audio_format); } - while (length > 0) { + while (!audio.empty()) { bool full; auto *chunk = GetChunk(); @@ -544,11 +542,11 @@ DecoderBridge::SubmitData(InputStream *is, continue; } - const size_t nbytes = std::min(dest.size(), length); + const size_t nbytes = std::min(dest.size(), audio.size()); /* copy the buffer */ - memcpy(dest.data(), data, nbytes); + memcpy(dest.data(), audio.data(), nbytes); /* expand the music pipe chunk */ @@ -558,8 +556,7 @@ DecoderBridge::SubmitData(InputStream *is, FlushChunk(); } - data = (const uint8_t *)data + nbytes; - length -= nbytes; + audio = audio.subspan(nbytes); timestamp += dc.out_audio_format.SizeToTime(nbytes); } diff --git a/src/decoder/Bridge.hxx b/src/decoder/Bridge.hxx index f29490793..bff5a10eb 100644 --- a/src/decoder/Bridge.hxx +++ b/src/decoder/Bridge.hxx @@ -177,9 +177,9 @@ public: size_t Read(InputStream &is, void *buffer, size_t length) noexcept override; void SubmitTimestamp(FloatDuration t) noexcept override; - DecoderCommand SubmitData(InputStream *is, - const void *data, size_t length, - uint16_t kbit_rate) noexcept override; + DecoderCommand SubmitAudio(InputStream *is, + std::span audio, + uint16_t kbit_rate) noexcept override; DecoderCommand SubmitTag(InputStream *is, Tag &&tag) noexcept override; void SubmitReplayGain(const ReplayGainInfo *replay_gain_info) noexcept override; void SubmitMixRamp(MixRampInfo &&mix_ramp) noexcept override; diff --git a/src/decoder/Client.hxx b/src/decoder/Client.hxx index 8f670885d..99e117737 100644 --- a/src/decoder/Client.hxx +++ b/src/decoder/Client.hxx @@ -24,7 +24,9 @@ #include "Chrono.hxx" #include "input/Ptr.hxx" +#include #include +#include struct AudioFormat; struct Tag; @@ -41,7 +43,7 @@ public: * that it has read the song's meta data. * * @param audio_format the audio format which is going to be - * sent to SubmitData() + * sent to SubmitAudio() * @param seekable true if the song is seekable * @param duration the total duration of this song; negative if * unknown @@ -128,14 +130,32 @@ public: * @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) noexcept = 0; + virtual DecoderCommand SubmitAudio(InputStream *is, + std::span audio, + uint16_t kbit_rate) noexcept = 0; - DecoderCommand SubmitData(InputStream &is, - const void *data, size_t length, - uint16_t kbit_rate) noexcept { - return SubmitData(&is, data, length, kbit_rate); + DecoderCommand SubmitAudio(InputStream &is, + std::span audio, + uint16_t kbit_rate) noexcept { + return SubmitAudio(&is, audio, kbit_rate); + } + + template + DecoderCommand SubmitAudio(InputStream *is, + std::span audio, + uint16_t kbit_rate) noexcept { + const std::span audio_bytes = + std::as_bytes(audio); + return SubmitAudio(is, audio_bytes, kbit_rate); + } + + template + DecoderCommand SubmitAudio(InputStream &is, + std::span audio, + uint16_t kbit_rate) noexcept { + const std::span audio_bytes = + std::as_bytes(audio); + return SubmitAudio(is, audio_bytes, kbit_rate); } /** diff --git a/src/decoder/plugins/AdPlugDecoderPlugin.cxx b/src/decoder/plugins/AdPlugDecoderPlugin.cxx index 07a761cfd..672cd2ebd 100644 --- a/src/decoder/plugins/AdPlugDecoderPlugin.cxx +++ b/src/decoder/plugins/AdPlugDecoderPlugin.cxx @@ -71,9 +71,9 @@ adplug_file_decode(DecoderClient &client, Path path_fs) int16_t buffer[2048]; constexpr unsigned frames_per_buffer = std::size(buffer) / 2; opl.update(buffer, frames_per_buffer); - cmd = client.SubmitData(nullptr, - buffer, sizeof(buffer), - 0); + cmd = client.SubmitAudio(nullptr, + std::span{buffer}, + 0); } while (cmd == DecoderCommand::NONE); delete player; diff --git a/src/decoder/plugins/AudiofileDecoderPlugin.cxx b/src/decoder/plugins/AudiofileDecoderPlugin.cxx index b7f1b90e9..fd7e2f634 100644 --- a/src/decoder/plugins/AudiofileDecoderPlugin.cxx +++ b/src/decoder/plugins/AudiofileDecoderPlugin.cxx @@ -212,7 +212,7 @@ audiofile_stream_decode(DecoderClient &client, InputStream &is) const auto kbit_rate = (uint16_t) (is.GetSize() * uint64_t(8) / total_time.ToMS()); - const auto frame_size = (unsigned) + const auto frame_size = (std::size_t) afGetVirtualFrameSize(fh, AF_DEFAULT_TRACK, true); client.Ready(audio_format, true, total_time); @@ -226,9 +226,9 @@ audiofile_stream_decode(DecoderClient &client, InputStream &is) if (nframes <= 0) break; - cmd = client.SubmitData(nullptr, - chunk, nframes * frame_size, - kbit_rate); + cmd = client.SubmitAudio(nullptr, + std::span{chunk, std::size_t(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 54412af20..c548e3321 100644 --- a/src/decoder/plugins/DsdiffDecoderPlugin.cxx +++ b/src/decoder/plugins/DsdiffDecoderPlugin.cxx @@ -417,8 +417,8 @@ dsdiff_decode_chunk(DecoderClient &client, InputStream &is, if (lsbitfirst) bit_reverse_buffer(buffer, buffer + nbytes); - cmd = client.SubmitData(is, buffer, nbytes, - kbit_rate); + cmd = client.SubmitAudio(is, std::span{buffer, nbytes}, + kbit_rate); } return true; diff --git a/src/decoder/plugins/DsfDecoderPlugin.cxx b/src/decoder/plugins/DsfDecoderPlugin.cxx index 88268670d..ca29b7423 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 = client.SubmitData(is, - interleaved_buffer, block_size, - kbit_rate); + cmd = client.SubmitAudio(is, + std::span{interleaved_buffer, block_size}, + kbit_rate); ++i; } diff --git a/src/decoder/plugins/FaadDecoderPlugin.cxx b/src/decoder/plugins/FaadDecoderPlugin.cxx index 357043ca0..1089b4ab0 100644 --- a/src/decoder/plugins/FaadDecoderPlugin.cxx +++ b/src/decoder/plugins/FaadDecoderPlugin.cxx @@ -354,7 +354,7 @@ faad_stream_decode(DecoderClient &client, InputStream &is, /* decode it */ NeAACDecFrameInfo frame_info; - const void *const decoded = + const auto decoded = (const int16_t *) faad_decoder_decode(decoder, buffer, &frame_info); if (frame_info.error > 0) { @@ -391,9 +391,9 @@ faad_stream_decode(DecoderClient &client, InputStream &is, /* send PCM samples to MPD */ - cmd = client.SubmitData(is, decoded, - (size_t)frame_info.samples * 2, - bit_rate); + const std::span audio{decoded, (size_t)frame_info.samples}; + + cmd = client.SubmitAudio(is, audio, bit_rate); } while (cmd != DecoderCommand::STOP); } diff --git a/src/decoder/plugins/FfmpegDecoderPlugin.cxx b/src/decoder/plugins/FfmpegDecoderPlugin.cxx index 384e31fcc..009d90cdf 100644 --- a/src/decoder/plugins/FfmpegDecoderPlugin.cxx +++ b/src/decoder/plugins/FfmpegDecoderPlugin.cxx @@ -205,7 +205,7 @@ PtsToPcmFrame(uint64_t pts, const AVStream &stream, } /** - * Invoke DecoderClient::SubmitData() with the contents of an + * Invoke DecoderClient::SubmitAudio() with the contents of an * #AVFrame. */ static DecoderCommand @@ -227,9 +227,8 @@ FfmpegSendFrame(DecoderClient &client, InputStream *is, skip_bytes = 0; } - return client.SubmitData(is, - output_buffer.data(), output_buffer.size(), - codec_context.bit_rate / 1000); + return client.SubmitAudio(is, output_buffer, + codec_context.bit_rate / 1000); } static DecoderCommand diff --git a/src/decoder/plugins/FlacCommon.hxx b/src/decoder/plugins/FlacCommon.hxx index f5c5a5809..fbb8cfa3b 100644 --- a/src/decoder/plugins/FlacCommon.hxx +++ b/src/decoder/plugins/FlacCommon.hxx @@ -46,7 +46,7 @@ struct FlacDecoder : public FlacInput { /** * The kbit_rate parameter for the next - * DecoderBridge::SubmitData() call. + * DecoderBridge::SubmitAudio() call. */ uint16_t kbit_rate; @@ -62,7 +62,7 @@ struct FlacDecoder : public FlacInput { /** * Decoded PCM data obtained by our libFLAC write callback. - * If this is non-empty, then DecoderBridge::SubmitData() + * If this is non-empty, then DecoderBridge::SubmitAudio() * should be called. */ std::span chunk = {}; diff --git a/src/decoder/plugins/FlacDecoderPlugin.cxx b/src/decoder/plugins/FlacDecoderPlugin.cxx index d2e84b388..7a6d31034 100644 --- a/src/decoder/plugins/FlacDecoderPlugin.cxx +++ b/src/decoder/plugins/FlacDecoderPlugin.cxx @@ -152,10 +152,8 @@ FlacSubmitToClient(DecoderClient &client, FlacDecoder &d) noexcept } if (!d.chunk.empty()) { - auto cmd = client.SubmitData(d.GetInputStream(), - d.chunk.data(), - d.chunk.size(), - d.kbit_rate); + auto cmd = client.SubmitAudio(d.GetInputStream(), d.chunk, + d.kbit_rate); d.chunk = {}; if (cmd != DecoderCommand::NONE) return cmd; diff --git a/src/decoder/plugins/FluidsynthDecoderPlugin.cxx b/src/decoder/plugins/FluidsynthDecoderPlugin.cxx index e29fb6958..87adcb531 100644 --- a/src/decoder/plugins/FluidsynthDecoderPlugin.cxx +++ b/src/decoder/plugins/FluidsynthDecoderPlugin.cxx @@ -179,7 +179,7 @@ fluidsynth_file_decode(DecoderClient &client, Path path_fs) if (ret != 0) break; - cmd = client.SubmitData(nullptr, buffer, sizeof(buffer), 0); + cmd = client.SubmitAudio(nullptr, std::span{buffer}, 0); if (cmd != DecoderCommand::NONE) break; } diff --git a/src/decoder/plugins/GmeDecoderPlugin.cxx b/src/decoder/plugins/GmeDecoderPlugin.cxx index ab108b912..a7eb650fb 100644 --- a/src/decoder/plugins/GmeDecoderPlugin.cxx +++ b/src/decoder/plugins/GmeDecoderPlugin.cxx @@ -216,7 +216,7 @@ gme_file_decode(DecoderClient &client, Path path_fs) return; } - cmd = client.SubmitData(nullptr, buf, sizeof(buf), 0); + cmd = client.SubmitAudio(nullptr, std::span{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 3bb522d22..0e60bd0ba 100644 --- a/src/decoder/plugins/MadDecoderPlugin.cxx +++ b/src/decoder/plugins/MadDecoderPlugin.cxx @@ -185,13 +185,13 @@ private: /** * Sends the synthesized current frame via - * DecoderClient::SubmitData(). + * DecoderClient::SubmitAudio(). */ DecoderCommand SubmitPCM(size_t start, size_t n) noexcept; /** * Synthesize the current frame and send it via - * DecoderClient::SubmitData(). + * DecoderClient::SubmitAudio(). */ DecoderCommand SynthAndSubmit() noexcept; @@ -805,9 +805,9 @@ MadDecoder::SubmitPCM(size_t i, size_t pcm_length) noexcept MAD_NCHANNELS(&frame.header)); num_samples *= MAD_NCHANNELS(&frame.header); - return client->SubmitData(input_stream, output_buffer, - sizeof(output_buffer[0]) * num_samples, - frame.header.bitrate / 1000); + return client->SubmitAudio(input_stream, + std::span{output_buffer, num_samples}, + frame.header.bitrate / 1000); } inline DecoderCommand diff --git a/src/decoder/plugins/MikmodDecoderPlugin.cxx b/src/decoder/plugins/MikmodDecoderPlugin.cxx index f5f92fafd..867303e7a 100644 --- a/src/decoder/plugins/MikmodDecoderPlugin.cxx +++ b/src/decoder/plugins/MikmodDecoderPlugin.cxx @@ -171,7 +171,9 @@ 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 = client.SubmitData(nullptr, buffer, ret, 0); + cmd = client.SubmitAudio(nullptr, + std::span{buffer, std::size_t(ret)}, + 0); } Player_Stop(); diff --git a/src/decoder/plugins/ModplugDecoderPlugin.cxx b/src/decoder/plugins/ModplugDecoderPlugin.cxx index 834d30e5d..8b0b902b9 100644 --- a/src/decoder/plugins/ModplugDecoderPlugin.cxx +++ b/src/decoder/plugins/ModplugDecoderPlugin.cxx @@ -116,9 +116,9 @@ mod_decode(DecoderClient &client, InputStream &is) if (ret <= 0) break; - cmd = client.SubmitData(nullptr, - audio_buffer, ret, - 0); + cmd = client.SubmitAudio(nullptr, + std::span{audio_buffer, std::size_t(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 86c608e77..774808d7f 100644 --- a/src/decoder/plugins/MpcdecDecoderPlugin.cxx +++ b/src/decoder/plugins/MpcdecDecoderPlugin.cxx @@ -241,9 +241,9 @@ mpcdec_decode(DecoderClient &client, InputStream &is) long bit_rate = unsigned(frame.bits) * audio_format.sample_rate / (1000 * frame.samples); - cmd = client.SubmitData(is, - chunk, ret * sizeof(chunk[0]), - bit_rate); + cmd = client.SubmitAudio(is, + std::span{chunk, ret}, + bit_rate); } while (cmd != DecoderCommand::STOP); } diff --git a/src/decoder/plugins/Mpg123DecoderPlugin.cxx b/src/decoder/plugins/Mpg123DecoderPlugin.cxx index cf506b032..e8f82b5b9 100644 --- a/src/decoder/plugins/Mpg123DecoderPlugin.cxx +++ b/src/decoder/plugins/Mpg123DecoderPlugin.cxx @@ -253,7 +253,8 @@ mpd_mpg123_file_decode(DecoderClient &client, Path path_fs) /* send to MPD */ - cmd = client.SubmitData(nullptr, buffer, nbytes, info.bitrate); + cmd = client.SubmitAudio(nullptr, std::span{buffer, nbytes}, + info.bitrate); if (cmd == DecoderCommand::SEEK) { off_t c = client.GetSeekFrame(); diff --git a/src/decoder/plugins/OpenmptDecoderPlugin.cxx b/src/decoder/plugins/OpenmptDecoderPlugin.cxx index b079c0102..b766d64bd 100644 --- a/src/decoder/plugins/OpenmptDecoderPlugin.cxx +++ b/src/decoder/plugins/OpenmptDecoderPlugin.cxx @@ -69,7 +69,6 @@ static void mod_decode(DecoderClient &client, InputStream &is) { int ret; - char audio_buffer[OPENMPT_FRAME_SIZE]; const auto buffer = mod_loadfile(&openmpt_domain, &client, is); if (buffer == nullptr) { @@ -99,7 +98,8 @@ mod_decode(DecoderClient &client, InputStream &is) mod.ctl_set("render.resampler.emulate_amiga", std::to_string((unsigned)openmpt_emulate_amiga)); #endif - static constexpr AudioFormat audio_format(OPENMPT_SAMPLE_RATE, SampleFormat::FLOAT, 2); + static constexpr unsigned channels = 2; + static constexpr AudioFormat audio_format(OPENMPT_SAMPLE_RATE, SampleFormat::FLOAT, channels); assert(audio_format.IsValid()); client.Ready(audio_format, is.IsSeekable(), @@ -107,13 +107,16 @@ mod_decode(DecoderClient &client, InputStream &is) DecoderCommand cmd; do { - ret = mod.read_interleaved_stereo(OPENMPT_SAMPLE_RATE, OPENMPT_FRAME_SIZE / 2 / sizeof(float), (float*)audio_buffer); + float audio_buffer[OPENMPT_FRAME_SIZE / sizeof(float)]; + ret = mod.read_interleaved_stereo(OPENMPT_SAMPLE_RATE, + OPENMPT_FRAME_SIZE / channels / sizeof(float), + audio_buffer); if (ret <= 0) break; - cmd = client.SubmitData(nullptr, - audio_buffer, ret * 2 * sizeof(float), - 0); + cmd = client.SubmitAudio(nullptr, + std::span{audio_buffer, ret * channels}, + 0); if (cmd == DecoderCommand::SEEK) { mod.set_position_seconds(client.GetSeekTime().ToS()); diff --git a/src/decoder/plugins/OpusDecoderPlugin.cxx b/src/decoder/plugins/OpusDecoderPlugin.cxx index c35914236..ccba79505 100644 --- a/src/decoder/plugins/OpusDecoderPlugin.cxx +++ b/src/decoder/plugins/OpusDecoderPlugin.cxx @@ -114,11 +114,9 @@ class MPDOpusDecoder final : public OggDecoder { */ unsigned previous_channels = 0; - size_t frame_size; - /** * The granulepos of the next sample to be submitted to - * DecoderClient::SubmitData(). Negative if unkown. + * DecoderClient::SubmitAudio(). Negative if unkown. * Initialized by OnOggBeginning(). */ ogg_int64_t granulepos; @@ -238,7 +236,6 @@ MPDOpusDecoder::OnOggBeginning(const ogg_packet &packet) const AudioFormat audio_format(opus_sample_rate, SampleFormat::S16, channels); client.Ready(audio_format, eos_granulepos > 0, duration); - frame_size = audio_format.GetFrameSize(); if (output_buffer == nullptr) /* note: if we ever support changing the channel count @@ -365,10 +362,10 @@ MPDOpusDecoder::HandleAudio(const ogg_packet &packet) } /* submit decoded samples to the DecoderClient */ - const size_t nbytes = nframes * frame_size; - auto cmd = client.SubmitData(input_stream, - data, nbytes, - kbits); + const size_t n_samples = nframes * previous_channels; + auto cmd = client.SubmitAudio(input_stream, + std::span{data, n_samples}, + kbits); if (cmd != DecoderCommand::NONE) throw cmd; diff --git a/src/decoder/plugins/PcmDecoderPlugin.cxx b/src/decoder/plugins/PcmDecoderPlugin.cxx index bd4dea739..8d9ab1f87 100644 --- a/src/decoder/plugins/PcmDecoderPlugin.cxx +++ b/src/decoder/plugins/PcmDecoderPlugin.cxx @@ -187,7 +187,7 @@ 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 - DecoderClient::SubmitData() */ + DecoderClient::SubmitAudio() */ r = r.first(r.size() - r.size() % in_frame_size); buffer.Consume(r.size()); @@ -209,7 +209,7 @@ pcm_stream_decode(DecoderClient &client, InputStream &is) } cmd = !r.empty() - ? client.SubmitData(is, r.data(), r.size(), 0) + ? client.SubmitAudio(is, r, 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 266b12bd6..a730b32e5 100644 --- a/src/decoder/plugins/SidplayDecoderPlugin.cxx +++ b/src/decoder/plugins/SidplayDecoderPlugin.cxx @@ -419,15 +419,16 @@ sidplay_file_decode(DecoderClient &client, Path path_fs) #ifdef HAVE_SIDPLAYFP /* libsidplayfp returns the number of samples */ - const size_t nbytes = result * sizeof(buffer[0]); + const size_t n_samples = result; #else /* libsidplay2 returns the number of bytes */ - const size_t nbytes = result; + const size_t n_samples = result / sizeof(buffer[0]); #endif client.SubmitTimestamp(FloatDuration(player.time()) / timebase); - cmd = client.SubmitData(nullptr, buffer, nbytes, 0); + cmd = client.SubmitAudio(nullptr, std::span{buffer, n_samples}, + 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 253aef585..9bc22795f 100644 --- a/src/decoder/plugins/SndfileDecoderPlugin.cxx +++ b/src/decoder/plugins/SndfileDecoderPlugin.cxx @@ -227,9 +227,9 @@ sndfile_stream_decode(DecoderClient &client, InputStream &is) if (num_frames <= 0) break; - cmd = client.SubmitData(is, - buffer, num_frames * frame_size, - 0); + cmd = client.SubmitAudio(is, + std::span{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 aaf37ad0a..2339ff833 100644 --- a/src/decoder/plugins/VorbisDecoderPlugin.cxx +++ b/src/decoder/plugins/VorbisDecoderPlugin.cxx @@ -233,10 +233,10 @@ VorbisDecoder::SubmitSomePcm() vorbis_synthesis_read(&dsp, n_frames); - const size_t nbytes = n_frames * frame_size; - auto cmd = client.SubmitData(input_stream, - buffer, nbytes, - 0); + const std::size_t n_samples = n_frames * channels; + auto cmd = client.SubmitAudio(input_stream, + std::span{buffer, n_samples}, + 0); if (cmd != DecoderCommand::NONE) throw cmd; diff --git a/src/decoder/plugins/WavpackDecoderPlugin.cxx b/src/decoder/plugins/WavpackDecoderPlugin.cxx index 871b9e1a7..1617d82be 100644 --- a/src/decoder/plugins/WavpackDecoderPlugin.cxx +++ b/src/decoder/plugins/WavpackDecoderPlugin.cxx @@ -234,9 +234,12 @@ wavpack_decode(DecoderClient &client, WavpackContext *wpc, bool can_seek) int bitrate = lround(WavpackGetInstantBitrate(wpc) / 1000); format_samples(buffer, n_frames * audio_format.channels); - cmd = client.SubmitData(nullptr, buffer, - n_frames * output_frame_size, - bitrate); + cmd = client.SubmitAudio(nullptr, + { + (const std::byte *)buffer, + n_frames * output_frame_size, + }, + bitrate); } } diff --git a/src/decoder/plugins/WildmidiDecoderPlugin.cxx b/src/decoder/plugins/WildmidiDecoderPlugin.cxx index fb9561153..9c67eb680 100644 --- a/src/decoder/plugins/WildmidiDecoderPlugin.cxx +++ b/src/decoder/plugins/WildmidiDecoderPlugin.cxx @@ -94,7 +94,9 @@ wildmidi_output(DecoderClient &client, midi *wm) if (length <= 0) return DecoderCommand::STOP; - return client.SubmitData(nullptr, buffer, length, 0); + return client.SubmitAudio(nullptr, + std::span{buffer, std::size_t(length)}, + 0); } static void diff --git a/src/lib/chromaprint/DecoderClient.cxx b/src/lib/chromaprint/DecoderClient.cxx index 4855f3b9d..d1ec1b986 100644 --- a/src/lib/chromaprint/DecoderClient.cxx +++ b/src/lib/chromaprint/DecoderClient.cxx @@ -63,23 +63,21 @@ ChromaprintDecoderClient::Ready(AudioFormat audio_format, bool, } DecoderCommand -ChromaprintDecoderClient::SubmitData(InputStream *, - const void *_data, size_t length, - uint16_t) noexcept +ChromaprintDecoderClient::SubmitAudio(InputStream *, + std::span audio, + uint16_t) noexcept { assert(ready); - if (length > remaining_bytes) + if (audio.size() > remaining_bytes) remaining_bytes = 0; else - remaining_bytes -= length; - - std::span src{(const std::byte *)_data, length}; + remaining_bytes -= audio.size(); if (convert) - src = convert->Convert(src); + audio = convert->Convert(audio); - chromaprint.Feed(FromBytesStrict(src)); + chromaprint.Feed(FromBytesStrict(audio)); return GetCommand(); } diff --git a/src/lib/chromaprint/DecoderClient.hxx b/src/lib/chromaprint/DecoderClient.hxx index fe6ed6afa..bc0d0b114 100644 --- a/src/lib/chromaprint/DecoderClient.hxx +++ b/src/lib/chromaprint/DecoderClient.hxx @@ -93,9 +93,9 @@ public: void *buffer, size_t length) noexcept override; void SubmitTimestamp(FloatDuration) noexcept override {} - DecoderCommand SubmitData(InputStream *is, - const void *data, size_t length, - uint16_t kbit_rate) noexcept override; + DecoderCommand SubmitAudio(InputStream *is, + std::span audio, + uint16_t kbit_rate) noexcept override; DecoderCommand SubmitTag(InputStream *, Tag &&) noexcept override { return GetCommand(); diff --git a/test/DumpDecoderClient.cxx b/test/DumpDecoderClient.cxx index 7941342bc..f59a00f74 100644 --- a/test/DumpDecoderClient.cxx +++ b/test/DumpDecoderClient.cxx @@ -91,16 +91,17 @@ DumpDecoderClient::SubmitTimestamp([[maybe_unused]] FloatDuration t) noexcept } DecoderCommand -DumpDecoderClient::SubmitData([[maybe_unused]] InputStream *is, - const void *data, size_t datalen, - [[maybe_unused]] uint16_t kbit_rate) noexcept +DumpDecoderClient::SubmitAudio([[maybe_unused]] InputStream *is, + std::span audio, + [[maybe_unused]] uint16_t kbit_rate) noexcept { if (kbit_rate != prev_kbit_rate) { prev_kbit_rate = kbit_rate; fprintf(stderr, "%u kbit/s\n", kbit_rate); } - [[maybe_unused]] ssize_t nbytes = write(STDOUT_FILENO, data, datalen); + [[maybe_unused]] ssize_t nbytes = write(STDOUT_FILENO, + audio.data(), audio.size()); return GetCommand(); } diff --git a/test/DumpDecoderClient.hxx b/test/DumpDecoderClient.hxx index 5f5827c36..274de839a 100644 --- a/test/DumpDecoderClient.hxx +++ b/test/DumpDecoderClient.hxx @@ -51,9 +51,9 @@ public: size_t Read(InputStream &is, void *buffer, size_t length) noexcept override; void SubmitTimestamp(FloatDuration t) noexcept override; - DecoderCommand SubmitData(InputStream *is, - const void *data, size_t length, - uint16_t kbit_rate) noexcept override; + DecoderCommand SubmitAudio(InputStream *is, + std::span audio, + uint16_t kbit_rate) noexcept override; DecoderCommand SubmitTag(InputStream *is, Tag &&tag) noexcept override; void SubmitReplayGain(const ReplayGainInfo *replay_gain_info) noexcept override; void SubmitMixRamp(MixRampInfo &&mix_ramp) noexcept override;