decoder/Client: pass std::span to SubmitData()

This commit is contained in:
Max Kellermann 2022-07-11 18:03:06 +02:00
parent 329c448d30
commit c34f6ed8c0
30 changed files with 138 additions and 116 deletions

View File

@ -451,18 +451,18 @@ DecoderBridge::SubmitTimestamp(FloatDuration t) noexcept
} }
DecoderCommand DecoderCommand
DecoderBridge::SubmitData(InputStream *is, DecoderBridge::SubmitAudio(InputStream *is,
const void *data, size_t length, std::span<const std::byte> audio,
uint16_t kbit_rate) noexcept uint16_t kbit_rate) noexcept
{ {
assert(dc.state == DecoderState::DECODE); assert(dc.state == DecoderState::DECODE);
assert(dc.pipe != nullptr); assert(dc.pipe != nullptr);
assert(length % dc.in_audio_format.GetFrameSize() == 0); assert(audio.size() % dc.in_audio_format.GetFrameSize() == 0);
DecoderCommand cmd = LockGetVirtualCommand(); DecoderCommand cmd = LockGetVirtualCommand();
if (cmd == DecoderCommand::STOP || cmd == DecoderCommand::SEEK || if (cmd == DecoderCommand::STOP || cmd == DecoderCommand::SEEK ||
length == 0) audio.empty())
return cmd; return cmd;
assert(!initial_seek_pending); assert(!initial_seek_pending);
@ -486,7 +486,7 @@ DecoderBridge::SubmitData(InputStream *is,
cmd = DecoderCommand::NONE; cmd = DecoderCommand::NONE;
const size_t frame_size = dc.in_audio_format.GetFrameSize(); 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()) { if (dc.end_time.IsPositive()) {
/* enforce the given end time */ /* enforce the given end time */
@ -501,7 +501,7 @@ DecoderBridge::SubmitData(InputStream *is,
/* past the end of the range: truncate this /* past the end of the range: truncate this
data submission and stop the decoder */ data submission and stop the decoder */
data_frames = remaining_frames; data_frames = remaining_frames;
length = data_frames * frame_size; audio = audio.first(data_frames * frame_size);
cmd = DecoderCommand::STOP; cmd = DecoderCommand::STOP;
} }
} }
@ -510,9 +510,7 @@ DecoderBridge::SubmitData(InputStream *is,
assert(dc.in_audio_format != dc.out_audio_format); assert(dc.in_audio_format != dc.out_audio_format);
try { try {
auto result = convert->Convert({(const std::byte *)data, length}); audio = convert->Convert(audio);
data = result.data();
length = result.size();
} catch (...) { } catch (...) {
/* the PCM conversion has failed - stop /* the PCM conversion has failed - stop
playback, since we have no better way to 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); assert(dc.in_audio_format == dc.out_audio_format);
} }
while (length > 0) { while (!audio.empty()) {
bool full; bool full;
auto *chunk = GetChunk(); auto *chunk = GetChunk();
@ -544,11 +542,11 @@ DecoderBridge::SubmitData(InputStream *is,
continue; continue;
} }
const size_t nbytes = std::min(dest.size(), length); const size_t nbytes = std::min(dest.size(), audio.size());
/* copy the buffer */ /* copy the buffer */
memcpy(dest.data(), data, nbytes); memcpy(dest.data(), audio.data(), nbytes);
/* expand the music pipe chunk */ /* expand the music pipe chunk */
@ -558,8 +556,7 @@ DecoderBridge::SubmitData(InputStream *is,
FlushChunk(); FlushChunk();
} }
data = (const uint8_t *)data + nbytes; audio = audio.subspan(nbytes);
length -= nbytes;
timestamp += dc.out_audio_format.SizeToTime<FloatDuration>(nbytes); timestamp += dc.out_audio_format.SizeToTime<FloatDuration>(nbytes);
} }

View File

@ -177,8 +177,8 @@ public:
size_t Read(InputStream &is, size_t Read(InputStream &is,
void *buffer, size_t length) noexcept override; void *buffer, size_t length) noexcept override;
void SubmitTimestamp(FloatDuration t) noexcept override; void SubmitTimestamp(FloatDuration t) noexcept override;
DecoderCommand SubmitData(InputStream *is, DecoderCommand SubmitAudio(InputStream *is,
const void *data, size_t length, std::span<const std::byte> audio,
uint16_t kbit_rate) noexcept override; uint16_t kbit_rate) noexcept override;
DecoderCommand SubmitTag(InputStream *is, Tag &&tag) noexcept override; DecoderCommand SubmitTag(InputStream *is, Tag &&tag) noexcept override;
void SubmitReplayGain(const ReplayGainInfo *replay_gain_info) noexcept override; void SubmitReplayGain(const ReplayGainInfo *replay_gain_info) noexcept override;

View File

@ -24,7 +24,9 @@
#include "Chrono.hxx" #include "Chrono.hxx"
#include "input/Ptr.hxx" #include "input/Ptr.hxx"
#include <cstddef>
#include <cstdint> #include <cstdint>
#include <span>
struct AudioFormat; struct AudioFormat;
struct Tag; struct Tag;
@ -41,7 +43,7 @@ public:
* that it has read the song's meta data. * that it has read the song's meta data.
* *
* @param audio_format the audio format which is going to be * @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 seekable true if the song is seekable
* @param duration the total duration of this song; negative if * @param duration the total duration of this song; negative if
* unknown * unknown
@ -128,14 +130,32 @@ public:
* @return the current command, or DecoderCommand::NONE if there is no * @return the current command, or DecoderCommand::NONE if there is no
* command pending * command pending
*/ */
virtual DecoderCommand SubmitData(InputStream *is, virtual DecoderCommand SubmitAudio(InputStream *is,
const void *data, size_t length, std::span<const std::byte> audio,
uint16_t kbit_rate) noexcept = 0; uint16_t kbit_rate) noexcept = 0;
DecoderCommand SubmitData(InputStream &is, DecoderCommand SubmitAudio(InputStream &is,
const void *data, size_t length, std::span<const std::byte> audio,
uint16_t kbit_rate) noexcept { uint16_t kbit_rate) noexcept {
return SubmitData(&is, data, length, kbit_rate); return SubmitAudio(&is, audio, kbit_rate);
}
template<typename T, std::size_t extent>
DecoderCommand SubmitAudio(InputStream *is,
std::span<T, extent> audio,
uint16_t kbit_rate) noexcept {
const std::span<const std::byte> audio_bytes =
std::as_bytes(audio);
return SubmitAudio(is, audio_bytes, kbit_rate);
}
template<typename T, std::size_t extent>
DecoderCommand SubmitAudio(InputStream &is,
std::span<T, extent> audio,
uint16_t kbit_rate) noexcept {
const std::span<const std::byte> audio_bytes =
std::as_bytes(audio);
return SubmitAudio(is, audio_bytes, kbit_rate);
} }
/** /**

View File

@ -71,8 +71,8 @@ adplug_file_decode(DecoderClient &client, Path path_fs)
int16_t buffer[2048]; int16_t buffer[2048];
constexpr unsigned frames_per_buffer = std::size(buffer) / 2; constexpr unsigned frames_per_buffer = std::size(buffer) / 2;
opl.update(buffer, frames_per_buffer); opl.update(buffer, frames_per_buffer);
cmd = client.SubmitData(nullptr, cmd = client.SubmitAudio(nullptr,
buffer, sizeof(buffer), std::span{buffer},
0); 0);
} while (cmd == DecoderCommand::NONE); } while (cmd == DecoderCommand::NONE);

View File

@ -212,7 +212,7 @@ audiofile_stream_decode(DecoderClient &client, InputStream &is)
const auto kbit_rate = (uint16_t) const auto kbit_rate = (uint16_t)
(is.GetSize() * uint64_t(8) / total_time.ToMS()); (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); afGetVirtualFrameSize(fh, AF_DEFAULT_TRACK, true);
client.Ready(audio_format, true, total_time); client.Ready(audio_format, true, total_time);
@ -226,8 +226,8 @@ audiofile_stream_decode(DecoderClient &client, InputStream &is)
if (nframes <= 0) if (nframes <= 0)
break; break;
cmd = client.SubmitData(nullptr, cmd = client.SubmitAudio(nullptr,
chunk, nframes * frame_size, std::span{chunk, std::size_t(nframes) * frame_size},
kbit_rate); kbit_rate);
if (cmd == DecoderCommand::SEEK) { if (cmd == DecoderCommand::SEEK) {

View File

@ -417,7 +417,7 @@ dsdiff_decode_chunk(DecoderClient &client, InputStream &is,
if (lsbitfirst) if (lsbitfirst)
bit_reverse_buffer(buffer, buffer + nbytes); bit_reverse_buffer(buffer, buffer + nbytes);
cmd = client.SubmitData(is, buffer, nbytes, cmd = client.SubmitAudio(is, std::span{buffer, nbytes},
kbit_rate); kbit_rate);
} }

View File

@ -289,8 +289,8 @@ dsf_decode_chunk(DecoderClient &client, InputStream &is,
uint8_t interleaved_buffer[MAX_CHANNELS * DSF_BLOCK_SIZE]; uint8_t interleaved_buffer[MAX_CHANNELS * DSF_BLOCK_SIZE];
InterleaveDsfBlock(interleaved_buffer, buffer, channels); InterleaveDsfBlock(interleaved_buffer, buffer, channels);
cmd = client.SubmitData(is, cmd = client.SubmitAudio(is,
interleaved_buffer, block_size, std::span{interleaved_buffer, block_size},
kbit_rate); kbit_rate);
++i; ++i;
} }

View File

@ -354,7 +354,7 @@ faad_stream_decode(DecoderClient &client, InputStream &is,
/* decode it */ /* decode it */
NeAACDecFrameInfo frame_info; NeAACDecFrameInfo frame_info;
const void *const decoded = const auto decoded = (const int16_t *)
faad_decoder_decode(decoder, buffer, &frame_info); faad_decoder_decode(decoder, buffer, &frame_info);
if (frame_info.error > 0) { if (frame_info.error > 0) {
@ -391,9 +391,9 @@ faad_stream_decode(DecoderClient &client, InputStream &is,
/* send PCM samples to MPD */ /* send PCM samples to MPD */
cmd = client.SubmitData(is, decoded, const std::span audio{decoded, (size_t)frame_info.samples};
(size_t)frame_info.samples * 2,
bit_rate); cmd = client.SubmitAudio(is, audio, bit_rate);
} while (cmd != DecoderCommand::STOP); } while (cmd != DecoderCommand::STOP);
} }

