Skip to content

Commit 26df621

Browse files
authored
Merge branch 'release/1.1' into cherry-pick-release/1.1-641da95ae5dafcc41fc3366131c5fcd169972468
2 parents c8fb0f0 + a5d985b commit 26df621

File tree

9 files changed

+81
-62
lines changed

9 files changed

+81
-62
lines changed

src/deluge/dsp/compressor/rms_feedback.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ void RMSFeedbackCompressor::updateER(float numSamples, q31_t finalVolume) {
3636
// this is effectively where song volume gets applied, so we'll stick an IIR filter (e.g. the envelope) here to
3737
// reduce clicking
3838
float lastER = er;
39-
er = std::max<float>((songVolumedB - threshdb - 1) * ratio, 0);
39+
er = std::max<float>((songVolumedB - threshdb - 1) * reduction, 0);
4040
// using the envelope is convenient since it means makeup gain and compression amount change at the same rate
4141
er = runEnvelope(lastER, er, numSamples);
4242
}
@@ -57,7 +57,7 @@ void RMSFeedbackCompressor::render(StereoSample* buffer, uint16_t numSamples, q3
5757

5858
state = runEnvelope(state, over, numSamples);
5959

60-
float reduction = -state * ratio;
60+
float reduction = -state * reduction;
6161

6262
// this is the most gain available without overflow
6363
float dbGain = 3.f + er + reduction;

src/deluge/dsp/compressor/rms_feedback.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,18 +67,20 @@ class RMSFeedbackCompressor {
6767
threshold = 1 - 0.8f * (float(thresholdKnobPos) / ONE_Q31f);
6868
}
6969
q31_t getRatio() { return ratioKnobPos; }
70+
constexpr int32_t getRatioForDisplay() { return ratio; }
7071
constexpr int32_t setRatio(q31_t rat) {
7172
ratioKnobPos = rat;
72-
ratio = 0.5f + (float(ratioKnobPos) / ONE_Q31f) / 2;
73-
return 1 / (1 - ratio);
73+
reduction = 0.5f + (float(ratioKnobPos) / ONE_Q31f) / 2;
74+
ratio = 1 / (1 - reduction);
75+
return ratio;
7476
}
7577
q31_t getSidechain() { return sideChainKnobPos; }
76-
78+
constexpr int32_t getSidechainForDisplay() { return fc_hz; }
7779
constexpr int32_t setSidechain(q31_t f) {
7880
sideChainKnobPos = f;
7981
// this exp will be between 1 and 5ish, half the knob range is about 2
8082
// the result will then be from 0 to 100hz with half the knob range at 60hz
81-
float fc_hz = (std::exp(1.5 * float(f) / ONE_Q31f) - 1) * 30;
83+
fc_hz = (std::exp(1.5 * float(f) / ONE_Q31f) - 1) * 30;
8284
float fc = fc_hz / float(kSampleRate);
8385
float wc = fc / (1 + fc);
8486
a = wc * ONE_Q31;
@@ -93,7 +95,7 @@ class RMSFeedbackCompressor {
9395
// parameters in use
9496
float a_ = (-1000.0f / kSampleRate);
9597
float r_ = (-1000.0f / kSampleRate);
96-
float ratio = 2;
98+
float reduction = 0.5;
9799
float er = 0;
98100
float threshdb = 17;
99101
float threshold = 1;
@@ -112,6 +114,8 @@ class RMSFeedbackCompressor {
112114
// for display
113115
float attackMS = 0;
114116
float releaseMS = 0;
117+
float ratio = 2;
118+
float fc_hz;
115119

116120
// raw knob positions
117121
q31_t thresholdKnobPos = 0;

src/deluge/gui/menu_item/audio_compressor/compressor_values.h

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,71 +12,73 @@ class Attack final : public Integer {
1212
using Integer::Integer;
1313
void readCurrentValue() override {
1414
auto value = (uint64_t)soundEditor.currentModControllable->compressor.getAttack();
15-
this->setValue((value * (kMaxMenuValue * 2) + 2147483648) >> 32);
15+
this->setValue(value >> 24);
1616
}
1717
void writeCurrentValue() override {
18-
if (this->getValue() == kMaxMenuValue) {
19-
soundEditor.currentModControllable->compressor.setAttack(ONE_Q31);
20-
}
21-
else {
22-
q31_t knobPos = (uint32_t)this->getValue() * (2147483648 / kMidMenuValue) >> 1;
18+
auto value = this->getValue();
19+
if (value < kMaxKnobPos) {
20+
q31_t knobPos = lshiftAndSaturate<24>(value);
2321
soundEditor.currentModControllable->compressor.setAttack(knobPos);
2422
}
2523
}
26-
[[nodiscard]] int32_t getMaxValue() const override { return kMaxMenuValue; }
24+
int32_t getDisplayValue() override { return soundEditor.currentModControllable->compressor.getAttackMS(); }
25+
const char* getUnit() override { return " MS"; }
26+
[[nodiscard]] int32_t getMaxValue() const override { return kMaxKnobPos; }
2727
};
2828
class Release final : public Integer {
2929
public:
3030
using Integer::Integer;
3131
void readCurrentValue() override {
3232
auto value = (uint64_t)soundEditor.currentModControllable->compressor.getRelease();
33-
this->setValue((value * (kMaxMenuValue * 2) + 2147483648) >> 32);
33+
this->setValue(value >> 24);
3434
}
3535
void writeCurrentValue() override {
36-
if (this->getValue() == kMaxMenuValue) {
37-
soundEditor.currentModControllable->compressor.setRelease(ONE_Q31);
38-
}
39-
else {
40-
q31_t knobPos = (uint32_t)this->getValue() * (2147483648 / kMidMenuValue) >> 1;
36+
auto value = this->getValue();
37+
if (value < kMaxKnobPos) {
38+
q31_t knobPos = lshiftAndSaturate<24>(value);
4139
soundEditor.currentModControllable->compressor.setRelease(knobPos);
4240
}
4341
}
44-
[[nodiscard]] int32_t getMaxValue() const override { return kMaxMenuValue; }
42+
int32_t getDisplayValue() override { return soundEditor.currentModControllable->compressor.getReleaseMS(); }
43+
const char* getUnit() override { return " MS"; }
44+
[[nodiscard]] int32_t getMaxValue() const override { return kMaxKnobPos; }
4545
};
4646
class Ratio final : public Integer {
4747
public:
4848
using Integer::Integer;
4949
void readCurrentValue() override {
5050
auto value = (uint64_t)soundEditor.currentModControllable->compressor.getRatio();
51-
this->setValue((value * (kMaxMenuValue * 2) + 2147483648) >> 32);
51+
this->setValue(value >> 24);
5252
}
5353
void writeCurrentValue() override {
54-
if (this->getValue() == kMaxMenuValue) {
55-
soundEditor.currentModControllable->compressor.setRatio(ONE_Q31);
56-
}
57-
else {
58-
q31_t knobPos = (uint32_t)this->getValue() * (2147483648 / kMidMenuValue) >> 1;
54+
auto value = this->getValue();
55+
if (value < kMaxKnobPos) {
56+
q31_t knobPos = lshiftAndSaturate<24>(value);
5957
soundEditor.currentModControllable->compressor.setRatio(knobPos);
6058
}
6159
}
62-
[[nodiscard]] int32_t getMaxValue() const override { return kMaxMenuValue; }
60+
int32_t getDisplayValue() override { return soundEditor.currentModControllable->compressor.getRatioForDisplay(); }
61+
const char* getUnit() override { return " : 1"; }
62+
[[nodiscard]] int32_t getMaxValue() const override { return kMaxKnobPos; }
6363
};
6464
class SideHPF final : public Integer {
6565
public:
6666
using Integer::Integer;
6767
void readCurrentValue() override {
6868
auto value = (uint64_t)soundEditor.currentModControllable->compressor.getSidechain();
69-
this->setValue((value * (kMaxMenuValue * 2) + 2147483648) >> 32);
69+
this->setValue(value >> 24);
7070
}
7171
void writeCurrentValue() override {
72-
if (this->getValue() == kMaxMenuValue) {
73-
soundEditor.currentModControllable->compressor.setSidechain(ONE_Q31);
74-
}
75-
else {
76-
q31_t knobPos = (uint32_t)this->getValue() * (2147483648 / kMidMenuValue) >> 1;
72+
auto value = this->getValue();
73+
if (value < kMaxKnobPos) {
74+
q31_t knobPos = lshiftAndSaturate<24>(value);
7775
soundEditor.currentModControllable->compressor.setSidechain(knobPos);
7876
}
7977
}
80-
[[nodiscard]] int32_t getMaxValue() const override { return kMaxMenuValue; }
78+
int32_t getDisplayValue() override {
79+
return soundEditor.currentModControllable->compressor.getSidechainForDisplay();
80+
}
81+
const char* getUnit() override { return " HZ"; }
82+
[[nodiscard]] int32_t getMaxValue() const override { return kMaxKnobPos; }
8183
};
8284
} // namespace deluge::gui::menu_item::audio_compressor

src/deluge/gui/menu_item/integer.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ void Integer::selectEncoderAction(int32_t offset) {
3939
}
4040

4141
void Integer::drawValue() {
42-
display->setTextAsNumber(this->getValue());
42+
display->setTextAsNumber(getDisplayValue());
4343
}
4444

4545
void IntegerWithOff::drawValue() {
@@ -53,7 +53,8 @@ void IntegerWithOff::drawValue() {
5353

5454
void Integer::drawInteger(int32_t textWidth, int32_t textHeight, int32_t yPixel) {
5555
char buffer[12];
56-
intToString(this->getValue(), buffer, 1);
56+
intToString(getDisplayValue(), buffer, 1);
57+
strncat(buffer, getUnit(), 4);
5758
deluge::hid::display::OLED::drawStringCentred(buffer, yPixel + OLED_MAIN_TOPMOST_PIXEL,
5859
deluge::hid::display::OLED::oledMainImage[0], OLED_MAIN_WIDTH_PIXELS,
5960
textWidth, textHeight);

src/deluge/gui/menu_item/integer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ class Integer : public Number {
2727
void selectEncoderAction(int32_t offset) override;
2828

2929
protected:
30+
virtual int32_t getDisplayValue() { return this->getValue(); }
31+
virtual const char* getUnit() { return ""; }
32+
3033
void drawPixelsForOled();
3134
virtual void drawInteger(int32_t textWidth, int32_t textHeight, int32_t yPixel);
3235

src/deluge/gui/ui/sound_editor.cpp

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -574,10 +574,8 @@ bool SoundEditor::beginScreen(MenuItem* oldMenuItem) {
574574

575575
// Find param shortcut
576576
currentParamShorcutX = 255;
577-
bool isUISessionView =
578-
(getRootUI() == &performanceSessionView) || (getRootUI() == &sessionView) || (getRootUI() == &arrangerView);
579577

580-
if (isUISessionView) {
578+
if (!rootUIIsClipMinderScreen()) {
581579
int32_t x, y;
582580

583581
// First, see if there's a shortcut for the actual MenuItem we're currently on
@@ -862,10 +860,13 @@ static const uint32_t shortcutPadUIModes[] = {UI_MODE_AUDITIONING, 0};
862860

863861
ActionResult SoundEditor::potentialShortcutPadAction(int32_t x, int32_t y, bool on) {
864862

863+
bool isUIPerformanceSessionView =
864+
(getRootUI() == &performanceSessionView) || (getCurrentUI() == &performanceSessionView);
865+
865866
bool ignoreAction = false;
866867
if (!Buttons::isShiftButtonPressed()) {
867868
// if in Performance Session View
868-
if ((getRootUI() == &performanceSessionView) || (getCurrentUI() == &performanceSessionView)) {
869+
if (isUIPerformanceSessionView) {
869870
// ignore if you're not in editing mode or if you're in editing mode but editing a param
870871
ignoreAction = (!performanceSessionView.defaultEditingMode || performanceSessionView.editingParam);
871872
}
@@ -889,8 +890,7 @@ ActionResult SoundEditor::potentialShortcutPadAction(int32_t x, int32_t y, bool
889890
return ActionResult::NOT_DEALT_WITH;
890891
}
891892

892-
bool isUIPerformanceSessionView =
893-
(getRootUI() == &performanceSessionView) || (getCurrentUI() == &performanceSessionView);
893+
bool isUISessionView = isUIPerformanceSessionView || !rootUIIsClipMinderScreen();
894894

895895
if (on && (isUIModeWithinRange(shortcutPadUIModes) || isUIPerformanceSessionView)) {
896896

@@ -900,8 +900,8 @@ ActionResult SoundEditor::potentialShortcutPadAction(int32_t x, int32_t y, bool
900900

901901
const MenuItem* item = nullptr;
902902

903-
// performance session view
904-
if (isUIPerformanceSessionView) {
903+
// session views (arranger, song, performance)
904+
if (isUISessionView) {
905905
if (x <= (kDisplayWidth - 2)) {
906906
item = paramShortcutsForSongView[x][y];
907907
}
@@ -1322,15 +1322,12 @@ bool SoundEditor::setup(Clip* clip, const MenuItem* item, int32_t sourceIndex) {
13221322
ModControllableAudio* newModControllable = nullptr;
13231323

13241324
UI* currentUI = getCurrentUI();
1325-
AutomationSubType automationSubType = AutomationSubType::NONE;
1326-
if (currentUI == &automationView) {
1327-
automationSubType = automationView.getAutomationSubType();
1328-
}
13291325

13301326
bool isUIPerformanceView = ((getRootUI() == &performanceSessionView) || currentUI == &performanceSessionView);
13311327

13321328
bool isUISessionView = isUIPerformanceView || !rootUIIsClipMinderScreen();
13331329

1330+
13341331
// getParamManager and ModControllable for Performance Session View (and Session View)
13351332
if (isUISessionView) {
13361333
char modelStackMemory[MODEL_STACK_MAX_SIZE];
@@ -1593,19 +1590,10 @@ AudioFileHolder* SoundEditor::getCurrentAudioFileHolder() {
15931590
}
15941591

15951592
ModelStackWithThreeMainThings* SoundEditor::getCurrentModelStack(void* memory) {
1596-
RootUI* rootUI = getRootUI();
1597-
AutomationSubType automationSubType = AutomationSubType::NONE;
1598-
if (rootUI == &automationView) {
1599-
automationSubType = automationView.getAutomationSubType();
1600-
}
1601-
1602-
bool isUISessionView = (rootUI == &performanceSessionView) || (rootUI == &sessionView) || (rootUI == &arrangerView)
1603-
|| (automationSubType == AutomationSubType::ARRANGER);
1604-
16051593
InstrumentClip* clip = getCurrentInstrumentClip();
16061594
Instrument* instrument = getCurrentInstrument();
16071595

1608-
if (isUISessionView) {
1596+
if (!rootUIIsClipMinderScreen()) {
16091597
return currentSong->setupModelStackWithSongAsTimelineCounter(memory);
16101598
}
16111599
else if (instrument->type == OutputType::KIT && clip->affectEntire) {

src/deluge/gui/ui/ui.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,11 @@ bool rootUIIsTimelineView() {
146146
return (rootUI && rootUI->isTimelineView());
147147
}
148148

149+
bool currentUIIsClipMinderScreen() {
150+
UI* currentUI = getCurrentUI();
151+
return (currentUI && currentUI->toClipMinder());
152+
}
153+
149154
bool rootUIIsClipMinderScreen() {
150155
UI* rootUI = getRootUI();
151156
return (rootUI && rootUI->toClipMinder());

src/deluge/gui/ui/ui.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ void setRootUILowLevel(UI* newUI);
162162
void swapOutRootUILowLevel(UI* newUI);
163163
void nullifyUIs();
164164
bool rootUIIsTimelineView();
165+
bool currentUIIsClipMinderScreen();
165166
bool rootUIIsClipMinderScreen();
166167
std::pair<uint32_t, uint32_t> getUIGreyoutColsAndRows();
167168

src/deluge/model/global_effectable/global_effectable.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,7 @@ ActionResult GlobalEffectable::modEncoderActionForNonExistentParam(int32_t offse
526526
int current;
527527
int displayLevel;
528528
int ledLevel;
529+
const char* unit;
529530
// this is only reachable in comp editing mode, otherwise it's an existent param
530531
if (whichModEncoder == 1) { // sidechain (threshold)
531532
current = (compressor.getThreshold() >> 24) - 64;
@@ -535,6 +536,7 @@ ActionResult GlobalEffectable::modEncoderActionForNonExistentParam(int32_t offse
535536
displayLevel = ((ledLevel)*kMaxMenuValue) / 128;
536537
compressor.setThreshold(lshiftAndSaturate<24>(current + 64));
537538
indicator_leds::setKnobIndicatorLevel(1, ledLevel);
539+
unit = "";
538540
}
539541
else if (whichModEncoder == 0) {
540542
switch (currentCompParam) {
@@ -545,9 +547,8 @@ ActionResult GlobalEffectable::modEncoderActionForNonExistentParam(int32_t offse
545547
// this range is ratio of 2 to 20
546548
current = std::clamp(current, -64, 64);
547549
ledLevel = (64 + current);
548-
displayLevel = ((ledLevel)*kMaxMenuValue) / 128;
549-
550550
displayLevel = compressor.setRatio(lshiftAndSaturate<24>(current + 64));
551+
unit = " : 1";
551552
break;
552553

553554
case CompParam::ATTACK:
@@ -557,6 +558,7 @@ ActionResult GlobalEffectable::modEncoderActionForNonExistentParam(int32_t offse
557558
ledLevel = (64 + current);
558559

559560
displayLevel = compressor.setAttack(lshiftAndSaturate<24>(current + 64));
561+
unit = " MS";
560562
break;
561563

562564
case CompParam::RELEASE:
@@ -566,6 +568,7 @@ ActionResult GlobalEffectable::modEncoderActionForNonExistentParam(int32_t offse
566568
ledLevel = (64 + current);
567569

568570
displayLevel = compressor.setRelease(lshiftAndSaturate<24>(current + 64));
571+
unit = " MS";
569572
break;
570573

571574
case CompParam::SIDECHAIN:
@@ -575,12 +578,16 @@ ActionResult GlobalEffectable::modEncoderActionForNonExistentParam(int32_t offse
575578
ledLevel = (64 + current);
576579

577580
displayLevel = compressor.setSidechain(lshiftAndSaturate<24>(current + 64));
581+
unit = " HZ";
578582
break;
579583
}
580584
indicator_leds::setKnobIndicatorLevel(0, ledLevel);
581585
}
582-
char buffer[5];
586+
char buffer[12];
583587
intToString(displayLevel, buffer);
588+
if (display->haveOLED()) {
589+
strncat(buffer, unit, 4);
590+
}
584591
display->displayPopup(buffer);
585592

586593
return ActionResult::DEALT_WITH;
@@ -886,6 +893,10 @@ bool GlobalEffectable::readParamTagFromFile(char const* tagName, ParamManagerFor
886893
unpatchedParams->readParam(unpatchedParamsSummary, params::UNPATCHED_LPF_RES, readAutomationUpToPos);
887894
storageManager.exitTag("resonance");
888895
}
896+
else if (!strcmp(tagName, "morph")) {
897+
unpatchedParams->readParam(unpatchedParamsSummary, params::UNPATCHED_LPF_MORPH, readAutomationUpToPos);
898+
storageManager.exitTag("morph");
899+
}
889900
}
890901
storageManager.exitTag("lpf");
891902
}
@@ -900,6 +911,10 @@ bool GlobalEffectable::readParamTagFromFile(char const* tagName, ParamManagerFor
900911
unpatchedParams->readParam(unpatchedParamsSummary, params::UNPATCHED_HPF_RES, readAutomationUpToPos);
901912
storageManager.exitTag("resonance");
902913
}
914+
else if (!strcmp(tagName, "morph")) {
915+
unpatchedParams->readParam(unpatchedParamsSummary, params::UNPATCHED_HPF_MORPH, readAutomationUpToPos);
916+
storageManager.exitTag("morph");
917+
}
903918
}
904919
storageManager.exitTag("hpf");
905920
}

0 commit comments

Comments
 (0)