Skip to content

Commit

Permalink
global filters for synths, ie. not per voice
Browse files Browse the repository at this point in the history
- SoundInstrument has a globalEffectable, Sound::render() accepts one,
  and uses it to filter post-fx if it's provided

- Sound menu has a new entry: Global filters, right under Filters.
  This is the same menu structure as under SONG - renamed for clarity.

- TODO:

  - Untested from SD card install, only via loadfw

  - I need to understand ParamMenager stuff better:

    - This uses same ParamManager as for voice, not entirely sure if
      that's right - it seems to work, and didn't seem to steal the values
      from another global filter... but the initial values for
      sound's global filter params in the sound menu are bogus. (Like 0 for LPF freq
      and 25 for resonance, and 25 for HPF freq and resonance??)

    - If you try this out, because of the above global LPF setting all
      sound is gone until you go and open up the filters! Give a try with
      taking a nice sound, adding bitcrush and flanger, and then play
      with LPF. :)
  • Loading branch information
nikodemus committed Jul 19, 2024
1 parent bf7fb5a commit 108e58d
Show file tree
Hide file tree
Showing 20 changed files with 116 additions and 10 deletions.
1 change: 1 addition & 0 deletions src/deluge/gui/l10n/english.json
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,7 @@

"STRING_FOR_MASTER": "Master",
"STRING_FOR_FILTERS": "Filters",
"STRING_FOR_GLOBAL_FILTERS": "Global Filters",

"STRING_FOR_CANT_TRANSPOSE": "Can't Transpose: No Scale Mode Clips",