View File

@ -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. * #AVFrame.
*/ */
static DecoderCommand static DecoderCommand
@ -227,8 +227,7 @@ FfmpegSendFrame(DecoderClient &client, InputStream *is,
skip_bytes = 0; skip_bytes = 0;
} }
return client.SubmitData(is, return client.SubmitAudio(is, output_buffer,
output_buffer.data(), output_buffer.size(),
codec_context.bit_rate / 1000); codec_context.bit_rate / 1000);
} }

View File

@ -46,7 +46,7 @@ struct FlacDecoder : public FlacInput {
/** /**
* The kbit_rate parameter for the next * The kbit_rate parameter for the next
* DecoderBridge::SubmitData() call. * DecoderBridge::SubmitAudio() call.
*/ */
uint16_t kbit_rate; uint16_t kbit_rate;
@ -62,7 +62,7 @@ struct FlacDecoder : public FlacInput {
/** /**
* Decoded PCM data obtained by our libFLAC write callback. * 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. * should be called.
*/ */
std::span<const std::byte> chunk = {}; std::span<const std::byte> chunk = {};

View File

@ -152,9 +152,7 @@ FlacSubmitToClient(DecoderClient &client, FlacDecoder &d) noexcept
} }
if (!d.chunk.empty()) { if (!d.chunk.empty()) {
auto cmd = client.SubmitData(d.GetInputStream(), auto cmd = client.SubmitAudio(d.GetInputStream(), d.chunk,
d.chunk.data(),
d.chunk.size(),
d.kbit_rate); d.kbit_rate);
d.chunk = {}; d.chunk = {};
if (cmd != DecoderCommand::NONE) if (cmd != DecoderCommand::NONE)

View File

@ -179,7 +179,7 @@ fluidsynth_file_decode(DecoderClient &client, Path path_fs)
if (ret != 0) if (ret != 0)
break; break;
cmd = client.SubmitData(nullptr, buffer, sizeof(buffer), 0); cmd = client.SubmitAudio(nullptr, std::span{buffer}, 0);
if (cmd != DecoderCommand::NONE) if (cmd != DecoderCommand::NONE)
break; break;
} }

