From a90da8fa95e21bd6ac2e189ff6147ed707d3369b Mon Sep 17 00:00:00 2001 From: Zachary Hall Date: Sat, 25 Jan 2025 08:11:07 -0800 Subject: [PATCH] Support enable/disable of voices in GME backend --- backends/playback/gme/gme_backend.cpp | 74 ++++++++++++++++++++++++++- backends/playback/gme/gme_backend.hpp | 2 +- backends/playback/gme/properties.inc | 2 +- 3 files changed, 74 insertions(+), 4 deletions(-) diff --git a/backends/playback/gme/gme_backend.cpp b/backends/playback/gme/gme_backend.cpp index 7cbe200..e96d6f1 100644 --- a/backends/playback/gme/gme_backend.cpp +++ b/backends/playback/gme/gme_backend.cpp @@ -12,6 +12,70 @@ #include #include #include +std::vector GmeBackend::get_property_list() { + std::vector output; + for (auto &kv : voices) { + Property prop; + prop.set_id(PropertyId::BackendSpecific); + prop.set_name(fmt::format("gme/voice/{}/enable", kv.first)); + prop.set_type(PropertyType::Boolean); + prop.set_path(prop.name()); + output.push_back(prop); + } + return output; +} +std::optional GmeBackend::get_voice_id(std::string path) { + std::string prefix = "gme/voice/"; + std::string suffix = "/enable"; + if (path.substr(0, prefix.length()) != prefix) { + return {}; + } + if (path.substr(path.length() - suffix.length()) != suffix) { + return {}; + } + path = path.substr(prefix.length()); + path = path.substr(0, path.length() - suffix.length()); + if (!voices.contains(path)) { + return {}; + } + return voices[path]; +} +bool GmeBackend::set(std::string path, google::protobuf::Any value) { + auto maybe_voice_id = get_voice_id(path); + if (maybe_voice_id.has_value()) { + bool enable = resolve_any(value); + gme_mute_voice(gme_backend, maybe_voice_id.value(), !enable); + properties[path] = value; + return true; + } + return false; +} +std::optional GmeBackend::get(std::string path) { + auto maybe_voice_id = get_voice_id(path); + if (maybe_voice_id.has_value()) { + if (properties.contains(path)) { + return properties[path]; + } else { + return reset(path); + } + } else { + return {}; + } +} +std::optional GmeBackend::reset(std::string path) { + auto maybe_voice_id = get_voice_id(path); + if (maybe_voice_id.has_value()) { + google::protobuf::Any prop; + BooleanProperty bool_prop; + bool_prop.set_value(true); + prop.PackFrom(bool_prop); + properties[path] = prop; + gme_mute_voice(gme_backend, maybe_voice_id.value(), false); + return prop; + } else { + return {}; + } +} void GmeBackend::load(const char *filename) { memset(&spec, 0, sizeof(spec)); current_file = filename; @@ -58,16 +122,22 @@ void GmeBackend::switch_stream(int idx) { info->length = 0; } uint64_t tmp = info->length; + this->loop_len = info->loop_length; + this->loop_start = info->intro_length; + if (tmp == 0) tmp = this->loop_len + this->loop_start; tmp *= spec.freq; tmp /= 1000; this->length = tmp; - this->loop_len = info->loop_length; - this->loop_start = info->intro_length; if (info->song[0] == '\0') { this->current_title = {}; } else { this->current_title = info->song; } + int voice_count = gme_voice_count(gme_backend); + for (int i = 0; i < voice_count; i++) { + const char *voice_name = gme_voice_name(gme_backend, i); + voices[voice_name] = i; + } gme_free_info(info); gme_ignore_silence(gme_backend, true); open = true; diff --git a/backends/playback/gme/gme_backend.hpp b/backends/playback/gme/gme_backend.hpp index 1538b15..cd8dbaa 100644 --- a/backends/playback/gme/gme_backend.hpp +++ b/backends/playback/gme/gme_backend.hpp @@ -29,7 +29,7 @@ class GmeBackend : public PlaybackBackend { return "Game Music Emu"; } void add_licenses() override; - //std::vector get_property_list() override; + std::vector get_property_list() override; void seek_samples(uint64_t position) override; void load(const char *filename) override; void switch_stream(int idx) override; diff --git a/backends/playback/gme/properties.inc b/backends/playback/gme/properties.inc index 379722b..98a79cb 100644 --- a/backends/playback/gme/properties.inc +++ b/backends/playback/gme/properties.inc @@ -3,7 +3,7 @@ BOOL_PROPERTY(pcm_enable, true) BOOL_PROPERTY(psg_enable, true) BOOL_PROPERTY(fm_enable, true) -DOUBLE_PROPERTY(pcm_volume, 1.0) +DOUBLE_PROPERTY(tempo, 1.0) DOUBLE_PROPERTY(psg_volume, 1.0) DOUBLE_PROPERTY(fm_volume, 1.0) #undef BOOL_PROPERTY