19void QAmbientSoundPrivate::load()
21 decoder = std::make_unique<QAudioDecoder>();
24 sourceDeviceFile.reset(
nullptr);
28 auto *ep = QAudioEnginePrivate::get(engine);
30 f.setSampleFormat(QAudioFormat::Float);
31 f.setSampleRate(ep->sampleRate);
32 f.setChannelConfig(nchannels == 2 ? QAudioFormat::ChannelConfigStereo : QAudioFormat::ChannelConfigMono);
33 decoder->setAudioFormat(f);
34 if (url.scheme().compare(u"qrc", Qt::CaseInsensitive) == 0) {
35 auto qrcFile = std::make_unique<QFile>(u':' + url.path());
36 if (!qrcFile->open(QFile::ReadOnly))
38 sourceDeviceFile = std::move(qrcFile);
39 decoder->setSourceDevice(sourceDeviceFile.get());
41 decoder->setSource(url);
43 QObject::connect(decoder.get(), &QAudioDecoder::bufferReady, decoder.get(), [
this] {
46 QMutexLocker l(&mutex);
47 auto b = decoder->read();
52 QObject::connect(decoder.get(), &QAudioDecoder::finished, decoder.get(), [
this] {
58void QAmbientSoundPrivate::getBuffer(
float *buf,
int nframes,
int channels)
60 Q_ASSERT(channels == nchannels);
61 QMutexLocker l(&mutex);
62 if (!m_playing || currentBuffer >= buffers.size()) {
63 memset(buf, 0, channels * nframes *
sizeof(
float));
68 if (currentBuffer < buffers.size()) {
69 const QAudioBuffer &b = buffers.at(currentBuffer);
71 auto *f = b.constData<
float>() + bufPos*nchannels;
72 int toCopy = qMin(b.frameCount() - bufPos, frames);
73 memcpy(ff, f, toCopy*
sizeof(
float)*nchannels);
74 ff += toCopy*nchannels;
77 Q_ASSERT(bufPos <= b.frameCount());
78 if (bufPos == b.frameCount()) {
85 qDebug() <<
"underrun" << frames <<
"frames when loading" << url;
86 memset(ff, 0, frames * channels *
sizeof(
float));
87 ff += frames * channels;
91 if (currentBuffer == buffers.size()) {
95 if (m_loops > 0 && m_currentLoop >= m_loops) {
101 Q_ASSERT(ff - buf == channels*nframes);