216 lines
5.0 KiB
C++
216 lines
5.0 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "common/config-manager.h"
|
|
#include "qdengine/qd_fwd.h"
|
|
#include "qdengine/xmath.h"
|
|
#include "qdengine/system/graphics/gr_dispatcher.h"
|
|
#include "qdengine/system/sound/snd_dispatcher.h"
|
|
#include "qdengine/qdcore/util/plaympp_api.h"
|
|
|
|
namespace QDEngine {
|
|
|
|
sndDispatcher *sndDispatcher::_dispatcher_ptr;
|
|
|
|
static bool operator == (const sndSound &snd0, const sndSound &snd1) {
|
|
return snd0.sound() == snd1.sound();
|
|
}
|
|
|
|
static bool operator == (const sndSound &snd, const sndHandle &h) {
|
|
return snd.handle() == &h;
|
|
}
|
|
|
|
sndDispatcher::sndDispatcher() : _is_enabled(true),
|
|
_is_paused(false),
|
|
_volume(255),
|
|
_volume_dB(0),
|
|
_frequency_coeff(1.0f) {
|
|
|
|
if (!_dispatcher_ptr)
|
|
_dispatcher_ptr = this;
|
|
}
|
|
|
|
sndDispatcher::~sndDispatcher() {
|
|
_sounds.clear();
|
|
|
|
if (_dispatcher_ptr == this)
|
|
_dispatcher_ptr = NULL;
|
|
}
|
|
|
|
void sndDispatcher::set_volume(uint32 vol) {
|
|
_volume = vol & 0xFF;
|
|
|
|
_volume_dB = convert_volume_to_dB(_volume);
|
|
|
|
update_volume();
|
|
}
|
|
|
|
int sndDispatcher::convert_volume_to_dB(int vol) {
|
|
if (vol > 255) vol = 255;
|
|
if (vol < 0) vol = 0;
|
|
|
|
if (vol != 255) {
|
|
const int DB_MIN = -10000;
|
|
const int DB_MAX = 0;
|
|
const int DB_SIZE = DB_MAX - DB_MIN;
|
|
|
|
return (DB_MIN + round(log10(9.0 * log(double(vol + 1)) / (log(2.0) * 8) + 1.0) * DB_SIZE));
|
|
} else
|
|
return 0;
|
|
}
|
|
|
|
void sndDispatcher::quant() {
|
|
for (auto it = _sounds.begin(); it != _sounds.end(); ) {
|
|
if (it->is_stopped())
|
|
it = _sounds.erase(it);
|
|
else
|
|
++it;
|
|
}
|
|
}
|
|
|
|
bool sndDispatcher::play_sound(const sndSound *snd, bool loop, int vol) {
|
|
if (is_enabled()) {
|
|
_sounds.push_back(sndSound(*snd));
|
|
sndSound &p = _sounds.back();
|
|
|
|
if (loop)
|
|
p.toggle_looping();
|
|
|
|
int snd_volume = vol * volume() / 256;
|
|
|
|
if (!p.create_sound_buffer())
|
|
return false;
|
|
|
|
p.set_volume(snd_volume);
|
|
p.change_frequency(frequency_coeff());
|
|
|
|
if (!is_paused()) {
|
|
if (!p.play()) return false;
|
|
} else
|
|
p.pause();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool sndDispatcher::stop_sound(const sndSound *snd) {
|
|
sound_list_t::iterator it = Common::find(_sounds.begin(), _sounds.end(), *snd);
|
|
|
|
if (it != _sounds.end()) {
|
|
it->stop();
|
|
_sounds.erase(it);
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool sndDispatcher::stop_sound(const sndHandle *handle) {
|
|
sound_list_t::iterator it = Common::find(_sounds.begin(), _sounds.end(), *handle);
|
|
|
|
if (it != _sounds.end()) {
|
|
it->stop();
|
|
_sounds.erase(it);
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
sndSound::status_t sndDispatcher::sound_status(const sndHandle *handle) const {
|
|
sound_list_t::const_iterator it = Common::find(_sounds.begin(), _sounds.end(), *handle);
|
|
|
|
if (it != _sounds.end()) {
|
|
if (is_paused())
|
|
return sndSound::SOUND_PAUSED;
|
|
|
|
return sndSound::SOUND_PLAYING;
|
|
}
|
|
|
|
return sndSound::SOUND_STOPPED;
|
|
}
|
|
|
|
sndSound::status_t sndDispatcher::sound_status(const sndSound *snd) const {
|
|
sound_list_t::const_iterator it = Common::find(_sounds.begin(), _sounds.end(), *snd);
|
|
|
|
if (it != _sounds.end())
|
|
return it->status();
|
|
|
|
return sndSound::SOUND_STOPPED;
|
|
}
|
|
|
|
bool sndDispatcher::update_volume() {
|
|
for (sound_list_t::iterator it = _sounds.begin(); it != _sounds.end(); ++it)
|
|
it->set_volume(volume());
|
|
|
|
return true;
|
|
}
|
|
|
|
bool sndDispatcher::update_frequency() {
|
|
for (sound_list_t::iterator it = _sounds.begin(); it != _sounds.end(); ++it)
|
|
it->change_frequency(frequency_coeff());
|
|
|
|
return true;
|
|
}
|
|
|
|
void sndDispatcher::stop_sounds() {
|
|
for (sound_list_t::iterator it = _sounds.begin(); it != _sounds.end(); ++it)
|
|
it->stop();
|
|
|
|
_sounds.clear();
|
|
}
|
|
|
|
bool sndDispatcher::set_sound_frequency(const sndHandle *snd, float coeff) {
|
|
sound_list_t::iterator it = Common::find(_sounds.begin(), _sounds.end(), *snd);
|
|
|
|
if (it != _sounds.end()) {
|
|
it->change_frequency(frequency_coeff() * coeff);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void sndDispatcher::pause_sounds() {
|
|
for (sound_list_t::iterator it = _sounds.begin(); it != _sounds.end(); ++it)
|
|
it->pause();
|
|
}
|
|
|
|
void sndDispatcher::resume_sounds() {
|
|
for (sound_list_t::iterator it = _sounds.begin(); it != _sounds.end(); ++it) {
|
|
if (it->is_paused())
|
|
it->resume();
|
|
}
|
|
}
|
|
|
|
void sndDispatcher::syncSoundSettings() {
|
|
set_volume(ConfMan.getInt("sound_volume"));
|
|
|
|
if (ConfMan.getBool("enable_sound"))
|
|
enable();
|
|
else
|
|
disable();
|
|
}
|
|
|
|
} // namespace QDEngine
|