diff options
author | Chris Robinson <[email protected]> | 2019-06-23 17:08:52 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2019-06-23 17:08:52 -0700 |
commit | b46fc572f598bfa917c8cd7f3c099cb218962dd1 (patch) | |
tree | 5fe207813a772c90646b64a00b60161cc0f9e112 /Alc/backends | |
parent | ee983bda75f341742b30dd205fbb88e962af54f6 (diff) |
Use spans to handle pulseaudio capture buffers
Diffstat (limited to 'Alc/backends')
-rw-r--r-- | Alc/backends/pulseaudio.cpp | 66 |
1 files changed, 36 insertions, 30 deletions
diff --git a/Alc/backends/pulseaudio.cpp b/Alc/backends/pulseaudio.cpp index 6d4f387c..a19663eb 100644 --- a/Alc/backends/pulseaudio.cpp +++ b/Alc/backends/pulseaudio.cpp @@ -1117,11 +1117,11 @@ struct PulseCapture final : public BackendBase { std::string mDeviceName; - const void *mCapStore{nullptr}; - size_t mCapLen{0u}; - size_t mCapRemain{0u}; - ALCuint mLastReadable{0u}; + al::byte mSilentVal{}; + + al::span<const al::byte> mCapBuffer; + ssize_t mCapLen{0}; pa_buffer_attr mAttr{}; pa_sample_spec mSpec{}; @@ -1247,6 +1247,7 @@ ALCenum PulseCapture::open(const ALCchar *name) switch(mDevice->FmtType) { case DevFmtUByte: + mSilentVal = al::byte(0x80); mSpec.format = PA_SAMPLE_U8; break; case DevFmtShort: @@ -1317,15 +1318,15 @@ void PulseCapture::stop() ALCenum PulseCapture::captureSamples(ALCvoid *buffer, ALCuint samples) { - ALCuint todo{samples * static_cast<ALCuint>(pa_frame_size(&mSpec))}; + al::span<al::byte> dstbuf{static_cast<al::byte*>(buffer), samples * pa_frame_size(&mSpec)}; /* Capture is done in fragment-sized chunks, so we loop until we get all * that's available */ - mLastReadable -= todo; + mLastReadable -= dstbuf.size(); std::lock_guard<std::mutex> _{pulse_lock}; - while(todo > 0) + while(!dstbuf.empty()) { - if(mCapLen == 0) + if(mCapBuffer.empty()) { if(UNLIKELY(!mDevice->Connected.load(std::memory_order_acquire))) break; @@ -1335,43 +1336,45 @@ ALCenum PulseCapture::captureSamples(ALCvoid *buffer, ALCuint samples) aluHandleDisconnect(mDevice, "Bad capture state: %u", state); break; } - if(UNLIKELY(pa_stream_peek(mStream, &mCapStore, &mCapLen) < 0)) + const void *capbuf; + size_t caplen; + if(UNLIKELY(pa_stream_peek(mStream, &capbuf, &caplen) < 0)) { aluHandleDisconnect(mDevice, "Failed retrieving capture samples: %s", - pa_strerror(pa_context_errno(mContext))); + pa_strerror(pa_context_errno(mContext))); break; } - if(mCapLen == 0) break; - mCapRemain = mCapLen; + if(caplen == 0) break; + if(UNLIKELY(!capbuf)) + mCapLen = -static_cast<ssize_t>(caplen); + else + mCapLen = static_cast<ssize_t>(caplen); + mCapBuffer = {static_cast<const al::byte*>(capbuf), caplen}; } - const size_t rem{minz(todo, mCapRemain)}; - if(LIKELY(mCapStore)) - memcpy(buffer, mCapStore, rem); + const size_t rem{minz(dstbuf.size(), mCapBuffer.size())}; + if(UNLIKELY(mCapLen < 0)) + std::fill_n(dstbuf.begin(), rem, mSilentVal); else - memset(buffer, ((mDevice->FmtType==DevFmtUByte) ? 0x80 : 0), rem); - - buffer = static_cast<ALbyte*>(buffer) + rem; - todo -= rem; + std::copy_n(mCapBuffer.begin(), rem, dstbuf.begin()); + dstbuf = dstbuf.subspan(rem); + mCapBuffer = mCapBuffer.subspan(rem); - if(LIKELY(mCapStore)) - mCapStore = reinterpret_cast<const ALbyte*>(mCapStore) + rem; - mCapRemain -= rem; - if(mCapRemain == 0) + if(mCapBuffer.empty()) { pa_stream_drop(mStream); mCapLen = 0; } } - if(todo > 0) - memset(buffer, ((mDevice->FmtType==DevFmtUByte) ? 0x80 : 0), todo); + if(!dstbuf.empty()) + std::fill(dstbuf.begin(), dstbuf.end(), mSilentVal); return ALC_NO_ERROR; } ALCuint PulseCapture::availableSamples() { - size_t readable{mCapRemain}; + size_t readable{mCapBuffer.size()}; if(mDevice->Connected.load(std::memory_order_acquire)) { @@ -1382,12 +1385,15 @@ ALCuint PulseCapture::availableSamples() ERR("pa_stream_readable_size() failed: %s\n", pa_strerror(got)); aluHandleDisconnect(mDevice, "Failed getting readable size: %s", pa_strerror(got)); } - else if(got > mCapLen) - readable += got - mCapLen; + else + { + const auto caplen = static_cast<size_t>(std::abs(mCapLen)); + if(got > caplen) readable += got - caplen; + } } - if(mLastReadable < readable) - mLastReadable = readable; + readable = std::min<size_t>(readable, std::numeric_limits<ALCuint>::max()); + mLastReadable = std::max(mLastReadable, static_cast<ALCuint>(readable)); return mLastReadable / pa_frame_size(&mSpec); } |