128 constexpr int framesPerBuffer = qToUnderlying(QAudioEnginePrivate::framesPerBuffer);
129 static constexpr std::array<
float, 2 * framesPerBuffer> nullBuffer{};
131 if (d->m_paused.loadRelaxed())
134 QSpan<
short> outputBuffer((
short *)data, len /
sizeof(
short));
136 QMutexLocker l(&d->mutex);
138 int nChannels = ambisonicDecoder ? ambisonicDecoder->nOutputChannels() : 2;
139 if (outputBuffer.size() < nChannels * framesPerBuffer)
142 using QtMultimediaPrivate::drop;
143 using QtMultimediaPrivate::take;
144 using namespace QAudioHelperInternal;
146 const std::unique_ptr<vraudio::ResonanceAudioApi> &api = d->resonanceAudio->api;
149 while (outputBuffer.size() >= nChannels * framesPerBuffer) {
152 for (
auto &&[source, playbackState] : d->playbackStates) {
153 Q_ASSERT(source->nchannels <= 2);
155 Q_ASSERT(playbackState->format().channelCount() <= 2);
156 std::array<
float, 2 * framesPerBuffer> buf;
158 playbackState->getBuffer(
159 take(QSpan<
float>{ buf },
160 playbackState->format().channelCount() * framesPerBuffer));
161 api->SetInterleavedBuffer(source->sourceId, buf.data(), source->nchannels,
164 api->SetInterleavedBuffer(source->sourceId, nullBuffer.data(), source->nchannels,
169 if (ambisonicDecoder && d->outputMode() == QAudioEngine::Surround) {
170 std::array<
const float *, QAmbisonicDecoder::maxAmbisonicChannels> channels;
171 std::array<
const float *, 2> reverbBuffers{};
172 int nFrames = d->resonanceAudio->getAmbisonicOutput(
173 channels.data(), reverbBuffers.data(), ambisonicDecoder->nInputChannels());
179 std::fill(outputBuffer.begin(), outputBuffer.end(), 0);
183 Q_ASSERT(ambisonicDecoder->nOutputChannels() <= 8);
184 int nSamples = ambisonicDecoder->outputSamples(nFrames);
186 constexpr size_t reverbBufferSize =
187 framesPerBuffer * QAmbisonicDecoder::maxAmbisonicChannels;
188 std::array<
float, reverbBufferSize> reverbFloatBuffers;
189 QSpan<
float> reverbOutputSpan = take(QSpan{ reverbFloatBuffers }, nSamples);
190 QSpan<
short> currentOutput = take(outputBuffer, nSamples);
192 ambisonicDecoder->processBufferWithReverb(
193 QSpan{ channels.data(), ambisonicDecoder->nInputChannels() }, reverbBuffers,
196 convertSampleFormat(as_bytes(reverbOutputSpan), NativeSampleFormat::float32_t,
197 as_writable_bytes(currentOutput), NativeSampleFormat::int16_t);
198 outputBuffer = drop(outputBuffer, nSamples);
200 QSpan<
short> currentOutput = take(outputBuffer, nChannels * framesPerBuffer);
201 ok = d->resonanceAudio->api->FillInterleavedOutputBuffer(2, framesPerBuffer,
202 currentOutput.data());
207 if (d->playbackStates.empty()) {
208 std::fill(currentOutput.begin(), currentOutput.end(), 0);
211 qWarning() <<
" Reading failed!";
215 outputBuffer = drop(outputBuffer, nChannels * framesPerBuffer);
219 qint64 bytesProcessed = len - outputBuffer.size_bytes();
220 m_pos += bytesProcessed;
221 return bytesProcessed;