View File

@ -216,7 +216,7 @@ gme_file_decode(DecoderClient &client, Path path_fs)
return; return;
} }
cmd = client.SubmitData(nullptr, buf, sizeof(buf), 0); cmd = client.SubmitAudio(nullptr, std::span{buf}, 0);
if (cmd == DecoderCommand::SEEK) { if (cmd == DecoderCommand::SEEK) {
unsigned where = client.GetSeekTime().ToMS(); unsigned where = client.GetSeekTime().ToMS();
gme_err = gme_seek(emu, where); gme_err = gme_seek(emu, where);

View File

@ -185,13 +185,13 @@ private:
/** /**
* Sends the synthesized current frame via * Sends the synthesized current frame via
* DecoderClient::SubmitData(). * DecoderClient::SubmitAudio().
*/ */
DecoderCommand SubmitPCM(size_t start, size_t n) noexcept; DecoderCommand SubmitPCM(size_t start, size_t n) noexcept;
/** /**
* Synthesize the current frame and send it via * Synthesize the current frame and send it via
* DecoderClient::SubmitData(). * DecoderClient::SubmitAudio().
*/ */
DecoderCommand SynthAndSubmit() noexcept; DecoderCommand SynthAndSubmit() noexcept;
@ -805,8 +805,8 @@ MadDecoder::SubmitPCM(size_t i, size_t pcm_length) noexcept
MAD_NCHANNELS(&frame.header)); MAD_NCHANNELS(&frame.header));
num_samples *= MAD_NCHANNELS(&frame.header); num_samples *= MAD_NCHANNELS(&frame.header);
return client->SubmitData(input_stream, output_buffer, return client->SubmitAudio(input_stream,
sizeof(output_buffer[0]) * num_samples, std::span{output_buffer, num_samples},
frame.header.bitrate / 1000); frame.header.bitrate / 1000);
} }

