mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 23:05:36 +08:00
[AFV] Optimize loading and sharing of CResourceSound objects
- Loading is now happening in a worker to not block the main thhread - The internal data is shared between all instances of the class.
This commit is contained in:
committed by
Mat Sutcliffe
parent
b65b2caa76
commit
ac833910c8
@@ -12,6 +12,7 @@
|
||||
#include "audioutilities.h"
|
||||
#include "blackmisc/fileutils.h"
|
||||
#include "blackmisc/stringutils.h"
|
||||
#include <QCoreApplication>
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackSound::Wav;
|
||||
@@ -20,30 +21,53 @@ namespace BlackSound
|
||||
{
|
||||
namespace SampleProvider
|
||||
{
|
||||
CResourceSound::CResourceSound()
|
||||
{
|
||||
m_data = new CResourceSoundData;
|
||||
}
|
||||
|
||||
CResourceSound::CResourceSound(const QString &audioFileName)
|
||||
{
|
||||
CWavFile wavFile;
|
||||
m_fn.clear();
|
||||
m_samples.clear();
|
||||
if (wavFile.open(audioFileName))
|
||||
m_data = new CResourceSoundData;
|
||||
m_data->fileName = audioFileName;
|
||||
}
|
||||
|
||||
bool CResourceSound::load()
|
||||
{
|
||||
if (m_data->fileName.isEmpty()) { return false; }
|
||||
|
||||
QObject *parent = QCoreApplication::instance();
|
||||
Q_ASSERT(parent);
|
||||
CWorker *worker = CWorker::fromTask(parent, "loadResourceSound", [this]()
|
||||
{
|
||||
if (wavFile.fileFormat().sampleType() == QAudioFormat::Float)
|
||||
CWavFile wavFile;
|
||||
|
||||
m_data->samples.clear();
|
||||
if (wavFile.open(m_data->fileName))
|
||||
{
|
||||
// Not implemented
|
||||
// m_samples = convertFloatBytesTo16BitPCM(wavFile.audioData());
|
||||
if (wavFile.fileFormat().sampleType() == QAudioFormat::Float)
|
||||
{
|
||||
// Not implemented
|
||||
// m_samples = convertFloatBytesTo16BitPCM(wavFile.audioData());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_data->samples = convertBytesTo32BitFloatPCM(wavFile.audioData());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_samples = convertBytesTo32BitFloatPCM(wavFile.audioData());
|
||||
}
|
||||
m_fn = audioFileName;
|
||||
}
|
||||
});
|
||||
worker->then([this]()
|
||||
{
|
||||
m_data->isLoaded = true;
|
||||
});
|
||||
|
||||
return worker ? true : false;
|
||||
}
|
||||
|
||||
bool CResourceSound::isSameFileName(const QString &fn) const
|
||||
{
|
||||
if (fn.isEmpty()) { return false; }
|
||||
return stringCompare(fn, m_fn, CFileUtils::osFileNameCaseSensitivity());
|
||||
return stringCompare(fn, m_data->fileName, CFileUtils::osFileNameCaseSensitivity());
|
||||
}
|
||||
} // ns
|
||||
} // ns
|
||||
|
||||
@@ -13,33 +13,53 @@
|
||||
|
||||
#include "blacksound/blacksoundexport.h"
|
||||
#include "blacksound/wav/wavfile.h"
|
||||
#include "blackmisc/worker.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
#include <QExplicitlySharedDataPointer>
|
||||
#include <atomic>
|
||||
|
||||
namespace BlackSound
|
||||
{
|
||||
namespace SampleProvider
|
||||
{
|
||||
|
||||
//! CResourceSound shared data
|
||||
struct CResourceSoundData : public QSharedData
|
||||
{
|
||||
QString fileName; //!< file name
|
||||
bool isLoaded = false; //!< is audio loaded
|
||||
QVector<float> samples; //!< audio samples
|
||||
};
|
||||
|
||||
//! File from resources
|
||||
class CResourceSound
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
CResourceSound();
|
||||
|
||||
//! Sound of audio file
|
||||
CResourceSound(const QString &audioFileName);
|
||||
|
||||
//! Load the attached resource file
|
||||
bool load();
|
||||
|
||||
//! Is resource already loaded?
|
||||
bool isLoaded() { return m_data->isLoaded; }
|
||||
|
||||
//! Audio data
|
||||
const QVector<float> &audioData() const { return m_samples; }
|
||||
const QVector<float> &audioData() const { return m_data->samples; }
|
||||
|
||||
//! Corresponding file
|
||||
const QString &getFileName() { return m_fn; }
|
||||
const QString &getFileName() { return m_data->fileName; }
|
||||
|
||||
//! Is same file?
|
||||
bool isSameFileName(const QString &fn) const;
|
||||
|
||||
private:
|
||||
QString m_fn; //!< file name
|
||||
QVector<float> m_samples;
|
||||
QExplicitlySharedDataPointer<CResourceSoundData> m_data;
|
||||
};
|
||||
} // ns
|
||||
} // ns
|
||||
|
||||
@@ -15,6 +15,8 @@ namespace BlackSound
|
||||
|
||||
int CResourceSoundSampleProvider::readSamples(QVector<float> &samples, qint64 count)
|
||||
{
|
||||
if (! m_resourceSound.isLoaded()) { return 0; }
|
||||
|
||||
if (count > m_tempBufferSize)
|
||||
{
|
||||
qDebug() << "Count too large for temp buffer" << count;
|
||||
|
||||
@@ -23,11 +23,7 @@ namespace BlackSound
|
||||
return samples;
|
||||
}
|
||||
|
||||
Samples::Samples() :
|
||||
m_crackle(CFileUtils::soundFilePathAndFileName(fnCrackle())),
|
||||
m_click(CFileUtils::soundFilePathAndFileName(fnClick())),
|
||||
m_whiteNoise(CFileUtils::soundFilePathAndFileName(fnWhiteNoise())),
|
||||
m_hfWhiteNoise(CFileUtils::soundFilePathAndFileName(fnHfWhiteNoise()))
|
||||
Samples::Samples()
|
||||
{
|
||||
this->initSounds();
|
||||
}
|
||||
@@ -36,13 +32,32 @@ namespace BlackSound
|
||||
{
|
||||
const CSettings settings = m_audioSettings.get();
|
||||
QString f = settings.getNotificationFilePath(fnCrackle());
|
||||
if (!m_crackle.isSameFileName(f)) { m_crackle = CResourceSound(f); }
|
||||
if (!m_crackle.isSameFileName(f))
|
||||
{
|
||||
m_crackle = CResourceSound(f);
|
||||
m_crackle.load();
|
||||
}
|
||||
|
||||
f = settings.getNotificationFilePath(fnClick());
|
||||
if (!m_click.isSameFileName(f)) { m_click = CResourceSound(f); }
|
||||
if (!m_click.isSameFileName(f))
|
||||
{
|
||||
m_click = CResourceSound(f);
|
||||
m_click.load();
|
||||
}
|
||||
|
||||
f = settings.getNotificationFilePath(fnWhiteNoise());
|
||||
if (!m_whiteNoise.isSameFileName(f)) { m_whiteNoise = CResourceSound(f); }
|
||||
if (!m_whiteNoise.isSameFileName(f))
|
||||
{
|
||||
m_whiteNoise = CResourceSound(f);
|
||||
m_whiteNoise.load();
|
||||
}
|
||||
|
||||
f = settings.getNotificationFilePath(fnHfWhiteNoise());
|
||||
if (!m_hfWhiteNoise.isSameFileName(f))
|
||||
{
|
||||
m_hfWhiteNoise = CResourceSound(f);
|
||||
m_hfWhiteNoise.load();
|
||||
}
|
||||
}
|
||||
|
||||
void Samples::onSettingsChanged()
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace BlackSound
|
||||
const CResourceSound &crackle() const { return m_crackle; }
|
||||
const CResourceSound &click() const { return m_click; }
|
||||
const CResourceSound &whiteNoise() const { return m_whiteNoise; }
|
||||
const CResourceSound hfWhiteNoise() const { return m_hfWhiteNoise; }
|
||||
const CResourceSound &hfWhiteNoise() const { return m_hfWhiteNoise; }
|
||||
//! @}
|
||||
|
||||
//! Play the click sound
|
||||
|
||||
Reference in New Issue
Block a user