Support enable/disable of voices in GME backend

This commit is contained in:
Zachary Hall 2025-01-25 08:11:07 -08:00
parent a53b2498cb
commit a90da8fa95
3 changed files with 74 additions and 4 deletions

View file

@ -12,6 +12,70 @@
#include <assets/assets.h>
#include <limits.h>
#include <gme/gme.h>
std::vector<Property> GmeBackend::get_property_list() {
std::vector<Property> 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<int> 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<bool>(value);
gme_mute_voice(gme_backend, maybe_voice_id.value(), !enable);
properties[path] = value;
return true;
}
return false;
}
std::optional<google::protobuf::Any> 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<google::protobuf::Any> 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;

View file

@ -29,7 +29,7 @@ class GmeBackend : public PlaybackBackend {
return "Game Music Emu";
}
void add_licenses() override;
//std::vector<Property> get_property_list() override;
std::vector<Property> get_property_list() override;
void seek_samples(uint64_t position) override;
void load(const char *filename) override;
void switch_stream(int idx) override;

View file

@ -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