23void QAmbientSoundPrivate::load()
25 decoder = std::make_unique<QAudioDecoder>();
26 sourceDeviceFile.reset(
nullptr);
28 QMutexLocker l(&mutex);
36 auto *ep = QAudioEnginePrivate::get(engine);
38 f.setSampleFormat(QAudioFormat::Float);
39 f.setSampleRate(ep->sampleRate());
40 f.setChannelConfig(nchannels == 2 ? QAudioFormat::ChannelConfigStereo : QAudioFormat::ChannelConfigMono);
41 decoder->setAudioFormat(f);
43 QUrl url = m_sourceResolver->resolve(m_url);
44 if (url.scheme().compare(u"qrc", Qt::CaseInsensitive) == 0) {
45 auto qrcFile = std::make_unique<QFile>(u':' + url.path());
46 if (!qrcFile->open(QFile::ReadOnly))
48 sourceDeviceFile = std::move(qrcFile);
49 decoder->setSourceDevice(sourceDeviceFile.get());
51 decoder->setSource(url);
53 QObject::connect(decoder.get(), &QAudioDecoder::bufferReady, decoder.get(), [
this] {
56 QMutexLocker l(&mutex);
57 auto b = decoder->read();
62 QObject::connect(decoder.get(), &QAudioDecoder::finished, decoder.get(), [
this] {
68void QAmbientSoundPrivate::getBuffer(
float *buf,
int nframes,
int channels)
70 Q_ASSERT(channels == nchannels);
71 QMutexLocker l(&mutex);
72 if (!m_playing || currentBuffer >= buffers.size()) {
73 memset(buf, 0, channels * nframes *
sizeof(
float));
78 if (currentBuffer < buffers.size()) {
79 const QAudioBuffer &b = buffers.at(currentBuffer);
81 auto *f = b.constData<
float>() + bufPos*nchannels;
82 int toCopy = qMin(b.frameCount() - bufPos, frames);
83 memcpy(ff, f, toCopy*
sizeof(
float)*nchannels);
84 ff += toCopy*nchannels;
87 Q_ASSERT(bufPos <= b.frameCount());
88 if (bufPos == b.frameCount()) {
95 qDebug() <<
"underrun" << frames <<
"frames when loading" << url();
96 memset(ff, 0, frames * channels *
sizeof(
float));
97 ff += frames * channels;
101 if (currentBuffer == buffers.size()) {
105 if (m_loops > 0 && m_currentLoop >= m_loops) {
111 Q_ASSERT(ff - buf == channels*nframes);