Skip to content

Commit

Permalink
Support non-float samples for uninterleaved output
Browse files Browse the repository at this point in the history
  • Loading branch information
kcat committed Aug 10, 2024
1 parent fb1d521 commit e390383
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 23 deletions.
34 changes: 28 additions & 6 deletions alc/alu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2174,6 +2174,22 @@ void Write(const al::span<const FloatBufferLine> InBuffer, void *OutBuffer, cons
}
}

template<typename T>
void Write(const al::span<const FloatBufferLine> InBuffer, al::span<void*> OutBuffers,
const size_t Offset, const size_t SamplesToDo)
{
ASSUME(SamplesToDo > 0);

auto srcbuf = InBuffer.cbegin();
for(auto *dstbuf : OutBuffers)
{
const auto src = al::span{*srcbuf}.first(SamplesToDo);
const auto dst = al::span{static_cast<T*>(dstbuf), Offset+SamplesToDo}.subspan(Offset);
std::transform(src.cbegin(), src.end(), dst.begin(), SampleConv<T>);
++srcbuf;
}
}

} // namespace

uint DeviceBase::renderSamples(const uint numSamples)
Expand Down Expand Up @@ -2222,21 +2238,27 @@ uint DeviceBase::renderSamples(const uint numSamples)
return samplesToDo;
}

