From 60fc225f5b5129f6c4530acaf5858a9ecf2f7e56 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Mon, 25 Sep 2023 19:25:09 +0200 Subject: added new drumkit XML parameter islogpower and support logarithmic powers for the dynamic expander --- src/DGDOM.h | 1 + src/dgxmlparser.cc | 2 ++ src/domloader.cc | 1 + src/drumkit.cc | 5 +++++ src/drumkit.h | 2 ++ src/drumkitloader.cc | 2 ++ src/inputprocessor.cc | 46 ++++++++++++++++++++++++++++++++++++---------- src/settings.h | 3 ++- 8 files changed, 51 insertions(+), 11 deletions(-) diff --git a/src/DGDOM.h b/src/DGDOM.h index a03f0ef..e39f445 100644 --- a/src/DGDOM.h +++ b/src/DGDOM.h @@ -139,6 +139,7 @@ struct DrumkitDOM { std::string version; double samplerate; + bool islogpower; MetadataDOM metadata; diff --git a/src/dgxmlparser.cc b/src/dgxmlparser.cc index bd9af66..b3aba75 100644 --- a/src/dgxmlparser.cc +++ b/src/dgxmlparser.cc @@ -209,6 +209,8 @@ bool parseDrumkitFile(const std::string& filename, DrumkitDOM& dom, LogFunction res &= attrcpy(dom.version, drumkit, "version", logger, filename, true); dom.samplerate = 44100.0; res &= attrcpy(dom.samplerate, drumkit, "samplerate", logger, filename, true); + dom.islogpower = false; + res &= attrcpy(dom.islogpower, drumkit, "islogpower", logger, filename, true); // Use the old name and description attributes on the drumkit node as fallback res &= attrcpy(dom.metadata.title, drumkit, "name", logger, filename, true); diff --git a/src/domloader.cc b/src/domloader.cc index 5d411bd..d422c9a 100644 --- a/src/domloader.cc +++ b/src/domloader.cc @@ -60,6 +60,7 @@ bool DOMLoader::loadDom(const std::string& basepath, drumkit.metadata._version = dom.version; drumkit.metadata._description = dom.metadata.description; drumkit.metadata._samplerate = dom.samplerate; + drumkit.metadata._islogpower = dom.islogpower; for(const auto& channel: dom.channels) { diff --git a/src/drumkit.cc b/src/drumkit.cc index 9df9a33..2fc16db 100644 --- a/src/drumkit.cc +++ b/src/drumkit.cc @@ -55,6 +55,11 @@ bool DrumKit::isValid() const return this == magic; } +bool DrumKit::isLogPower() const +{ + return metadata._islogpower; +} + std::string DrumKit::getFile() const { return _file; diff --git a/src/drumkit.h b/src/drumkit.h index aee5d19..3f2677f 100644 --- a/src/drumkit.h +++ b/src/drumkit.h @@ -51,6 +51,7 @@ public: void clear(); bool isValid() const; + bool isLogPower() const; float getSamplerate() const; @@ -74,5 +75,6 @@ private: std::string _description; float _samplerate{44100.0f}; VersionStr _version; + bool _islogpower{false}; } metadata; }; diff --git a/src/drumkitloader.cc b/src/drumkitloader.cc index 9167201..91a235f 100644 --- a/src/drumkitloader.cc +++ b/src/drumkitloader.cc @@ -136,6 +136,7 @@ bool DrumKitLoader::loadkit(const std::string& file) settings.drumkit_description.store(""); settings.drumkit_version.store(""); settings.drumkit_samplerate.store(44100); + settings.drumkit_is_log_power.store(false); settings.load_status_text.store(""); settings.drumkit_load_status.store(LoadStatus::Parsing); @@ -219,6 +220,7 @@ bool DrumKitLoader::loadkit(const std::string& file) settings.drumkit_description = kit.getDescription(); settings.drumkit_version = kit.getVersion(); settings.drumkit_samplerate = kit.getSamplerate(); + settings.drumkit_is_log_power = kit.isLogPower(); // only load the default midi map if there is one and no midimap is selected yet if (drumkitdom.metadata.default_midimap_file != "" && settings.midimap_file == "") { diff --git a/src/inputprocessor.cc b/src/inputprocessor.cc index f0b2935..7d58b52 100644 --- a/src/inputprocessor.cc +++ b/src/inputprocessor.cc @@ -210,6 +210,19 @@ bool InputProcessor::processOnset(event_t& event, std::size_t pos, return false; } + +// TEST dynamic expander +if(settings.drumkit_is_log_power) +{ + static auto a = 0.981; + static auto factor = 126.0f / (pow(a, 126.0f) - 1.0f); + event.velocity = (factor * (pow(a, event.velocity * 127.0f - 1.0f) - 1.0f) + 1.0f) / 127.0f; +} + +// TODO velocity 1 does not select thehighest amplitude samples... -> maybe bug in sample selection +//event.velocity=1.0; + + std::size_t instrument_id = event.instrument; Instrument* instr = nullptr; @@ -294,16 +307,29 @@ bool InputProcessor::processOnset(event_t& event, std::size_t pos, // TEST dynamic expander //printf("event_sample.scale: %f, event.velocity: %f, sample->getPower(): %f, instr->getMinPower(): %f, instr->getMaxPower(): %f\n", event_sample.scale, event.velocity, sample->getPower(), instr->getMinPower(), instr->getMaxPower()); -auto target_max_power_db = 10 * log10(instr->getMaxPower()); -auto sel_power_db = 10 * log10(sample->getPower()); -auto target_dynamic_db = 40.0; // dB - -static auto a = 0.981; -static auto factor = 126.0f / (pow(a, 126.0f) - 1.0f); -auto y = (factor * (pow(a, event.velocity * 127.0f - 1.0f) - 1.0f) + 1.0f) / 127.0f; -auto target_power_db = y * target_dynamic_db + target_max_power_db - target_dynamic_db; -auto diff_power_db = target_power_db - sel_power_db; -event_sample.scale = pow(10.0, diff_power_db / 20); +if(settings.drumkit_is_log_power) +{ + // powers in instrument XML are in dB and curve is already applied to event.velocity: + auto target_max_power_db = instr->getMaxPower(); + auto sel_power_db = sample->getPower(); + auto target_dynamic_db = 50.0; // dB + auto target_power_db = event.velocity * target_dynamic_db + target_max_power_db - target_dynamic_db; + auto diff_power_db = target_power_db - sel_power_db; + event_sample.scale = pow(10.0, diff_power_db / 20); +} +else +{ + auto target_max_power_db = 10 * log10(instr->getMaxPower()); + auto sel_power_db = 10 * log10(sample->getPower()); + auto target_dynamic_db = 40.0; // dB + + static auto a = 0.981; + static auto factor = 126.0f / (pow(a, 126.0f) - 1.0f); + auto y = (factor * (pow(a, event.velocity * 127.0f - 1.0f) - 1.0f) + 1.0f) / 127.0f; + auto target_power_db = y * target_dynamic_db + target_max_power_db - target_dynamic_db; + auto diff_power_db = target_power_db - sel_power_db; + event_sample.scale = pow(10.0, diff_power_db / 20); +} //printf("event_sample.scale: %f, diff_power_db: %f, target_power_db: %f, sel_power_db: %f\n", event_sample.scale, diff_power_db, target_power_db, sel_power_db); diff --git a/src/settings.h b/src/settings.h index 5c2e4ee..f2d656e 100644 --- a/src/settings.h +++ b/src/settings.h @@ -3,7 +3,7 @@ * settings.h * * Tue Mar 22 10:59:46 CET 2016 - * Copyright 2016 Christian Glöckner + * Copyright 2016 Christian Gl�ckner * cgloeckner@freenet.de ****************************************************************************/ @@ -53,6 +53,7 @@ struct Settings Atomic drumkit_description{""}; Atomic drumkit_version{""}; Atomic drumkit_samplerate{44100}; + Atomic drumkit_is_log_power{false}; //! The maximum amount of memory in bytes that the AudioCache //! is allowed to use for preloading. Default is 1GB. -- cgit v1.2.3