feat: Add separate volume options for music and sounds
This commit is contained in:
parent
c4fb806af3
commit
9df6fc326e
8 changed files with 29 additions and 13 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -29,7 +29,8 @@ enum class AudioFormat {
|
|||
};
|
||||
|
||||
struct AudioOptions {
|
||||
int volume { 0 };
|
||||
int soundVolume { 85 };
|
||||
int musicVolume { 85 };
|
||||
};
|
||||
|
||||
} // namespace audio
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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>();
|
||||
|
||||
|
|
Loading…
Reference in a new issue