129 if (d->m_paused.loadRelaxed())
132 constexpr auto framesPerBuffer = QAudioEngineThreaded::framesPerBuffer;
133 QSpan<
short> outputBuffer((
short *)data, len /
sizeof(
short));
135 QMutexLocker l(&d->mutex);
137 int nChannels = ambisonicDecoder ? ambisonicDecoder->nOutputChannels() : 2;
138 if (outputBuffer.size() < nChannels * framesPerBuffer)
141 using QtMultimediaPrivate::drop;
142 using QtMultimediaPrivate::take;
143 using namespace QAudioHelperInternal;
145 const std::unique_ptr<vraudio::ResonanceAudioApi> &api = d->resonanceAudio->api;
148 while (outputBuffer.size() >= nChannels * framesPerBuffer) {
151 for (
auto &&[source, playbackState] : d->playbackStates) {
152 Q_ASSERT(source->nchannels <= 2);
154 Q_ASSERT(playbackState->format().channelCount() <= 2);
155 std::array<
float, 2 * framesPerBuffer> buf;
157 playbackState->getBuffer(
158 take(QSpan<
float>{ buf },
159 playbackState->format().channelCount() * framesPerBuffer));
160 api->SetInterleavedBuffer(source->sourceId, buf.data(), source->nchannels,
163 api->SetInterleavedBuffer(source->sourceId, nullBuffer.data(), source->nchannels,
168 if (ambisonicDecoder && d->outputMode() == QAudioEngine::Surround) {
169 std::array<
const float *, QAmbisonicDecoder::maxAmbisonicChannels> channels;
170 std::array<
const float *, 2> reverbBuffers{};
171 int nFrames = d->resonanceAudio->getAmbisonicOutput(
172 channels.data(), reverbBuffers.data(), ambisonicDecoder->nInputChannels());
178 std::fill(outputBuffer.begin(), outputBuffer.end(), 0);
182 Q_ASSERT(ambisonicDecoder->nOutputChannels() <= 8);
183 int nSamples = ambisonicDecoder->outputSamples(nFrames);
185 constexpr size_t reverbBufferSize =
186 framesPerBuffer * QAmbisonicDecoder::maxAmbisonicChannels;
187 std::array<
float, reverbBufferSize> reverbFloatBuffers;
188 QSpan<
float> reverbOutputSpan = take(QSpan{ reverbFloatBuffers }, nSamples);
189 QSpan<
short> currentOutput = take(outputBuffer, nSamples);
191 ambisonicDecoder->processBufferWithReverb(
192 QSpan{ channels.data(), ambisonicDecoder->nInputChannels() }, reverbBuffers,
195 convertSampleFormat(as_bytes(reverbOutputSpan), NativeSampleFormat::float32_t,
196 as_writable_bytes(currentOutput), NativeSampleFormat::int16_t);
197 outputBuffer = drop(outputBuffer, nSamples);
199 QSpan<
short> currentOutput = take(outputBuffer, nChannels * framesPerBuffer);
200 ok = d->resonanceAudio->api->FillInterleavedOutputBuffer(2, framesPerBuffer,
201 currentOutput.data());
206 if (d->playbackStates.empty()) {
207 std::fill(currentOutput.begin(), currentOutput.end(), 0);
210 qWarning() <<
" Reading failed!";
214 outputBuffer = drop(outputBuffer, nChannels * framesPerBuffer);
218 qint64 bytesProcessed = len - outputBuffer.size_bytes();
219 m_pos += bytesProcessed;
220 return bytesProcessed;