From 0a309e5ba1b6e800ba63a1ff96eda5dcea2bca10 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Wed, 27 Sep 2023 17:10:45 +0200 Subject: integrate islogpower drumkit XML parameter and 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 | 16 +++++++++++++++- src/settings.h | 3 ++- 8 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/DGDOM.h b/src/DGDOM.h index 474b29c..4a74c4c 100644 --- a/src/DGDOM.h +++ b/src/DGDOM.h @@ -138,6 +138,7 @@ struct DrumkitDOM { std::string version; double samplerate; + bool islogpower; MetadataDOM metadata; diff --git a/src/dgxmlparser.cc b/src/dgxmlparser.cc index 0d3cdcd..c3d9941 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 c78ed75..24569ff 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 c0c0e92..64b0dc5 100644 --- a/src/inputprocessor.cc +++ b/src/inputprocessor.cc @@ -3,7 +3,7 @@ * inputprocessor.cc * * Sat Apr 23 20:39:30 CEST 2016 - * Copyright 2016 André Nusser + * Copyright 2016 Andr� Nusser * andre.nusser@googlemail.com ****************************************************************************/ @@ -215,6 +215,13 @@ bool InputProcessor::processOnset(event_t& event, std::size_t pos, return false; } + // In case log-power and dynamic expander is used, apply a special velocity curve + if(settings.drumkit_is_log_power) + { + auto a = 0.981; // compatible to Roland sound modules + event.velocity = (126.0f / (pow(a, 126.0f) - 1.0f) * (pow(a, event.velocity * 127.0f - 1.0f) - 1.0f) + 1.0f) / 127.0f; + } + std::size_t instrument_id = event.instrument; Instrument* instr = nullptr; @@ -299,6 +306,13 @@ bool InputProcessor::processOnset(event_t& event, std::size_t pos, { event_sample.scale *= event.velocity; } + + // Dynamic expander (only enabled if log-power is configured) + if(settings.drumkit_is_log_power) + { + auto target_dynamic_db = 50.0; // dB, defined maximum dynamic after expander + event_sample.scale = pow(10.0, (event.velocity * target_dynamic_db + instr->getMaxPower() - target_dynamic_db - sample->getPower()) / 20); + } } } diff --git a/src/settings.h b/src/settings.h index fb93d79..a92acff 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