feat: Add separate volume options for music and sounds

This commit is contained in:
Vsevolod Kremianskii 2020-08-07 15:44:06 +07:00
parent c4fb806af3
commit 9df6fc326e
8 changed files with 29 additions and 13 deletions

View file

@ -38,8 +38,8 @@ AudioPlayer &AudioPlayer::instance() {
void AudioPlayer::init(const AudioOptions &opts) {
_opts = opts;
if (_opts.volume == 0) {
info("Volume set to 0, disabling audio");
if (_opts.musicVolume == 0 && _opts.soundVolume == 0) {
info("Music and sound volume set to 0, disabling audio");
return;
}
@ -53,7 +53,6 @@ void AudioPlayer::init(const AudioOptions &opts) {
throw runtime_error("Failed to create audio context");
}
alcMakeContextCurrent(_context);
alListenerf(AL_GAIN, _opts.volume / 100.0f);
_thread = thread(bind(&AudioPlayer::threadStart, this));
}
@ -102,11 +101,14 @@ void AudioPlayer::reset() {
_sounds.clear();
}
shared_ptr<SoundInstance> AudioPlayer::play(const shared_ptr<AudioStream> &stream, bool loop) {
shared_ptr<SoundInstance> AudioPlayer::play(const shared_ptr<AudioStream> &stream, AudioType type) {
if (!stream) {
throw invalid_argument("Audio stream is empty");
}
shared_ptr<SoundInstance> sound(new SoundInstance(stream, loop));
bool loop = type == AudioType::Music;
float gain = (type == AudioType::Music ? _opts.musicVolume : _opts.soundVolume) / 100.0f;
shared_ptr<SoundInstance> sound(new SoundInstance(stream, loop, gain));
lock_guard<recursive_mutex> lock(_soundsMutex);
_sounds.push_back(sound);

View file

@ -30,6 +30,11 @@ namespace reone {
namespace audio {
enum class AudioType {
Music,
Sound
};
class AudioPlayer {
public:
static AudioPlayer &instance();
@ -38,7 +43,7 @@ public:
void deinit();
void reset();
std::shared_ptr<SoundInstance> play(const std::shared_ptr<AudioStream> &stream, bool loop = false);
std::shared_ptr<SoundInstance> play(const std::shared_ptr<AudioStream> &stream, AudioType type);
private:
AudioOptions _opts;

View file

@ -23,7 +23,9 @@ namespace reone {
namespace audio {
SoundInstance::SoundInstance(const std::shared_ptr<AudioStream> &stream, bool loop) : _stream(stream), _loop(loop) {
SoundInstance::SoundInstance(const std::shared_ptr<AudioStream> &stream, bool loop, float gain) :
_stream(stream), _loop(loop), _gain(gain) {
_multiframe = _stream->frameCount() > 1;
}
@ -32,6 +34,7 @@ void SoundInstance::init() {
_buffers.resize(bufferCount);
alGenBuffers(bufferCount, &_buffers[0]);
alGenSources(1, &_source);
alSourcef(_source, AL_GAIN, _gain);
if (_multiframe) {
_stream->fill(_nextFrame++, _buffers[0]);

View file

@ -27,7 +27,7 @@ namespace audio {
class SoundInstance {
public:
SoundInstance(const std::shared_ptr<AudioStream> &stream, bool loop);
SoundInstance(const std::shared_ptr<AudioStream> &stream, bool loop, float gain);
SoundInstance(SoundInstance &&) = default;
~SoundInstance();
@ -47,6 +47,7 @@ private:
std::shared_ptr<AudioStream> _stream;
bool _loop { false };
float _gain { 0.0f };
bool _multiframe { false };
State _state { State::NotInited };
int _nextFrame { 0 };

View file

@ -29,7 +29,8 @@ enum class AudioFormat {
};
struct AudioOptions {
int volume { 0 };
int soundVolume { 85 };
int musicVolume { 85 };
};
} // namespace audio

View file

@ -124,7 +124,7 @@ void Game::loadModule(const string &name, string entry) {
string musicName(_module->area().music());
if (!musicName.empty()) {
shared_ptr<AudioStream> music(resources.findAudio(musicName));
audio.play(music, true);
audio.play(music, AudioType::Music);
}
if (!_hud) {

View file

@ -194,7 +194,7 @@ void DialogGui::loadCurrentEntry() {
if (!_currentEntry->voResRef.empty()) {
shared_ptr<AudioStream> voice(ResMan.findAudio(_currentEntry->voResRef));
if (voice) {
_currentVoice = TheAudioPlayer.play(voice);
_currentVoice = TheAudioPlayer.play(voice, AudioType::Sound);
}
}

View file

@ -37,6 +37,8 @@ namespace po = boost::program_options;
namespace reone {
static const char *kConfigFilename = "reone.cfg";
static const int kDefaultMusicVolume = 85;
static const int kDefaultSoundVolume = 85;
static const int kDefaultMultiplayerPort = 2003;
Program::Program(int argc, char **argv) : _argc(argc), _argv(argv) {
@ -60,7 +62,8 @@ void Program::loadOptions() {
("width", po::value<int>()->default_value(800), "window width")
("height", po::value<int>()->default_value(600), "window height")
("fullscreen", po::value<bool>()->default_value(false), "enable fullscreen")
("volume", po::value<int>()->default_value(100), "audio volume in percents")
("musicvol", po::value<int>()->default_value(kDefaultMusicVolume), "music volume in percents")
("soundvol", po::value<int>()->default_value(kDefaultSoundVolume), "sound volume in percents")
("port", po::value<int>()->default_value(kDefaultMultiplayerPort), "multiplayer port number")
("debug", po::value<bool>()->default_value(false), "enable debug logging");
@ -85,7 +88,8 @@ void Program::loadOptions() {
_gameOpts.graphics.width = _vars["width"].as<int>();
_gameOpts.graphics.height = _vars["height"].as<int>();
_gameOpts.graphics.fullscreen = _vars["fullscreen"].as<bool>();
_gameOpts.audio.volume = _vars["volume"].as<int>();
_gameOpts.audio.musicVolume = _vars["musicvol"].as<int>();
_gameOpts.audio.soundVolume = _vars["soundvol"].as<int>();
_gameOpts.network.host = _vars.count("join") ? _vars["join"].as<std::string>() : "";
_gameOpts.network.port = _vars["port"].as<int>();