Expand Down
1 change: 1 addition & 0 deletions src/deluge/gui/l10n/g_english.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,7 @@ PLACE_SDRAM_DATA Language english{
{STRING_FOR_TIME, "Time"},
{STRING_FOR_MASTER, "Master"},
{STRING_FOR_FILTERS, "Filters"},
{STRING_FOR_GLOBAL_FILTERS, "Global Filters"},
{STRING_FOR_CANT_TRANSPOSE, "Can't Transpose: No Scale Mode Clips"},
{STRING_FOR_TRANSPOSE_INKEY, "In Key"},
{STRING_FOR_TRANSPOSE_CHROMATIC, "Chromatic"},
Expand Down
2 changes: 1 addition & 1 deletion src/deluge/gui/l10n/g_seven_segment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ PLACE_SDRAM_DATA Language seven_segment{
{STRING_FOR_DIFFUSION, "DIFF"},
{STRING_FOR_TIME, "TIME"},
{STRING_FOR_MASTER, "MSTR"},
{STRING_FOR_FILTERS, "FLTR"},
{STRING_FOR_FILTERS, "GFLT"},
{STRING_FOR_CANT_TRANSPOSE, "CANT"},
{STRING_FOR_TRANSPOSE_INKEY, "IN-K"},
{STRING_FOR_TRANSPOSE_CHROMATIC, "CHRM"},
Expand Down
1 change: 1 addition & 0 deletions src/deluge/gui/l10n/seven_segment.json
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@

"STRING_FOR_MASTER": "MSTR",
"STRING_FOR_FILTERS": "FLTR",
"STRING_FOR_FILTERS": "GFLT",

"STRING_FOR_CANT_TRANSPOSE": "CANT",

Expand Down
1 change: 1 addition & 0 deletions src/deluge/gui/l10n/strings.h
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,7 @@ enum class String : size_t {

STRING_FOR_MASTER,
STRING_FOR_FILTERS,
STRING_FOR_GLOBAL_FILTERS,

STRING_FOR_CANT_TRANSPOSE,

Expand Down
31 changes: 31 additions & 0 deletions src/deluge/gui/menu_item/filter/global_hpf_mode.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2014-2023 Synthstrom Audible Limited
*
* This file is part of The Synthstrom Audible Deluge Firmware.
*
* The Synthstrom Audible Deluge Firmware is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once

#include "gui/ui/sound_editor.h"
#include "model/global_effectable/global_effectable.h"
#include "gui/menu_item/filter/hpf_mode.h"

namespace deluge::gui::menu_item::filter {
class GlobalHPFMode final : public HPFMode {
public:
using HPFMode::HPFMode;
void readCurrentValue() override { this->setValue<::FilterMode>(soundEditor.currentGlobalEffectable->hpfMode); }
void writeCurrentValue() override { soundEditor.currentGlobalEffectable->hpfMode = this->getValue<::FilterMode>(); }
bool isRelevant(ModControllableAudio* modControllable, int32_t whichThing) override { return true; }
};
} // namespace deluge::gui::menu_item::filter
31 changes: 31 additions & 0 deletions src/deluge/gui/menu_item/filter/global_lpf_mode.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2014-2023 Synthstrom Audible Limited
*
* This file is part of The Synthstrom Audible Deluge Firmware.
*
* The Synthstrom Audible Deluge Firmware is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once

#include "gui/ui/sound_editor.h"
#include "model/global_effectable/global_effectable.h"
#include "gui/menu_item/filter/lpf_mode.h"

namespace deluge::gui::menu_item::filter {
class GlobalLPFMode final : public LPFMode {
public:
using LPFMode::LPFMode;
void readCurrentValue() override { this->setValue<::FilterMode>(soundEditor.currentGlobalEffectable->lpfMode); }
void writeCurrentValue() override { soundEditor.currentGlobalEffectable->lpfMode = this->getValue<::FilterMode>(); }
bool isRelevant(ModControllableAudio* modControllable, int32_t whichThing) override { return true; }
};
} // namespace deluge::gui::menu_item::filter
2 changes: 1 addition & 1 deletion src/deluge/gui/menu_item/filter/hpf_mode.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include "util/misc.h"

namespace deluge::gui::menu_item::filter {
class HPFMode final : public Selection {
class HPFMode : public Selection {
public:
using Selection::Selection;
void readCurrentValue() override {
Expand Down
2 changes: 1 addition & 1 deletion src/deluge/gui/menu_item/filter/lpf_mode.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#include "processing/sound/sound.h"

namespace deluge::gui::menu_item::filter {
class LPFMode final : public Selection {
class LPFMode : public Selection {
public:
using Selection::Selection;
void readCurrentValue() override { this->setValue<::FilterMode>(soundEditor.currentModControllable->lpfMode); }
Expand Down
9 changes: 9 additions & 0 deletions src/deluge/gui/menu_item/generate/dmenus/filter/hpf.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@
title="STRING_FOR_HPF_MODE",
)

global_mode = Menu(
"filter::GlobalHPFMode",
"globalHPFModeMenu",
["{name}", "{title}"],
"filter/hpf/resonance.md",
name="STRING_FOR_MODE",
title="STRING_FOR_HPF_MODE",
)

morph = MultiModeMenu(
"filter::FilterMorph",
"hpfMorphMenu",
Expand Down
9 changes: 9 additions & 0 deletions src/deluge/gui/menu_item/generate/dmenus/filter/lpf.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@
title="STRING_FOR_LPF_MODE",
)

global_mode = Menu(
"filter::GlobalLPFMode",
"globalLPFModeMenu",
["{name}", "{title}"],
"filter/lpf/resonance.md",
name="STRING_FOR_MODE",
title="STRING_FOR_LPF_MODE",
)

morph = MultiModeMenu(
"filter::FilterMorph",
"lpfMorphMenu",
Expand Down
2 changes: 2 additions & 0 deletions src/deluge/gui/menu_item/generate/g_menus.inc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ std::array<MenuItem*, 3> child2 = {
&filterRoutingMenu,
};
submenu::Filter soundFiltersMenu{STRING_FOR_FILTERS, child2};
filter::GlobalHPFMode globalHPFModeMenu{STRING_FOR_MODE, STRING_FOR_HPF_MODE};
filter::GlobalLPFMode globalLPFModeMenu{STRING_FOR_MODE, STRING_FOR_LPF_MODE};
audio_compressor::CompParam threshold{STRING_FOR_THRESHOLD, STRING_FOR_THRESHOLD, params::UNPATCHED_COMPRESSOR_THRESHOLD};
audio_compressor::Ratio compRatio{STRING_FOR_RATIO, STRING_FOR_RATIO};
audio_compressor::Attack compAttack{STRING_FOR_ATTACK, STRING_FOR_ATTACK};
Expand Down
2 changes: 2 additions & 0 deletions src/deluge/gui/menu_item/generate/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
top_level_menus = (
[
dmenus.filter.sound_filters,
dmenus.filter.hpf.global_mode,
dmenus.filter.lpf.global_mode,
dmenus.compressor.menu,
dmenus.unison.menu,
]
Expand Down
9 changes: 6 additions & 3 deletions src/deluge/gui/ui/menus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@
#include "gui/menu_item/filter/hpf_mode.h"
#include "gui/menu_item/filter/lpf_freq.h"
#include "gui/menu_item/filter/lpf_mode.h"
#include "gui/menu_item/filter/global_lpf_mode.h"
#include "gui/menu_item/filter/global_hpf_mode.h"
#include "gui/menu_item/filter/morph.h"
#include "gui/menu_item/filter_route.h"
#include "gui/menu_item/firmware/version.h"
Expand Down Expand Up @@ -476,7 +478,7 @@ Submenu globalLPFMenu{
&globalLPFFreqMenu,
&globalLPFResMenu,
&globalLPFMorphMenu,
&lpfModeMenu,
&globalLPFModeMenu,
},
};

Expand All @@ -491,12 +493,12 @@ Submenu globalHPFMenu{
&globalHPFFreqMenu,
&globalHPFResMenu,
&globalHPFMorphMenu,
&hpfModeMenu,
&globalHPFModeMenu,
},
};

Submenu globalFiltersMenu{
STRING_FOR_FILTERS,
STRING_FOR_GLOBAL_FILTERS,
{
&globalLPFMenu,
&globalHPFMenu,
Expand Down Expand Up @@ -1108,6 +1110,7 @@ menu_item::Submenu soundEditorRootMenu{
&arpMenu,
&audioCompMenu,
&soundFiltersMenu,
&globalFiltersMenu,
&soundFXMenu,
&sidechainMenu,
&source0Menu,
Expand Down
9 changes: 8 additions & 1 deletion src/deluge/gui/ui/sound_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1314,6 +1314,7 @@ bool SoundEditor::setup(Clip* clip, const MenuItem* item, int32_t sourceIndex) {
ParamManagerForTimeline* newParamManager = nullptr;
ArpeggiatorSettings* newArpSettings = nullptr;
ModControllableAudio* newModControllable = nullptr;
ModControllableAudio* newGlobalEffectable = nullptr;

InstrumentClip* instrumentClip = nullptr;

Expand Down Expand Up @@ -1393,7 +1394,8 @@ bool SoundEditor::setup(Clip* clip, const MenuItem* item, int32_t sourceIndex) {

// Synth
if (outputType == OutputType::SYNTH) {
newSound = (SoundInstrument*)output;
newSound = (Sound*)output;
newGlobalEffectable = &((SoundInstrument*)newSound)->fx;
newModControllable = newSound;
}

Expand Down Expand Up @@ -1492,6 +1494,11 @@ bool SoundEditor::setup(Clip* clip, const MenuItem* item, int32_t sourceIndex) {
currentArpSettings = newArpSettings;
currentMultiRange = newRange;
currentModControllable = newModControllable;
if (newGlobalEffectable) {
currentGlobalEffectable = newGlobalEffectable;
} else {
currentGlobalEffectable = newModControllable;
}

if (currentModControllable) {
currentSidechain = &currentModControllable->sidechain;
Expand Down
1 change: 1 addition & 0 deletions src/deluge/gui/ui/sound_editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class SoundEditor final : public UI {
bool getGreyoutColsAndRows(uint32_t* cols, uint32_t* rows);
Sound* currentSound;
ModControllableAudio* currentModControllable;
ModControllableAudio* currentGlobalEffectable;
int8_t currentSourceIndex;
Source* currentSource;
ParamManagerForTimeline* currentParamManager;
Expand Down
6 changes: 5 additions & 1 deletion src/deluge/processing/sound/sound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2180,7 +2180,7 @@ void Sound::stopParamLPF(ModelStackWithSoundFlags* modelStack) {

void Sound::render(ModelStackWithThreeMainThings* modelStack, StereoSample* outputBuffer, int32_t numSamples,
int32_t* reverbBuffer, int32_t sideChainHitPending, int32_t reverbAmountAdjust,
bool shouldLimitDelayFeedback, int32_t pitchAdjust) {
bool shouldLimitDelayFeedback, int32_t pitchAdjust, GlobalEffectable* fx) {

if (skippingRendering) {
compressor.gainReduction = 0;
Expand Down Expand Up @@ -2415,6 +2415,10 @@ void Sound::render(ModelStackWithThreeMainThings* modelStack, StereoSample* outp
processSRRAndBitcrushing((StereoSample*)soundBuffer, numSamples, &postFXVolume, paramManager);
processFX((StereoSample*)soundBuffer, numSamples, modFXType, modFXRate, modFXDepth, delayWorkingState,
&postFXVolume, paramManager);
if (fx) {
fx->setupFilterSetConfig(&postFXVolume, paramManager);
fx->processFilters((StereoSample*)soundBuffer, numSamples);
}
processStutter((StereoSample*)soundBuffer, numSamples, paramManager);

processReverbSendAndVolume((StereoSample*)soundBuffer, numSamples, reverbBuffer, postFXVolume, postReverbVolume,
Expand Down
3 changes: 2 additions & 1 deletion src/deluge/processing/sound/sound.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class Kit;
class ParamManagerForTimeline;
class TimelineCounter;
class Clip;
class GlobalEffectable;
class GlobalEffectableForClip;
class ModelStackWithThreeMainThings;
class ModelStackWithSoundFlags;
Expand Down Expand Up @@ -145,7 +146,7 @@ class Sound : public ModControllableAudio {
int32_t newValue);
void render(ModelStackWithThreeMainThings* modelStack, StereoSample* outputBuffer, int32_t numSamples,
int32_t* reverbBuffer, int32_t sideChainHitPending, int32_t reverbAmountAdjust = 134217728,
bool shouldLimitDelayFeedback = false, int32_t pitchAdjust = kMaxSampleValue);
bool shouldLimitDelayFeedback = false, int32_t pitchAdjust = kMaxSampleValue, GlobalEffectable* fx = nullptr);
void unassignAllVoices();

void ensureInaccessibleParamPresetValuesWithoutKnobsAreZero(Song* song) final; // Song may be NULL
Expand Down
2 changes: 1 addition & 1 deletion src/deluge/processing/sound/sound_instrument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void SoundInstrument::renderOutput(ModelStack* modelStack, StereoSample* startPo
}
else {
Sound::render(modelStackWithThreeMainThings, startPos, numSamples, reverbBuffer, sideChainHitPending,
reverbAmountAdjust, shouldLimitDelayFeedback);
reverbAmountAdjust, shouldLimitDelayFeedback, kMaxSampleValue, &fx);
}

if (playbackHandler.isEitherClockActive() && !playbackHandler.ticksLeftInCountIn && isClipActive) {
Expand Down
2 changes: 2 additions & 0 deletions src/deluge/processing/sound/sound_instrument.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "model/instrument/melodic_instrument.h"
#include "modulation/arpeggiator.h"
#include "processing/sound/sound.h"
#include "model/global_effectable/global_effectable.h"

class ParamManagerForTimeline;
class ParamManagerForTimeline;
Expand Down Expand Up @@ -82,4 +83,5 @@ class SoundInstrument final : public Sound, public MelodicInstrument {
ArpeggiatorBase* getArp();
char const* getXMLTag() { return "sound"; }
ArpeggiatorSettings defaultArpSettings;
GlobalEffectable fx;
};

0 comments on commit 108e58d

Please sign in to comment.