void DeviceBase::renderSamples(const al::span<float*> outBuffers, const uint numSamples)
void DeviceBase::renderSamples(const al::span<void*> outBuffers, const uint numSamples)
{
FPUCtl mixer_mode{};
uint total{0};
while(const uint todo{numSamples - total})
{
const uint samplesToDo{renderSamples(todo)};

auto srcbuf = RealOut.Buffer.cbegin();
for(auto *dstbuf : outBuffers)
switch(FmtType)
{
const auto dst = al::span{dstbuf, numSamples}.subspan(total);
std::copy_n(srcbuf->cbegin(), samplesToDo, dst.begin());
++srcbuf;
#define HANDLE_WRITE(T) case T: \
Write<DevFmtType_t<T>>(RealOut.Buffer, outBuffers, total, samplesToDo); break;
HANDLE_WRITE(DevFmtByte)
HANDLE_WRITE(DevFmtUByte)
HANDLE_WRITE(DevFmtShort)
HANDLE_WRITE(DevFmtUShort)
HANDLE_WRITE(DevFmtInt)
HANDLE_WRITE(DevFmtUInt)
HANDLE_WRITE(DevFmtFloat)
}
#undef HANDLE_WRITE

total += samplesToDo;
}
Expand Down
10 changes: 5 additions & 5 deletions alc/backends/jack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,22 +329,22 @@ JackPlayback::~JackPlayback()

int JackPlayback::processRt(jack_nframes_t numframes) noexcept
{
auto outptrs = std::array<jack_default_audio_sample_t*,MaxOutputChannels>{};
auto outptrs = std::array<void*,MaxOutputChannels>{};
auto numchans = size_t{0};
for(auto port : mPort)
{
if(!port || numchans == mDevice->RealOut.Buffer.size())
break;
outptrs[numchans++] = static_cast<float*>(jack_port_get_buffer(port, numframes));
outptrs[numchans++] = jack_port_get_buffer(port, numframes);
}

const auto dst = al::span{outptrs}.first(numchans);
if(mPlaying.load(std::memory_order_acquire)) LIKELY
mDevice->renderSamples(dst, static_cast<uint>(numframes));
else
{
std::for_each(dst.begin(), dst.end(), [numframes](float *outbuf) -> void
{ std::fill_n(outbuf, numframes, 0.0f); });
std::for_each(dst.begin(), dst.end(), [numframes](void *outbuf) -> void
{ std::fill_n(static_cast<float*>(outbuf), numframes, 0.0f); });
}

return 0;
Expand Down Expand Up @@ -416,7 +416,7 @@ int JackPlayback::mixerProc()

const auto update_size = uint{mDevice->UpdateSize};
const auto num_channels = size_t{mDevice->channelsFromFmt()};
auto outptrs = std::vector<float*>(num_channels);
auto outptrs = std::vector<void*>(num_channels);

while(!mKillNow.load(std::memory_order_acquire)
&& mDevice->Connected.load(std::memory_order_acquire))
Expand Down
4 changes: 2 additions & 2 deletions alc/backends/pipewire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1432,7 +1432,7 @@ class PipeWirePlayback final : public BackendBase {
PwStreamPtr mStream;
spa_hook mStreamListener{};
spa_io_rate_match *mRateMatch{};
std::vector<float*> mChannelPtrs;
std::vector<void*> mChannelPtrs;

static constexpr pw_stream_events CreateEvents()
{
Expand Down Expand Up @@ -1503,7 +1503,7 @@ void PipeWirePlayback::outputCallback() noexcept
for(const auto &data : datas)
{
length = std::min(length, data.maxsize/uint{sizeof(float)});
*chanptr_end = static_cast<float*>(data.data);
*chanptr_end = data.data;
++chanptr_end;

data.chunk->offset = 0;
Expand Down
18 changes: 9 additions & 9 deletions alc/backends/wasapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1253,8 +1253,8 @@ FORCE_ALIGN int WasapiPlayback::mixerSpatialProc()
althrd_setname(GetMixerThreadName());

std::vector<ComPtr<ISpatialAudioObject>> channels;
std::vector<float*> buffers;
std::vector<float*> resbuffers;
std::vector<void*> buffers;
std::vector<void*> resbuffers;
std::vector<const void*> tmpbuffers;

/* TODO: Set mPadding appropriately. There doesn't seem to be a way to
Expand Down Expand Up @@ -1304,7 +1304,7 @@ FORCE_ALIGN int WasapiPlayback::mixerSpatialProc()
auto bufptr = mResampleBuffer.begin();
for(size_t i{0};i < tmpbuffers.size();++i)
{
resbuffers[i] = reinterpret_cast<float*>(al::to_address(bufptr));
resbuffers[i] = al::to_address(bufptr);
bufptr += ptrdiff_t(mDevice->UpdateSize*sizeof(float));
}
}
Expand All @@ -1314,12 +1314,12 @@ FORCE_ALIGN int WasapiPlayback::mixerSpatialProc()
* update, unfortunately.
*/
std::transform(channels.cbegin(), channels.cend(), buffers.begin(),
[](const ComPtr<ISpatialAudioObject> &obj) -> float*
[](const ComPtr<ISpatialAudioObject> &obj) -> void*
{
BYTE *buffer{};
UINT32 size{};
auto buffer = LPBYTE{};
auto size = UINT32{};
obj->GetBuffer(&buffer, &size);
return reinterpret_cast<float*>(buffer);
return buffer;
});

if(!mResampler)
Expand All @@ -1337,9 +1337,9 @@ FORCE_ALIGN int WasapiPlayback::mixerSpatialProc()
}

const uint got{mResampler->convertPlanar(tmpbuffers.data(), &mBufferFilled,
reinterpret_cast<void*const*>(buffers.data()), framesToDo-pos)};
buffers.data(), framesToDo-pos)};
for(auto &buf : buffers)
buf += got; /* NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) */
buf = static_cast<float*>(buf) + got; /* NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) */
pos += got;
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ struct SIMDALIGN DeviceBase {
inline void postProcess(const std::size_t SamplesToDo)
{ if(PostProcess) LIKELY (this->*PostProcess)(SamplesToDo); }

void renderSamples(const al::span<float*> outBuffers, const uint numSamples);
void renderSamples(const al::span<void*> outBuffers, const uint numSamples);
void renderSamples(void *outBuffer, const uint numSamples, const std::size_t frameStep);

/* Caller must lock the device state, and the mixer must not be running. */
Expand Down

0 comments on commit e390383

Please sign in to comment.