View File

@ -171,7 +171,9 @@ mikmod_decoder_file_decode(DecoderClient &client, Path path_fs)
DecoderCommand cmd = DecoderCommand::NONE; DecoderCommand cmd = DecoderCommand::NONE;
while (cmd == DecoderCommand::NONE && Player_Active()) { while (cmd == DecoderCommand::NONE && Player_Active()) {
ret = VC_WriteBytes(buffer, sizeof(buffer)); 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(); Player_Stop();

View File

@ -116,8 +116,8 @@ mod_decode(DecoderClient &client, InputStream &is)
if (ret <= 0) if (ret <= 0)
break; break;
cmd = client.SubmitData(nullptr, cmd = client.SubmitAudio(nullptr,
audio_buffer, ret, std::span{audio_buffer, std::size_t(ret)},
0); 0);
if (cmd == DecoderCommand::SEEK) { if (cmd == DecoderCommand::SEEK) {

View File

@ -241,8 +241,8 @@ mpcdec_decode(DecoderClient &client, InputStream &is)
long bit_rate = unsigned(frame.bits) * audio_format.sample_rate long bit_rate = unsigned(frame.bits) * audio_format.sample_rate
/ (1000 * frame.samples); / (1000 * frame.samples);
cmd = client.SubmitData(is, cmd = client.SubmitAudio(is,
chunk, ret * sizeof(chunk[0]), std::span{chunk, ret},
bit_rate); bit_rate);
} while (cmd != DecoderCommand::STOP); } while (cmd != DecoderCommand::STOP);
} }

