#include "miniaudio.h" #include "sound_manager.h" #include #include 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); }