diff options
author | Chris Robinson <[email protected]> | 2022-05-12 09:22:22 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2022-05-13 15:40:15 -0700 |
commit | dbf5306828f811286feb7e45774cfc46b117da05 (patch) | |
tree | 1f3b85aa0801805bea5899382dc6970d221cbd2c | |
parent | d38d9b091eaae5e3d36fde64c597d2ec68370339 (diff) |
Use pw_buffer::requested in newer PipeWire versions
-rw-r--r-- | alc/backends/pipewire.cpp | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/alc/backends/pipewire.cpp b/alc/backends/pipewire.cpp index b573bd5a..165579b2 100644 --- a/alc/backends/pipewire.cpp +++ b/alc/backends/pipewire.cpp @@ -1308,32 +1308,42 @@ void PipeWirePlayback::outputCallback() pw_buffer *pw_buf{pw_stream_dequeue_buffer(mStream.get())}; if(unlikely(!pw_buf)) return; + const al::span<spa_data> datas{pw_buf->buffer->datas, + minu(mNumChannels, pw_buf->buffer->n_datas)}; +#if PW_CHECK_VERSION(0,3,49) + /* In 0.3.49, pw_buffer::requested specifies the number of samples needed + * by the resampler/graph for this audio update. + */ + uint length{static_cast<uint>(pw_buf->requested)}; +#else + /* In 0.3.48 and earlier, spa_io_rate_match::size apparently has the number + * of samples per update. + */ + uint length{mRateMatch ? mRateMatch->size : 0u}; +#endif + /* If no length is specified, use the device's update size as a fallback. */ + if(unlikely(!length)) length = mDevice->UpdateSize; + /* For planar formats, each datas[] seems to contain one channel, so store * the pointers in an array. Limit the render length in case the available * buffer length in any one channel is smaller than we wanted (shouldn't * be, but just in case). */ - spa_data *datas{pw_buf->buffer->datas}; - const size_t chancount{minu(mNumChannels, pw_buf->buffer->n_datas)}; - /* TODO: How many samples should actually be written? 'maxsize' can be 16k - * samples, which is excessive (~341ms @ 48khz). SPA_IO_RateMatch contains - * a 'size' field that apparently indicates how many samples should be - * written per update, but it's not obviously right. - */ - uint length{mRateMatch ? mRateMatch->size : mDevice->UpdateSize}; - for(size_t i{0};i < chancount;++i) + float **chanptr_end{mChannelPtrs.get()}; + for(const auto &data : datas) { - length = minu(length, datas[i].maxsize/sizeof(float)); - mChannelPtrs[i] = static_cast<float*>(datas[i].data); + length = minu(length, data.maxsize/sizeof(float)); + *chanptr_end = static_cast<float*>(data.data); + ++chanptr_end; } - mDevice->renderSamples({mChannelPtrs.get(), chancount}, length); + mDevice->renderSamples({mChannelPtrs.get(), chanptr_end}, length); - for(size_t i{0};i < chancount;++i) + for(const auto &data : datas) { - datas[i].chunk->offset = 0; - datas[i].chunk->stride = sizeof(float); - datas[i].chunk->size = length * sizeof(float); + data.chunk->offset = 0; + data.chunk->stride = sizeof(float); + data.chunk->size = length * sizeof(float); } pw_buf->size = length; pw_stream_queue_buffer(mStream.get(), pw_buf); |