View File

@ -253,7 +253,8 @@ mpd_mpg123_file_decode(DecoderClient &client, Path path_fs)
/* send to MPD */ /* 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) { if (cmd == DecoderCommand::SEEK) {
off_t c = client.GetSeekFrame(); off_t c = client.GetSeekFrame();

View File

@ -69,7 +69,6 @@ static void
mod_decode(DecoderClient &client, InputStream &is) mod_decode(DecoderClient &client, InputStream &is)
{ {
int ret; int ret;
char audio_buffer[OPENMPT_FRAME_SIZE];
const auto buffer = mod_loadfile(&openmpt_domain, &client, is); const auto buffer = mod_loadfile(&openmpt_domain, &client, is);
if (buffer == nullptr) { 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)); mod.ctl_set("render.resampler.emulate_amiga", std::to_string((unsigned)openmpt_emulate_amiga));
#endif #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()); assert(audio_format.IsValid());
client.Ready(audio_format, is.IsSeekable(), client.Ready(audio_format, is.IsSeekable(),
@ -107,12 +107,15 @@ mod_decode(DecoderClient &client, InputStream &is)
DecoderCommand cmd; DecoderCommand cmd;
do { 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) if (ret <= 0)
break; break;
cmd = client.SubmitData(nullptr, cmd = client.SubmitAudio(nullptr,
audio_buffer, ret * 2 * sizeof(float), std::span{audio_buffer, ret * channels},
0); 0);
if (cmd == DecoderCommand::SEEK) { if (cmd == DecoderCommand::SEEK) {

View File

@ -114,11 +114,9 @@ class MPDOpusDecoder final : public OggDecoder {
*/ */
unsigned previous_channels = 0; unsigned previous_channels = 0;
size_t frame_size;
/** /**
* The granulepos of the next sample to be submitted to * The granulepos of the next sample to be submitted to
* DecoderClient::SubmitData(). Negative if unkown. * DecoderClient::SubmitAudio(). Negative if unkown.
* Initialized by OnOggBeginning(). * Initialized by OnOggBeginning().
*/ */
ogg_int64_t granulepos; ogg_int64_t granulepos;
@ -238,7 +236,6 @@ MPDOpusDecoder::OnOggBeginning(const ogg_packet &packet)
const AudioFormat audio_format(opus_sample_rate, const AudioFormat audio_format(opus_sample_rate,
SampleFormat::S16, channels); SampleFormat::S16, channels);
client.Ready(audio_format, eos_granulepos > 0, duration); client.Ready(audio_format, eos_granulepos > 0, duration);
frame_size = audio_format.GetFrameSize();
if (output_buffer == nullptr) if (output_buffer == nullptr)
/* note: if we ever support changing the channel count /* note: if we ever support changing the channel count
@ -365,9 +362,9 @@ MPDOpusDecoder::HandleAudio(const ogg_packet &packet)
} }
/* submit decoded samples to the DecoderClient */ /* submit decoded samples to the DecoderClient */
const size_t nbytes = nframes * frame_size; const size_t n_samples = nframes * previous_channels;
auto cmd = client.SubmitData(input_stream, auto cmd = client.SubmitAudio(input_stream,
data, nbytes, std::span{data, n_samples},
kbits); kbits);
if (cmd != DecoderCommand::NONE) if (cmd != DecoderCommand::NONE)
throw cmd; throw cmd;

