You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

131 lines
3.6 KiB

#include "miniaudio.h"
#include "sound_manager.h"
#include <QFile>
#include <QDebug>
SoundManager* SoundManager::instance() {
static SoundManager s;
return &s;
}
SoundManager::~SoundManager() { shutdown(); }
bool SoundManager::init() {
if (m_initialized) return true;
ma_engine* engine = new ma_engine;
ma_result result = ma_engine_init(NULL, engine);
if (result != MA_SUCCESS) {
qWarning("SoundManager: ma_engine_init failed (%d)", result);
delete engine;
return false;
}
m_engine = engine;
m_initialized = true;
qDebug("SoundManager: initialized");
return true;
}
void SoundManager::shutdown() {
if (!m_initialized) return;
for (auto it = m_sounds.begin(); it != m_sounds.end(); ++it) {
if (it->sound) {
ma_sound_uninit(it->sound);
delete it->sound;
}
if (it->decoder) {
ma_decoder_uninit(it->decoder);
delete it->decoder;
}
}
m_sounds.clear();
if (m_engine) {
ma_engine_uninit(m_engine);
delete m_engine;
m_engine = nullptr;
}
m_initialized = false;
qDebug("SoundManager: shutdown");
}
void SoundManager::setEnabled(bool enabled) {
m_enabled = enabled;
qDebug("SoundManager: enabled=%d", enabled);
}
bool SoundManager::isEnabled() const { return m_enabled; }
void SoundManager::setVolume(float volume) {
if (volume < 0.0f) volume = 0.0f;
if (volume > 1.0f) volume = 1.0f;
m_volume = volume;
for (auto it = m_sounds.begin(); it != m_sounds.end(); ++it) {
if (it->sound)
ma_sound_set_volume(it->sound, m_volume);
}
}
float SoundManager::volume() const { return m_volume; }
bool SoundManager::loadSound(const QString& name, const QString& qrcPath) {
if (!m_initialized) {
qWarning("SoundManager: not initialized, cannot load %s", qPrintable(name));
return false;
}
if (m_sounds.contains(name)) {
qWarning("SoundManager: sound '%s' already loaded", qPrintable(name));
return false;
}
QFile f(qrcPath);
if (!f.open(QIODevice::ReadOnly)) {
qWarning("SoundManager: cannot open %s", qPrintable(qrcPath));
return false;
}
LoadedSound ls;
ls.mp3Data = f.readAll();
f.close();
ls.decoder = new ma_decoder;
ma_decoder_config decConfig = ma_decoder_config_init_default();
ma_result result = ma_decoder_init_memory(ls.mp3Data.constData(), ls.mp3Data.size(),
&decConfig, ls.decoder);
if (result != MA_SUCCESS) {
qWarning("SoundManager: ma_decoder_init_memory failed for %s (%d)", qPrintable(name), result);
delete ls.decoder;
return false;
}
ls.sound = new ma_sound;
result = ma_sound_init_from_data_source(m_engine, (ma_data_source*)&ls.decoder->ds,
0, NULL, ls.sound);
if (result != MA_SUCCESS) {
qWarning("SoundManager: sound init failed for %s (%d)", qPrintable(name), result);
ma_decoder_uninit(ls.decoder);
delete ls.decoder;
delete ls.sound;
return false;
}
ma_sound_set_volume(ls.sound, m_volume);
m_sounds.insert(name, ls);
qDebug("SoundManager: loaded '%s' from %s (%lld bytes)",
qPrintable(name), qPrintable(qrcPath), (long long)ls.mp3Data.size());
return true;
}
void SoundManager::play(const QString& name) {
if (!m_enabled || !m_initialized) return;
auto it = m_sounds.find(name);
if (it == m_sounds.end()) return;
ma_sound* s = it->sound;
ma_sound_stop(s);
ma_sound_seek_to_pcm_frame(s, 0);
ma_sound_start(s);
}