18void QAmbientSoundPrivate::load()
20 decoder = std::make_unique<QAudioDecoder>();
21 sourceDeviceFile.reset(
nullptr);
23 QMutexLocker l(&mutex);
31 auto *ep = QAudioEnginePrivate::get(engine);
33 f.setSampleFormat(QAudioFormat::Float);
34 f.setSampleRate(ep->sampleRate());
35 f.setChannelConfig(nchannels == 2 ? QAudioFormat::ChannelConfigStereo : QAudioFormat::ChannelConfigMono);
36 decoder->setAudioFormat(f);
37 if (url.scheme().compare(u"qrc", Qt::CaseInsensitive) == 0) {
38 auto qrcFile = std::make_unique<QFile>(u':' + url.path());
39 if (!qrcFile->open(QFile::ReadOnly))
41 sourceDeviceFile = std::move(qrcFile);
42 decoder->setSourceDevice(sourceDeviceFile.get());
44 decoder->setSource(url);
46 QObject::connect(decoder.get(), &QAudioDecoder::bufferReady, decoder.get(), [
this] {
49 QMutexLocker l(&mutex);
50 auto b = decoder->read();
55 QObject::connect(decoder.get(), &QAudioDecoder::finished, decoder.get(), [
this] {
61void QAmbientSoundPrivate::getBuffer(
float *buf,
int nframes,
int channels)
63 Q_ASSERT(channels == nchannels);
64 QMutexLocker l(&mutex);
65 if (!m_playing || currentBuffer >= buffers.size()) {
66 memset(buf, 0, channels * nframes *
sizeof(
float));
71 if (currentBuffer < buffers.size()) {
72 const QAudioBuffer &b = buffers.at(currentBuffer);
74 auto *f = b.constData<
float>() + bufPos*nchannels;
75 int toCopy = qMin(b.frameCount() - bufPos, frames);
76 memcpy(ff, f, toCopy*
sizeof(
float)*nchannels);
77 ff += toCopy*nchannels;
80 Q_ASSERT(bufPos <= b.frameCount());
81 if (bufPos == b.frameCount()) {
88 qDebug() <<
"underrun" << frames <<
"frames when loading" << url;
89 memset(ff, 0, frames * channels *
sizeof(
float));
90 ff += frames * channels;
94 if (currentBuffer == buffers.size()) {
98 if (m_loops > 0 && m_currentLoop >= m_loops) {
104 Q_ASSERT(ff - buf == channels*nframes);