encoder/Interface: pass std::span to Write() and Read()
This commit is contained in:
parent
28e044a36a
commit
7e14f8f830
@ -21,6 +21,7 @@
|
||||
#define MPD_ENCODER_INTERFACE_HXX
|
||||
|
||||
#include <cstddef>
|
||||
#include <span>
|
||||
|
||||
struct AudioFormat;
|
||||
struct Tag;
|
||||
@ -91,18 +92,19 @@ public:
|
||||
* @param data the buffer containing PCM samples
|
||||
* @param length the length of the buffer in bytes
|
||||
*/
|
||||
virtual void Write(const void *data, std::size_t length) = 0;
|
||||
virtual void Write(std::span<const std::byte> src) = 0;
|
||||
|
||||
/**
|
||||
* Reads encoded data from the encoder.
|
||||
*
|
||||
* Call this repeatedly until no more data is returned.
|
||||
*
|
||||
* @param dest the destination buffer to copy to
|
||||
* @param length the maximum length of the destination buffer
|
||||
* @return the number of bytes written to #dest
|
||||
* @param buffer a buffer that can be used to write data into
|
||||
*
|
||||
* @return the portion of the buffer that was filled (but may
|
||||
* also point to a different buffer, e.g. one owned by this object)
|
||||
*/
|
||||
virtual std::size_t Read(void *dest, std::size_t length) noexcept = 0;
|
||||
virtual std::span<const std::byte> Read(std::span<std::byte> buffer) noexcept = 0;
|
||||
};
|
||||
|
||||
class PreparedEncoder {
|
||||
|
@ -28,12 +28,12 @@ EncoderToOutputStream(OutputStream &os, Encoder &encoder)
|
||||
/* read from the encoder */
|
||||
|
||||
std::byte buffer[32768];
|
||||
size_t nbytes = encoder.Read(buffer, sizeof(buffer));
|
||||
if (nbytes == 0)
|
||||
const auto r = encoder.Read(std::span{buffer});
|
||||
if (r.empty())
|
||||
return;
|
||||
|
||||
/* write everything to the stream */
|
||||
|
||||
os.Write(buffer, nbytes);
|
||||
os.Write(r.data(), r.size());
|
||||
}
|
||||
}
|
||||
|
@ -71,10 +71,10 @@ public:
|
||||
|
||||
void SendTag(const Tag &tag) override;
|
||||
|
||||
void Write(const void *data, size_t length) override;
|
||||
void Write(std::span<const std::byte> src) override;
|
||||
|
||||
size_t Read(void *dest, size_t length) noexcept override {
|
||||
return output_buffer.Read((std::byte *)dest, length);
|
||||
std::span<const std::byte> Read(std::span<std::byte> buffer) noexcept override {
|
||||
return buffer.first(output_buffer.Read(buffer.data(), buffer.size()));
|
||||
}
|
||||
|
||||
private:
|
||||
@ -267,27 +267,27 @@ pcm16_to_flac(int32_t *out, const int16_t *in, std::size_t num_samples) noexcept
|
||||
}
|
||||
|
||||
void
|
||||
FlacEncoder::Write(const void *data, size_t length)
|
||||
FlacEncoder::Write(std::span<const std::byte> src)
|
||||
{
|
||||
void *exbuffer;
|
||||
const void *buffer = nullptr;
|
||||
|
||||
/* format conversion */
|
||||
|
||||
const std::size_t num_frames = length / audio_format.GetFrameSize();
|
||||
const std::size_t num_frames = src.size() / audio_format.GetFrameSize();
|
||||
const std::size_t num_samples = num_frames * audio_format.channels;
|
||||
|
||||
switch (audio_format.format) {
|
||||
case SampleFormat::S8:
|
||||
exbuffer = expand_buffer.Get(length * 4);
|
||||
pcm8_to_flac((int32_t *)exbuffer, (const int8_t *)data,
|
||||
exbuffer = expand_buffer.Get(src.size() * 4);
|
||||
pcm8_to_flac((int32_t *)exbuffer, (const int8_t *)src.data(),
|
||||
num_samples);
|
||||
buffer = exbuffer;
|
||||
break;
|
||||
|
||||
case SampleFormat::S16:
|
||||
exbuffer = expand_buffer.Get(length * 2);
|
||||
pcm16_to_flac((int32_t *)exbuffer, (const int16_t *)data,
|
||||
exbuffer = expand_buffer.Get(src.size() * 2);
|
||||
pcm16_to_flac((int32_t *)exbuffer, (const int16_t *)src.data(),
|
||||
num_samples);
|
||||
buffer = exbuffer;
|
||||
break;
|
||||
@ -296,7 +296,7 @@ FlacEncoder::Write(const void *data, size_t length)
|
||||
case SampleFormat::S32:
|
||||
/* nothing need to be done; format is the same for
|
||||
both mpd and libFLAC */
|
||||
buffer = data;
|
||||
buffer = src.data();
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "util/NumberParser.hxx"
|
||||
#include "util/ReusableArray.hxx"
|
||||
#include "util/RuntimeError.hxx"
|
||||
#include "util/SpanCast.hxx"
|
||||
|
||||
#include <lame/lame.h>
|
||||
|
||||
@ -167,14 +168,14 @@ LameEncoder::~LameEncoder() noexcept
|
||||
}
|
||||
|
||||
void
|
||||
LameEncoder::Write(std::span<const std::byte> src)
|
||||
LameEncoder::Write(std::span<const std::byte> _src)
|
||||
{
|
||||
const auto *src = (const int16_t*)data;
|
||||
const auto src = FromBytesStrict<const int16_t>(_src);
|
||||
|
||||
assert(output_begin == output_end);
|
||||
|
||||
const std::size_t num_frames = length / audio_format.GetFrameSize();
|
||||
const std::size_t num_samples = length / audio_format.GetSampleSize();
|
||||
const std::size_t num_samples = src.size();
|
||||
const std::size_t num_frames = num_samples / audio_format.channels;
|
||||
|
||||
/* worst-case formula according to LAME documentation */
|
||||
const std::size_t output_buffer_size = 5 * num_samples / 4 + 7200;
|
||||
@ -183,7 +184,7 @@ LameEncoder::Write(std::span<const std::byte> src)
|
||||
/* this is for only 16-bit audio */
|
||||
|
||||
int bytes_out = lame_encode_buffer_interleaved(gfp,
|
||||
const_cast<short *>(src),
|
||||
const_cast<short *>(src.data()),
|
||||
num_frames,
|
||||
dest, output_buffer_size);
|
||||
|
||||
@ -194,19 +195,18 @@ LameEncoder::Write(std::span<const std::byte> src)
|
||||
output_end = dest + bytes_out;
|
||||
}
|
||||
|
||||
size_t
|
||||
LameEncoder::Read(void *dest, size_t length) noexcept
|
||||
std::span<const std::byte>
|
||||
LameEncoder::Read(std::span<std::byte> buffer) noexcept
|
||||
{
|
||||
const auto begin = output_begin;
|
||||
assert(begin <= output_end);
|
||||
const std::size_t remainning = output_end - begin;
|
||||
if (length > remainning)
|
||||
length = remainning;
|
||||
const std::size_t nbytes = std::min(remainning, buffer.size());
|
||||
|
||||
memcpy(dest, begin, length);
|
||||
memcpy(buffer.data(), begin, nbytes);
|
||||
|
||||
output_begin = begin + length;
|
||||
return length;
|
||||
output_begin = begin + nbytes;
|
||||
return buffer.first(nbytes);
|
||||
}
|
||||
|
||||
const EncoderPlugin lame_encoder_plugin = {
|
||||
|
@ -29,12 +29,12 @@ public:
|
||||
:Encoder(false) {}
|
||||
|
||||
/* virtual methods from class Encoder */
|
||||
void Write(const void *data, size_t length) override {
|
||||
buffer.Append({(const std::byte *)data, length});
|
||||
void Write(std::span<const std::byte> src) override {
|
||||
buffer.Append(src);
|
||||
}
|
||||
|
||||
size_t Read(void *dest, size_t length) noexcept override {
|
||||
return buffer.Read((std::byte *)dest, length);
|
||||
std::span<const std::byte> Read(std::span<std::byte> b) noexcept override {
|
||||
return b.first(buffer.Read(b.data(), b.size()));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -50,7 +50,7 @@ public:
|
||||
flush = true;
|
||||
}
|
||||
|
||||
size_t Read(void *dest, size_t length) noexcept override {
|
||||
std::span<const std::byte> Read(std::span<std::byte> buffer) noexcept override {
|
||||
ogg_page page;
|
||||
bool success = stream.PageOut(page);
|
||||
if (!success) {
|
||||
@ -60,10 +60,11 @@ public:
|
||||
}
|
||||
|
||||
if (!success)
|
||||
return 0;
|
||||
return {};
|
||||
}
|
||||
|
||||
return ReadPage(page, dest, length);
|
||||
return buffer.first(ReadPage(page, buffer.data(),
|
||||
buffer.size()));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -61,7 +61,7 @@ public:
|
||||
|
||||
/* virtual methods from class Encoder */
|
||||
void End() override;
|
||||
void Write(const void *data, size_t length) override;
|
||||
void Write(std::span<const std::byte> src) override;
|
||||
|
||||
void PreTag() override;
|
||||
void SendTag(const Tag &tag) override;
|
||||
@ -272,10 +272,8 @@ OpusEncoder::WriteSilence(unsigned fill_frames)
|
||||
}
|
||||
|
||||
void
|
||||
OpusEncoder::Write(const void *_data, size_t length)
|
||||
OpusEncoder::Write(std::span<const std::byte> src)
|
||||
{
|
||||
const auto *data = (const std::byte *)_data;
|
||||
|
||||
if (lookahead > 0) {
|
||||
/* generate some silence at the beginning of the
|
||||
stream */
|
||||
@ -286,14 +284,12 @@ OpusEncoder::Write(const void *_data, size_t length)
|
||||
lookahead = 0;
|
||||
}
|
||||
|
||||
while (length > 0) {
|
||||
size_t nbytes = buffer_size - buffer_position;
|
||||
if (nbytes > length)
|
||||
nbytes = length;
|
||||
while (!src.empty()) {
|
||||
const std::size_t nbytes = std::min(buffer_size - buffer_position,
|
||||
src.size());
|
||||
|
||||
memcpy(buffer + buffer_position, data, nbytes);
|
||||
data += nbytes;
|
||||
length -= nbytes;
|
||||
memcpy(buffer + buffer_position, src.data(), nbytes);
|
||||
src = src.subspan(nbytes);
|
||||
buffer_position += nbytes;
|
||||
|
||||
if (buffer_position == buffer_size)
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "pcm/AudioFormat.hxx"
|
||||
#include "util/DynamicFifoBuffer.hxx"
|
||||
#include "util/RuntimeError.hxx"
|
||||
#include "util/SpanCast.hxx"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
@ -75,10 +76,10 @@ public:
|
||||
|
||||
void Flush() override;
|
||||
|
||||
void Write(const void *data, size_t length) override;
|
||||
void Write(std::span<const std::byte> src) override;
|
||||
|
||||
size_t Read(void *dest, size_t length) noexcept override {
|
||||
return output_buffer.Read((std::byte *)dest, length);
|
||||
std::span<const std::byte> Read(std::span<std::byte> buffer) noexcept override {
|
||||
return buffer.first(output_buffer.Read(buffer.data(), buffer.size()));
|
||||
}
|
||||
};
|
||||
|
||||
@ -165,24 +166,24 @@ ShineEncoder::WriteChunk(bool flush)
|
||||
}
|
||||
|
||||
void
|
||||
ShineEncoder::Write(const void *_data, size_t length)
|
||||
ShineEncoder::Write(std::span<const std::byte> _src)
|
||||
{
|
||||
const auto *data = (const int16_t*)_data;
|
||||
length /= sizeof(*data) * audio_format.channels;
|
||||
const auto src = FromBytesStrict<const int16_t>(_src);
|
||||
const std::size_t nframes = src.size() / audio_format.channels;
|
||||
size_t written = 0;
|
||||
|
||||
if (input_pos > SHINE_MAX_SAMPLES)
|
||||
input_pos = 0;
|
||||
|
||||
/* write all data to de-interleaved buffers */
|
||||
while (written < length) {
|
||||
while (written < nframes) {
|
||||
for (;
|
||||
written < length && input_pos < frame_size;
|
||||
written < nframes && input_pos < frame_size;
|
||||
written++, input_pos++) {
|
||||
const size_t base =
|
||||
written * audio_format.channels;
|
||||
stereo[0][input_pos] = data[base];
|
||||
stereo[1][input_pos] = data[base + 1];
|
||||
stereo[0][input_pos] = src[base];
|
||||
stereo[1][input_pos] = src[base + 1];
|
||||
}
|
||||
/* write if chunk is filled */
|
||||
WriteChunk(false);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "pcm/AudioFormat.hxx"
|
||||
#include "util/NumberParser.hxx"
|
||||
#include "util/RuntimeError.hxx"
|
||||
#include "util/SpanCast.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
#include "Log.hxx"
|
||||
|
||||
@ -67,8 +68,8 @@ public:
|
||||
flush = true;
|
||||
}
|
||||
|
||||
void Write(const void *data, size_t length) override;
|
||||
size_t Read(void *dest, size_t length) noexcept override;
|
||||
void Write(std::span<const std::byte> src) override;
|
||||
std::span<const std::byte> Read(std::span<std::byte> buffer) noexcept override;
|
||||
};
|
||||
|
||||
class PreparedTwolameEncoder final : public PreparedEncoder {
|
||||
@ -187,16 +188,16 @@ TwolameEncoder::~TwolameEncoder() noexcept
|
||||
}
|
||||
|
||||
void
|
||||
TwolameEncoder::Write(const void *data, size_t length)
|
||||
TwolameEncoder::Write(std::span<const std::byte> _src)
|
||||
{
|
||||
const auto *src = (const int16_t*)data;
|
||||
const auto src = FromBytesStrict<const int16_t>(_src);
|
||||
|
||||
assert(output_buffer_position == output_buffer_length);
|
||||
|
||||
const std::size_t num_frames = length / audio_format.GetFrameSize();
|
||||
const std::size_t num_frames = src.size() / audio_format.channels;
|
||||
|
||||
int bytes_out = twolame_encode_buffer_interleaved(options,
|
||||
src, num_frames,
|
||||
src.data(), num_frames,
|
||||
output_buffer,
|
||||
sizeof(output_buffer));
|
||||
if (bytes_out < 0)
|
||||
@ -206,8 +207,8 @@ TwolameEncoder::Write(const void *data, size_t length)
|
||||
output_buffer_position = 0;
|
||||
}
|
||||
|
||||
size_t
|
||||
TwolameEncoder::Read(void *dest, size_t length) noexcept
|
||||
std::span<const std::byte>
|
||||
TwolameEncoder::Read(std::span<std::byte> buffer) noexcept
|
||||
{
|
||||
assert(output_buffer_position <= output_buffer_length);
|
||||
|
||||
@ -224,14 +225,13 @@ TwolameEncoder::Read(void *dest, size_t length) noexcept
|
||||
|
||||
|
||||
const std::size_t remainning = output_buffer_length - output_buffer_position;
|
||||
if (length > remainning)
|
||||
length = remainning;
|
||||
const std::size_t nbytes = std::min(remainning, buffer.size());
|
||||
|
||||
memcpy(dest, output_buffer + output_buffer_position, length);
|
||||
memcpy(buffer.data(), output_buffer + output_buffer_position, nbytes);
|
||||
|
||||
output_buffer_position += length;
|
||||
output_buffer_position += nbytes;
|
||||
|
||||
return length;
|
||||
return buffer.first(nbytes);
|
||||
}
|
||||
|
||||
const EncoderPlugin twolame_encoder_plugin = {
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
void PreTag() override;
|
||||
void SendTag(const Tag &tag) override;
|
||||
|
||||
void Write(const void *data, size_t length) override;
|
||||
void Write(std::span<const std::byte> src) override;
|
||||
|
||||
private:
|
||||
void HeaderOut(vorbis_comment &vc);
|
||||
@ -245,14 +245,14 @@ interleaved_to_vorbis_buffer(float **dest, const float *src,
|
||||
}
|
||||
|
||||
void
|
||||
VorbisEncoder::Write(const void *data, size_t length)
|
||||
VorbisEncoder::Write(std::span<const std::byte> src)
|
||||
{
|
||||
std::size_t num_frames = length / audio_format.GetFrameSize();
|
||||
std::size_t num_frames = src.size() / audio_format.GetFrameSize();
|
||||
|
||||
/* this is for only 16-bit audio */
|
||||
|
||||
interleaved_to_vorbis_buffer(vorbis_analysis_buffer(&vd, num_frames),
|
||||
(const float *)data,
|
||||
(const float *)(const void *)src.data(),
|
||||
num_frames,
|
||||
audio_format.channels);
|
||||
|
||||
|
@ -36,10 +36,10 @@ public:
|
||||
explicit WaveEncoder(AudioFormat &audio_format) noexcept;
|
||||
|
||||
/* virtual methods from class Encoder */
|
||||
void Write(const void *data, size_t length) override;
|
||||
void Write(std::span<const std::byte> src) override;
|
||||
|
||||
size_t Read(void *dest, size_t length) noexcept override {
|
||||
return buffer.Read((std::byte *)dest, length);
|
||||
std::span<const std::byte> Read(std::span<std::byte> b) noexcept override {
|
||||
return b.first(buffer.Read(b.data(), b.size()));
|
||||
}
|
||||
};
|
||||
|
||||
@ -183,8 +183,9 @@ pcm24_to_wave(uint8_t *dst8, const uint32_t *src32, size_t length) noexcept
|
||||
}
|
||||
|
||||
void
|
||||
WaveEncoder::Write(const void *src, size_t length)
|
||||
WaveEncoder::Write(std::span<const std::byte> src)
|
||||
{
|
||||
std::size_t length = src.size();
|
||||
std::byte *dst = buffer.Write(length);
|
||||
|
||||
if (IsLittleEndian()) {
|
||||
@ -192,29 +193,33 @@ WaveEncoder::Write(const void *src, size_t length)
|
||||
case 8:
|
||||
case 16:
|
||||
case 32:// optimized cases
|
||||
memcpy(dst, src, length);
|
||||
memcpy(dst, src.data(), length);
|
||||
break;
|
||||
case 24:
|
||||
length = pcm24_to_wave((uint8_t *)dst,
|
||||
(const uint32_t *)src, length);
|
||||
(const uint32_t *)(const void *)src.data(),
|
||||
length);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (bits) {
|
||||
case 8:
|
||||
memcpy(dst, src, length);
|
||||
memcpy(dst, src.data(), length);
|
||||
break;
|
||||
case 16:
|
||||
length = pcm16_to_wave((uint16_t *)dst,
|
||||
(const uint16_t *)src, length);
|
||||
(const uint16_t *)(const void *)src.data(),
|
||||
length);
|
||||
break;
|
||||
case 24:
|
||||
length = pcm24_to_wave((uint8_t *)dst,
|
||||
(const uint32_t *)src, length);
|
||||
(const uint32_t *)(const void *)src.data(),
|
||||
length);
|
||||
break;
|
||||
case 32:
|
||||
length = pcm32_to_wave((uint32_t *)dst,
|
||||
(const uint32_t *)src, length);
|
||||
(const uint32_t *)(const void *)src.data(),
|
||||
length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -333,7 +333,7 @@ RecorderOutput::Play(const void *chunk, size_t size)
|
||||
return size;
|
||||
}
|
||||
|
||||
encoder->Write(chunk, size);
|
||||
encoder->Write({(const std::byte *)chunk, size});
|
||||
|
||||
EncoderToFile();
|
||||
|
||||
|
@ -326,12 +326,14 @@ static void
|
||||
EncoderToShout(shout_t *shout_conn, Encoder &encoder)
|
||||
{
|
||||
while (true) {
|
||||
uint8_t buffer[32768];
|
||||
size_t nbytes = encoder.Read(buffer, sizeof(buffer));
|
||||
if (nbytes == 0)
|
||||
std::byte buffer[32768];
|
||||
const auto e = encoder.Read(std::span{buffer});
|
||||
if (e.empty() == 0)
|
||||
return;
|
||||
|
||||
int err = shout_send(shout_conn, buffer, nbytes);
|
||||
int err = shout_send(shout_conn,
|
||||
(const unsigned char *)e.data(),
|
||||
e.size());
|
||||
HandleShoutError(shout_conn, err);
|
||||
}
|
||||
}
|
||||
@ -414,7 +416,7 @@ ShoutOutput::Delay() const noexcept
|
||||
size_t
|
||||
ShoutOutput::Play(const void *chunk, size_t size)
|
||||
{
|
||||
encoder->Write(chunk, size);
|
||||
encoder->Write({(const std::byte *)chunk, size});
|
||||
WritePage();
|
||||
return size;
|
||||
}
|
||||
@ -422,9 +424,9 @@ ShoutOutput::Play(const void *chunk, size_t size)
|
||||
bool
|
||||
ShoutOutput::Pause()
|
||||
{
|
||||
static char silence[1020];
|
||||
static std::byte silence[1020];
|
||||
|
||||
encoder->Write(silence, sizeof(silence));
|
||||
encoder->Write(std::span{silence});
|
||||
WritePage();
|
||||
|
||||
return true;
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <queue>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <span>
|
||||
|
||||
struct ConfigBlock;
|
||||
class EventLoop;
|
||||
@ -249,7 +250,7 @@ public:
|
||||
*
|
||||
* Throws on error.
|
||||
*/
|
||||
void EncodeAndPlay(const void *chunk, size_t size);
|
||||
void EncodeAndPlay(std::span<const std::byte> src);
|
||||
|
||||
void SendTag(const Tag &tag) override;
|
||||
|
||||
|
@ -161,14 +161,13 @@ HttpdOutput::ReadPage() noexcept
|
||||
|
||||
size_t size = 0;
|
||||
do {
|
||||
size_t nbytes = encoder->Read(buffer + size,
|
||||
sizeof(buffer) - size);
|
||||
if (nbytes == 0)
|
||||
const auto r = encoder->Read(std::span{buffer}.subspan(size));
|
||||
if (r.empty())
|
||||
break;
|
||||
|
||||
unflushed_input = 0;
|
||||
|
||||
size += nbytes;
|
||||
size += r.size();
|
||||
} while (size < sizeof(buffer));
|
||||
|
||||
if (size == 0)
|
||||
@ -301,11 +300,11 @@ HttpdOutput::BroadcastFromEncoder() noexcept
|
||||
}
|
||||
|
||||
inline void
|
||||
HttpdOutput::EncodeAndPlay(const void *chunk, size_t size)
|
||||
HttpdOutput::EncodeAndPlay(std::span<const std::byte> src)
|
||||
{
|
||||
encoder->Write(chunk, size);
|
||||
encoder->Write(src);
|
||||
|
||||
unflushed_input += size;
|
||||
unflushed_input += src.size();
|
||||
|
||||
BroadcastFromEncoder();
|
||||
}
|
||||
@ -316,7 +315,7 @@ HttpdOutput::Play(const void *chunk, size_t size)
|
||||
pause = false;
|
||||
|
||||
if (LockHasClients())
|
||||
EncodeAndPlay(chunk, size);
|
||||
EncodeAndPlay({(const std::byte *)chunk, size});
|
||||
|
||||
if (!timer->IsStarted())
|
||||
timer->Start();
|
||||
|
@ -128,9 +128,7 @@ ReadEncoder(Encoder &encoder) noexcept
|
||||
{
|
||||
std::byte buffer[4096];
|
||||
|
||||
size_t nbytes = encoder.Read(buffer, sizeof(buffer));
|
||||
const std::span<const std::byte> src{buffer, nbytes};
|
||||
return AllocatedArray<std::byte>{src};
|
||||
return AllocatedArray<std::byte>{encoder.Read(std::span{buffer})};
|
||||
}
|
||||
|
||||
inline void
|
||||
@ -313,7 +311,7 @@ SnapcastOutput::Play(const void *chunk, size_t size)
|
||||
if (!LockHasClients())
|
||||
return size;
|
||||
|
||||
encoder->Write(chunk, size);
|
||||
encoder->Write({(const std::byte *)chunk, size});
|
||||
unflushed_input += size;
|
||||
|
||||
if (unflushed_input >= 65536) {
|
||||
@ -332,8 +330,8 @@ SnapcastOutput::Play(const void *chunk, size_t size)
|
||||
while (true) {
|
||||
std::byte buffer[32768];
|
||||
|
||||
size_t nbytes = encoder->Read(buffer, sizeof(buffer));
|
||||
if (nbytes == 0)
|
||||
const auto payload = encoder->Read(std::span{buffer});
|
||||
if (payload.empty())
|
||||
break;
|
||||
|
||||
unflushed_input = 0;
|
||||
@ -342,7 +340,6 @@ SnapcastOutput::Play(const void *chunk, size_t size)
|
||||
if (chunks.empty())
|
||||
inject_event.Schedule();
|
||||
|
||||
const std::span<const std::byte> payload{buffer, nbytes};
|
||||
chunks.push(std::make_shared<SnapcastChunk>(now, AllocatedArray{payload}));
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,6 @@
|
||||
int main(int argc, char **argv)
|
||||
try {
|
||||
const char *encoder_name;
|
||||
static char buffer[32768];
|
||||
|
||||
/* parse command line */
|
||||
|
||||
@ -79,9 +78,10 @@ try {
|
||||
|
||||
/* do it */
|
||||
|
||||
static std::byte buffer[32768];
|
||||
ssize_t nbytes;
|
||||
while ((nbytes = read(0, buffer, sizeof(buffer))) > 0) {
|
||||
encoder->Write(buffer, nbytes);
|
||||
encoder->Write(std::span{buffer}.first(nbytes));
|
||||
EncoderToOutputStream(os, *encoder);
|
||||
}
|
||||
|
||||
|
@ -33,8 +33,6 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
static uint8_t zero[256];
|
||||
|
||||
int
|
||||
main([[maybe_unused]] int argc, [[maybe_unused]] char **argv)
|
||||
try {
|
||||
@ -61,7 +59,8 @@ try {
|
||||
|
||||
/* write a block of data */
|
||||
|
||||
encoder->Write(zero, sizeof(zero));
|
||||
static constexpr std::byte zero[256]{};
|
||||
encoder->Write(std::span{zero});
|
||||
|
||||
EncoderToOutputStream(os, *encoder);
|
||||
|
||||
@ -86,7 +85,7 @@ try {
|
||||
|
||||
/* write another block of data */
|
||||
|
||||
encoder->Write(zero, sizeof(zero));
|
||||
encoder->Write(std::span{zero});
|
||||
|
||||
/* finish */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user