View File

@ -187,7 +187,7 @@ pcm_stream_decode(DecoderClient &client, InputStream &is)
auto r = buffer.Read(); auto r = buffer.Read();
/* round down to the nearest frame size, because we /* round down to the nearest frame size, because we
must not pass partial frames to must not pass partial frames to
DecoderClient::SubmitData() */ DecoderClient::SubmitAudio() */
r = r.first(r.size() - r.size() % in_frame_size); r = r.first(r.size() - r.size() % in_frame_size);
buffer.Consume(r.size()); buffer.Consume(r.size());
@ -209,7 +209,7 @@ pcm_stream_decode(DecoderClient &client, InputStream &is)
} }
cmd = !r.empty() cmd = !r.empty()
? client.SubmitData(is, r.data(), r.size(), 0) ? client.SubmitAudio(is, r, 0)
: client.GetCommand(); : client.GetCommand();
if (cmd == DecoderCommand::SEEK) { if (cmd == DecoderCommand::SEEK) {
uint64_t frame = client.GetSeekFrame(); uint64_t frame = client.GetSeekFrame();

View File

@ -419,15 +419,16 @@ sidplay_file_decode(DecoderClient &client, Path path_fs)
#ifdef HAVE_SIDPLAYFP #ifdef HAVE_SIDPLAYFP
/* libsidplayfp returns the number of samples */ /* libsidplayfp returns the number of samples */
const size_t nbytes = result * sizeof(buffer[0]); const size_t n_samples = result;
#else #else
/* libsidplay2 returns the number of bytes */ /* libsidplay2 returns the number of bytes */
const size_t nbytes = result; const size_t n_samples = result / sizeof(buffer[0]);
#endif #endif
client.SubmitTimestamp(FloatDuration(player.time()) / timebase); 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) { if (cmd == DecoderCommand::SEEK) {
unsigned data_time = player.time(); unsigned data_time = player.time();

View File

@ -227,8 +227,8 @@ sndfile_stream_decode(DecoderClient &client, InputStream &is)
if (num_frames <= 0) if (num_frames <= 0)
break; break;
cmd = client.SubmitData(is, cmd = client.SubmitAudio(is,
buffer, num_frames * frame_size, std::span{buffer, num_frames * frame_size},
0); 0);
if (cmd == DecoderCommand::SEEK) { if (cmd == DecoderCommand::SEEK) {
sf_count_t c = client.GetSeekFrame(); sf_count_t c = client.GetSeekFrame();

View File

@ -233,9 +233,9 @@ VorbisDecoder::SubmitSomePcm()
vorbis_synthesis_read(&dsp, n_frames); vorbis_synthesis_read(&dsp, n_frames);
const size_t nbytes = n_frames * frame_size; const std::size_t n_samples = n_frames * channels;
auto cmd = client.SubmitData(input_stream, auto cmd = client.SubmitAudio(input_stream,
buffer, nbytes, std::span{buffer, n_samples},
0); 0);
if (cmd != DecoderCommand::NONE) if (cmd != DecoderCommand::NONE)
throw cmd; throw cmd;

View File

@ -234,8 +234,11 @@ wavpack_decode(DecoderClient &client, WavpackContext *wpc, bool can_seek)
int bitrate = lround(WavpackGetInstantBitrate(wpc) / 1000); int bitrate = lround(WavpackGetInstantBitrate(wpc) / 1000);
format_samples(buffer, n_frames * audio_format.channels); format_samples(buffer, n_frames * audio_format.channels);
cmd = client.SubmitData(nullptr, buffer, cmd = client.SubmitAudio(nullptr,
{
(const std::byte *)buffer,
n_frames * output_frame_size, n_frames * output_frame_size,
},
bitrate); bitrate);
} }
} }

View File

@ -94,7 +94,9 @@ wildmidi_output(DecoderClient &client, midi *wm)
if (length <= 0) if (length <= 0)
return DecoderCommand::STOP; return DecoderCommand::STOP;
return client.SubmitData(nullptr, buffer, length, 0); return client.SubmitAudio(nullptr,
std::span{buffer, std::size_t(length)},
0);
} }
static void static void

