126 constexpr int framesPerBuffer = qToUnderlying(QAudioEnginePrivate::framesPerBuffer);
127 static constexpr std::array<
float, 2 * framesPerBuffer> nullBuffer{};
129 if (d->m_paused.loadRelaxed())
132 QSpan<
short> outputBuffer((
short *)data, len /
sizeof(
short));
134 QMutexLocker l(&d->mutex);
136 int nChannels = ambisonicDecoder ? ambisonicDecoder->nOutputChannels() : 2;
137 if (outputBuffer.size() < nChannels * framesPerBuffer)
140 using QtMultimediaPrivate::drop;
141 using QtMultimediaPrivate::take;
142 using namespace QAudioHelperInternal;
144 const std::unique_ptr<vraudio::ResonanceAudioApi> &api = d->resonanceAudio->api;
147 while (outputBuffer.size() >= nChannels * framesPerBuffer) {
150 for (
auto &&[source, playbackState] : d->playbackStates) {
151 Q_ASSERT(source->nchannels <= 2);
153 Q_ASSERT(playbackState->format().channelCount() <= 2);
154 std::array<
float, 2 * framesPerBuffer> buf;
156 playbackState->getBuffer(
157 take(QSpan<
float>{ buf },
158 playbackState->format().channelCount() * framesPerBuffer));
159 api->SetInterleavedBuffer(source->sourceId, buf.data(), source->nchannels,
162 api->SetInterleavedBuffer(source->sourceId, nullBuffer.data(), source->nchannels,
167 if (ambisonicDecoder && d->outputMode() == QAudioEngine::Surround) {
168 std::array<
const float *, QAmbisonicDecoder::maxAmbisonicChannels> channels;
169 std::array<
const float *, 2> reverbBuffers{};
170 int nFrames = d->resonanceAudio->getAmbisonicOutput(
171 channels.data(), reverbBuffers.data(), ambisonicDecoder->nInputChannels());
177 std::fill(outputBuffer.begin(), outputBuffer.end(), 0);
181 Q_ASSERT(ambisonicDecoder->nOutputChannels() <= 8);
182 int nSamples = ambisonicDecoder->outputSamples(nFrames);
184 constexpr size_t reverbBufferSize =
185 framesPerBuffer * QAmbisonicDecoder::maxAmbisonicChannels;
186 std::array<
float, reverbBufferSize> reverbFloatBuffers;
187 QSpan<
float> reverbOutputSpan = take(QSpan{ reverbFloatBuffers }, nSamples);
188 QSpan<
short> currentOutput = take(outputBuffer, nSamples);
190 ambisonicDecoder->processBufferWithReverb(
191 QSpan{ channels.data(), ambisonicDecoder->nInputChannels() }, reverbBuffers,
194 convertSampleFormat(as_bytes(reverbOutputSpan), NativeSampleFormat::float32_t,
195 as_writable_bytes(currentOutput), NativeSampleFormat::int16_t);
196 outputBuffer = drop(outputBuffer, nSamples);
198 QSpan<
short> currentOutput = take(outputBuffer, nChannels * framesPerBuffer);
199 ok = d->resonanceAudio->api->FillInterleavedOutputBuffer(2, framesPerBuffer,
200 currentOutput.data());
205 if (d->playbackStates.empty()) {
206 std::fill(currentOutput.begin(), currentOutput.end(), 0);
209 qWarning() <<
" Reading failed!";
213 outputBuffer = drop(outputBuffer, nChannels * framesPerBuffer);
217 qint64 bytesProcessed = len - outputBuffer.size_bytes();
218 m_pos += bytesProcessed;
219 return bytesProcessed;