31 using QtMultimediaPrivate::drop;
32 using QtMultimediaPrivate::take;
33 namespace ranges = QtMultimediaPrivate::ranges;
35 if (!m_playing.load(std::memory_order_relaxed)) {
36 ranges::fill(output, 0.f);
40 QSpan<
const float> wholeSampleBuffer{
41 m_buffer.constData<
float>(),
42 m_buffer.sampleCount(),
45 while (!output.empty()) {
46 QSpan remainingSamples = drop(wholeSampleBuffer, m_currentSample);
47 const QSpan samplesToCopy = take(remainingSamples, output.size());
48 ranges::copy(samplesToCopy, output.begin());
49 output = drop(output, samplesToCopy.size());
50 m_currentSample += samplesToCopy.size();
56 Q_ASSERT(m_currentSample == wholeSampleBuffer.size());
65 ranges::fill(output, 0.f);
69 if (m_currentLoop >= m_loops) {
72 ranges::fill(output, 0.f);
210 auto *ep = QAudioEnginePrivate::get(engine);
214 m_loadFuture.cancelChain();
219 m_loadFuture = QSampleCache::instance()
220 ->requestSampleFuture(m_sourceResolver->resolve(url), ep->sampleRate())
221 .then(q_ptr, [
this](SharedSamplePtr sample) {
223 qWarning() <<
"QAmbientSound: cannot load file";
230 const QAudioFormat &srcFmt = sample->format();
231 const int srcChannels = srcFmt.channelCount();
234 QAudioFormat outFmt = srcFmt;
235 outFmt.setChannelCount(nchannels);
236 outFmt.setChannelConfig(nchannels == 2 ? QAudioFormat::ChannelConfigStereo
237 : QAudioFormat::ChannelConfigMono);
239 using namespace QAudioHelperInternal;
241 if (srcChannels == nchannels) {
242 pcmData = sample->data();
244 m_sample = std::move(sample);
245 }
else if (srcChannels == 1 && nchannels == 2) {
246 qWarning() <<
"QAmbientSound: upmixing mono source to stereo";
247 pcmData = upmixMonoToStereo(sample->dataAsFloatSpan(), UpmixScaling::Duplicate);
248 }
else if (srcChannels == 2 && nchannels == 1) {
249 qWarning() <<
"QAmbientSound: downmixing stereo source to mono";
250 pcmData = downmixStereoToMono(sample->dataAsFloatSpan(), DownmixScaling::Average);
252 qWarning() <<
"QAmbientSound: unsupported channel count"
253 << srcChannels <<
"- rejecting file";
257 m_buffer = QAudioBuffer{
262 const bool startingPlayback = m_autoPlay || m_state != State::Stopped;
263 if (!startingPlayback)
265 const bool startPaused = (m_state == State::Paused) && !m_autoPlay;
266 setState(std::make_shared<QSpatialAudioPlaybackState>(*m_buffer, !startPaused,
269 m_state = startPaused ? State::Paused : State::Playing;