/* Minetest Copyright (C) 2023 DS This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "proxy_sound_manager.h" #include "filesys.h" namespace sound { ProxySoundManager::MsgResult ProxySoundManager::handleMsg(SoundManagerMsgToProxy &&msg) { using namespace sound_manager_messages_to_proxy; return std::visit([&](auto &&msg) { using T = std::decay_t; if constexpr (std::is_same_v) return MsgResult::Empty; else if constexpr (std::is_same_v) reportRemovedSound(msg.id); else if constexpr (std::is_same_v) return MsgResult::Stopped; return MsgResult::Ok; }, std::move(msg)); } ProxySoundManager::~ProxySoundManager() { if (m_sound_manager.isRunning()) { send(sound_manager_messages_to_mgr::PleaseStop{}); // recv until it stopped auto recv = [&] { return m_sound_manager.m_queue_to_proxy.pop_frontNoEx(); }; while (true) { if (handleMsg(recv()) == MsgResult::Stopped) break; } // join m_sound_manager.stop(); SANITY_CHECK(m_sound_manager.wait()); } } void ProxySoundManager::step(f32 dtime) { auto recv = [&] { return m_sound_manager.m_queue_to_proxy.pop_frontNoEx(0); }; while (true) { MsgResult res = handleMsg(recv()); if (res == MsgResult::Empty) break; else if (res == MsgResult::Stopped) throw std::runtime_error("OpenALSoundManager stopped unexpectedly"); } } void ProxySoundManager::pauseAll() { send(sound_manager_messages_to_mgr::PauseAll{}); } void ProxySoundManager::resumeAll() { send(sound_manager_messages_to_mgr::ResumeAll{}); } void ProxySoundManager::updateListener(const v3f &pos_, const v3f &vel_, const v3f &at_, const v3f &up_) { send(sound_manager_messages_to_mgr::UpdateListener{pos_, vel_, at_, up_}); } void ProxySoundManager::setListenerGain(f32 gain) { send(sound_manager_messages_to_mgr::SetListenerGain{gain}); } bool ProxySoundManager::loadSoundFile(const std::string &name, const std::string &filepath) { // do not add twice if (m_known_sound_names.count(name) != 0) return false; // coarse check if (!fs::IsFile(filepath)) return false; send(sound_manager_messages_to_mgr::LoadSoundFile{name, filepath}); m_known_sound_names.insert(name); return true; } bool ProxySoundManager::loadSoundData(const std::string &name, std::string &&filedata) { // do not add twice if (m_known_sound_names.count(name) != 0) return false; send(sound_manager_messages_to_mgr::LoadSoundData{name, std::move(filedata)}); m_known_sound_names.insert(name); return true; } void ProxySoundManager::addSoundToGroup(const std::string &sound_name, const std::string &group_name) { send(sound_manager_messages_to_mgr::AddSoundToGroup{sound_name, group_name}); } void ProxySoundManager::playSound(sound_handle_t id, const SoundSpec &spec) { if (id == 0) id = allocateId(1); send(sound_manager_messages_to_mgr::PlaySound{id, spec}); } void ProxySoundManager::playSoundAt(sound_handle_t id, const SoundSpec &spec, const v3f &pos_, const v3f &vel_) { if (id == 0) id = allocateId(1); send(sound_manager_messages_to_mgr::PlaySoundAt{id, spec, pos_, vel_}); } void ProxySoundManager::stopSound(sound_handle_t sound) { send(sound_manager_messages_to_mgr::StopSound{sound}); } void ProxySoundManager::fadeSound(sound_handle_t soundid, f32 step, f32 target_gain) { send(sound_manager_messages_to_mgr::FadeSound{soundid, step, target_gain}); } void ProxySoundManager::updateSoundPosVel(sound_handle_t sound, const v3f &pos_, const v3f &vel_) { send(sound_manager_messages_to_mgr::UpdateSoundPosVel{sound, pos_, vel_}); } } // namespace sound