View File

@ -63,23 +63,21 @@ ChromaprintDecoderClient::Ready(AudioFormat audio_format, bool,
} }
DecoderCommand DecoderCommand
ChromaprintDecoderClient::SubmitData(InputStream *, ChromaprintDecoderClient::SubmitAudio(InputStream *,
const void *_data, size_t length, std::span<const std::byte> audio,
uint16_t) noexcept uint16_t) noexcept
{ {
assert(ready); assert(ready);
if (length > remaining_bytes) if (audio.size() > remaining_bytes)
remaining_bytes = 0; remaining_bytes = 0;
else else
remaining_bytes -= length; remaining_bytes -= audio.size();
std::span<const std::byte> src{(const std::byte *)_data, length};
if (convert) if (convert)
src = convert->Convert(src); audio = convert->Convert(audio);
chromaprint.Feed(FromBytesStrict<const int16_t>(src)); chromaprint.Feed(FromBytesStrict<const int16_t>(audio));
return GetCommand(); return GetCommand();
} }

View File

@ -93,8 +93,8 @@ public:
void *buffer, size_t length) noexcept override; void *buffer, size_t length) noexcept override;
void SubmitTimestamp(FloatDuration) noexcept override {} void SubmitTimestamp(FloatDuration) noexcept override {}
DecoderCommand SubmitData(InputStream *is, DecoderCommand SubmitAudio(InputStream *is,
const void *data, size_t length, std::span<const std::byte> audio,
uint16_t kbit_rate) noexcept override; uint16_t kbit_rate) noexcept override;
DecoderCommand SubmitTag(InputStream *, Tag &&) noexcept override { DecoderCommand SubmitTag(InputStream *, Tag &&) noexcept override {

View File

@ -91,8 +91,8 @@ DumpDecoderClient::SubmitTimestamp([[maybe_unused]] FloatDuration t) noexcept
} }
DecoderCommand DecoderCommand
DumpDecoderClient::SubmitData([[maybe_unused]] InputStream *is, DumpDecoderClient::SubmitAudio([[maybe_unused]] InputStream *is,
const void *data, size_t datalen, std::span<const std::byte> audio,
[[maybe_unused]] uint16_t kbit_rate) noexcept [[maybe_unused]] uint16_t kbit_rate) noexcept
{ {
if (kbit_rate != prev_kbit_rate) { if (kbit_rate != prev_kbit_rate) {
@ -100,7 +100,8 @@ DumpDecoderClient::SubmitData([[maybe_unused]] InputStream *is,
fprintf(stderr, "%u kbit/s\n", 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(); return GetCommand();
} }

View File

@ -51,8 +51,8 @@ public:
size_t Read(InputStream &is, size_t Read(InputStream &is,
void *buffer, size_t length) noexcept override; void *buffer, size_t length) noexcept override;
void SubmitTimestamp(FloatDuration t) noexcept override; void SubmitTimestamp(FloatDuration t) noexcept override;
DecoderCommand SubmitData(InputStream *is, DecoderCommand SubmitAudio(InputStream *is,
const void *data, size_t length, std::span<const std::byte> audio,
uint16_t kbit_rate) noexcept override; uint16_t kbit_rate) noexcept override;
DecoderCommand SubmitTag(InputStream *is, Tag &&tag) noexcept override; DecoderCommand SubmitTag(InputStream *is, Tag &&tag) noexcept override;
void SubmitReplayGain(const ReplayGainInfo *replay_gain_info) noexcept override; void SubmitReplayGain(const ReplayGainInfo *replay_gain_info) noexcept override;