18void QAmbientSoundPrivate::load()
20 decoder = std::make_unique<QAudioDecoder>();
23 sourceDeviceFile.reset(
nullptr);
27 auto *ep = QAudioEnginePrivate::get(engine);
29 f.setSampleFormat(QAudioFormat::Float);
30 f.setSampleRate(ep->sampleRate);
31 f.setChannelConfig(nchannels == 2 ? QAudioFormat::ChannelConfigStereo : QAudioFormat::ChannelConfigMono);
32 decoder->setAudioFormat(f);
33 if (url.scheme().compare(u"qrc", Qt::CaseInsensitive) == 0) {
34 auto qrcFile = std::make_unique<QFile>(u':' + url.path());
35 if (!qrcFile->open(QFile::ReadOnly))
37 sourceDeviceFile = std::move(qrcFile);
38 decoder->setSourceDevice(sourceDeviceFile.get());
40 decoder->setSource(url);
42 QObject::connect(decoder.get(), &QAudioDecoder::bufferReady, decoder.get(), [
this] {
45 QMutexLocker l(&mutex);
46 auto b = decoder->read();
51 QObject::connect(decoder.get(), &QAudioDecoder::finished, decoder.get(), [
this] {
57void QAmbientSoundPrivate::getBuffer(
float *buf,
int nframes,
int channels)
59 Q_ASSERT(channels == nchannels);
60 QMutexLocker l(&mutex);
61 if (!m_playing || currentBuffer >= buffers.size()) {
62 memset(buf, 0, channels * nframes *
sizeof(
float));
67 if (currentBuffer < buffers.size()) {
68 const QAudioBuffer &b = buffers.at(currentBuffer);
70 auto *f = b.constData<
float>() + bufPos*nchannels;
71 int toCopy = qMin(b.frameCount() - bufPos, frames);
72 memcpy(ff, f, toCopy*
sizeof(
float)*nchannels);
73 ff += toCopy*nchannels;
76 Q_ASSERT(bufPos <= b.frameCount());
77 if (bufPos == b.frameCount()) {
84 qDebug() <<
"underrun" << frames <<
"frames when loading" << url;
85 memset(ff, 0, frames * channels *
sizeof(
float));
86 ff += frames * channels;
90 if (currentBuffer == buffers.size()) {
94 if (m_loops > 0 && m_currentLoop >= m_loops) {
100 Q_ASSERT(ff - buf == channels*nframes);