Skip to content

Commit

Permalink
Master comp UI improvements (#655)
Browse files Browse the repository at this point in the history
* move comp params to click on reverb gold knob

add timeout to meters

popups

* set led for non existent params

* clarifying comments

* prep for move to param manager

* tweak ranges

* dbt format

* popup values out of 50

* Added feature to show last return addresses on grid going into fault handler

* Implemented new grid options and added J-Link debug server launching to launch config (#652)

* Display Mod Encoder Values with Popup, Update Value Ranges in Menu's, Update Midi CC Value Range, Bug Fix for Midi CC Assignment in Automation Overview (#636)

* Display Mod Encoder Values with Popup

Added code to view.cpp to display new value corresponding to the parameter that the mod encoder being turned is assigned to.

Removed display popup code for from MidiParamCollection and ExpressionParamSet as its no longer required.

* Fixed value displayed for Pan

Changed display of Pan values from:

0 - 128

to

-64 - +64

* Dbt Format

* Updated Menu Value Adjustment Range

Updated the Value Adjustment range in the menu from 0 - 50 to 0 - 128.

For Pan, the range changed from -32 to +32 to -64 to + 64

* Updated Param Value Range for Patch Cables

Factored out the constants for Patch Cables

Updated range from -50 to.+50 to -128 to +128 to align with the +128 range displayed for params in the regular menu's

* Adjust displayed of popups when in soundEditor

When in soundEditor, if you turn a modEncoder, it will only display a pop up when you're turning a modEncoder that is mapped to a parameter that is different from the parameter being edited in the soundEditor menu

* Ignore modEncoder turns for Midi above 127

Currently there is a bug where turning the knob to the 128th position acts as sending 127 twice.

Instead of doing that, I have set it to ignore modEncoderActions for MIDI Instrument Clips that result in the knob turning to 128 or turning from 128 to 127.

* Dbt Format

* Update Midi CC Value Range in Automation Instrument Clip View

Changed Midi CC Value Range in Automation Instrument Clip View from 0 - 128 to 0 - 127.

* dbt format

* Bug Fix + Documentation

Documented some changes to Automation Instrument Clip View for Midi CC values

Fixed issue where you could not assign a Midi CC to a Mod Encoder with the Select Encoder when in the Automation Overview

* Adjustments

- Added description of improvements to community_features.md
- Reversed changes to compressor attack / release menu items per feedback from @m-m-adams
- Updated selectEncoderAction when in Menu to adjust menu values by +/- 2 by default. To adjust menu values by +/- 1, you just need to hold shift.

* Fixed quantized stutter crashing

Fixed bug with quantize stutter crashing

* Fixed selectEncoder default acceleration

Changed default acceleration for Select Encoder back to +/- 1 as changing it to +/- 2 affects scrolling through menu items.

* Adjusted select encoder acceleration

Per feedback, adjusted select encoder acceleration to +/- 5 while holding shift

* Updated display for stutter quantization

if turning stutter mod encoder and stutter quantize is enabled, display stutter quantization instead of knob position

* dbt format

* Fixed stutter display

When pressing down on the stutter mod encoder and turning the knob, the knob now displays the fine tuned stutter amounts rather than the quantized amounts.

* Updated knobPos displayed

1) Changed menu range back to 0 - 50 (Pan displays -25 to +25)

2) Changed mod encoder pop-ups to display the 0-50 range by converting the 0-128 knob positions to 0 - 50 (with the exception of Pan which displays -25 to +25)

3) Updated parameter values displayed in Automation View to use the 0 - 50 range (except for MIDI which stays with 0 - 127)

4) Update Pan in Automation View to display the -25 to +25 range
Changed range from 0 - 128 to 0 - 50

5) Some cleanup of function definitions in Automation View by passing the InstrumentClip and Instrument variables where needed

* Updates to documentation

* Don't strip symbols from release ELF, only strip them in object

* dbt format

* seperate led level from popup

use new max menu constant where possible

* set correct values

* set better default values

---------

Co-authored-by: Paul Freund <[email protected]>
Co-authored-by: Sean Ditny <[email protected]>
  • Loading branch information
3 people authored Oct 30, 2023
1 parent 7a752d7 commit 1556628
Show file tree
Hide file tree
Showing 11 changed files with 142 additions and 41 deletions.
7 changes: 7 additions & 0 deletions src/definitions_cxx.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,13 @@ enum class ModFXParam {
FEEDBACK,
OFFSET,
};

enum class CompParam {
RATIO,
ATTACK,
RELEASE,
};

constexpr auto kNumModFXParams = util::to_underlying(ModFXParam::OFFSET) + 1;

enum class PatchCableAcceptance {
Expand Down
7 changes: 5 additions & 2 deletions src/deluge/dsp/master_compressor/master_compressor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ MasterCompressor::MasterCompressor() {
shape = getParamFromUserValue(Param::Unpatched::COMPRESSOR_SHAPE, 1);
//an appropriate range is 0-50*one q 15
threshold = ONE_Q31;
rawThreshold = 0;
follower = true;
//this is about a 1:1 ratio
ratio = ONE_Q31 >> 1;
Expand Down Expand Up @@ -64,6 +65,8 @@ void MasterCompressor::updateER() {
}

void MasterCompressor::render(StereoSample* buffer, uint16_t numSamples, q31_t volAdjustL, q31_t volAdjustR) {
ratio = (rawRatio >> 1) + (3 << 28);
threshold = ONE_Q31 - rawThreshold;
updateER();

q31_t over = std::max<float>(0, (meanVolume - threshdb) / 21) * ONE_Q31;
Expand Down Expand Up @@ -144,7 +147,7 @@ float MasterCompressor::calc_rms(StereoSample* buffer, uint16_t numSamples) {
void MasterCompressor::setup(int32_t a, int32_t r, int32_t t, int32_t rat) {
attack = a;
release = r;
threshold = t;
ratio = rat;
rawThreshold = t;
rawRatio = rat;
updateER();
}
2 changes: 2 additions & 0 deletions src/deluge/dsp/master_compressor/master_compressor.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class MasterCompressor : public Compressor {
float calc_rms(StereoSample* buffer, uint16_t numSamples);
uint8_t gainReduction;
bool dither;
q31_t rawRatio;
q31_t rawThreshold;
q31_t threshold;
q31_t shape;
q31_t ratio;
Expand Down
3 changes: 2 additions & 1 deletion src/deluge/gui/ui_timer_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
#define TIMER_OLED_CONSOLE 16
#define TIMER_OLED_SCROLLING_AND_BLINKING 17
#define TIMER_SYSEX_DISPLAY 18
#define NUM_TIMERS 19
#define TIMER_METER_INDICATOR_BLINK 19
#define NUM_TIMERS 20

struct Timer {
bool active;
Expand Down
5 changes: 2 additions & 3 deletions src/deluge/gui/views/session_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1921,9 +1921,8 @@ void SessionView::graphicsRoutine() {
counter = (counter + 1) % 5;
if (counter == 0) {
uint8_t gr = AudioEngine::mastercompressor.gainReduction;
//uint8_t mv = int(6 * AudioEngine::mastercompressor.meanVolume);
indicator_leds::setKnobIndicatorLevel(1, gr); //Gain Reduction LED
//indicator_leds::setKnobIndicatorLevel(0, mv); //Input level LED

indicator_leds::setMeterLevel(1, gr); //Gain Reduction LED
}
}
}
Expand Down
19 changes: 19 additions & 0 deletions src/deluge/hid/led/indicator_leds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ uint8_t whichLevelIndicatorBlinking;
bool levelIndicatorBlinkOn;
uint8_t levelIndicatorBlinksLeft;

uint8_t whichKnobMetering;

void setLedState(LED led, bool newState, bool allowContinuedBlinking) {

if (!allowContinuedBlinking) {
Expand Down Expand Up @@ -164,8 +166,25 @@ void indicateAlertOnLed(LED led) {
blinkLed(led, 3, 1);
}

//this sets the level only if there hasn't been a value update in 500ms
void setMeterLevel(uint8_t whichKnob, uint8_t level) {
whichKnobMetering = whichKnob;
if (!uiTimerManager.isTimerSet(TIMER_METER_INDICATOR_BLINK)) {
actuallySetKnobIndicatorLevel(whichKnob, level);
}
}

// Level is out of 128
//Set level and block metering for 500ms
void setKnobIndicatorLevel(uint8_t whichKnob, uint8_t level) {
if (whichKnob == whichKnobMetering) {
uiTimerManager.setTimer(TIMER_METER_INDICATOR_BLINK, 500);
}
actuallySetKnobIndicatorLevel(whichKnob, level);
}

//Just set level
void actuallySetKnobIndicatorLevel(uint8_t whichKnob, uint8_t level) {
// If this indicator was blinking, stop it
if (uiTimerManager.isTimerSet(TIMER_LEVEL_INDICATOR_BLINK) && whichLevelIndicatorBlinking == whichKnob) {
uiTimerManager.unsetTimer(TIMER_LEVEL_INDICATOR_BLINK);
Expand Down
2 changes: 2 additions & 0 deletions src/deluge/hid/led/indicator_leds.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ void setLedState(LED led, bool newState, bool allowContinuedBlinking = false);
void blinkLed(LED led, uint8_t numBlinks = 255, uint8_t blinkingType = 0, bool initialState = true);
void ledBlinkTimeout(uint8_t blinkingType, bool forceRestart = false, bool resetToState = true);
void indicateAlertOnLed(LED led);
void setMeterLevel(uint8_t whichKnob, uint8_t level);
void setKnobIndicatorLevel(uint8_t whichKnob, uint8_t level);
void actuallySetKnobIndicatorLevel(uint8_t whichKnob, uint8_t level);
void clearKnobIndicatorLevels();
void blinkKnobIndicator(int32_t whichKnob);
void stopBlinkingKnobIndicator(int32_t whichKnob);
Expand Down
131 changes: 97 additions & 34 deletions src/deluge/model/global_effectable/global_effectable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ GlobalEffectable::GlobalEffectable() {
memset(allpassMemory, 0, sizeof(allpassMemory));
memset(&phaserMemory, 0, sizeof(phaserMemory));
editingComp = false;
currentCompParam = CompParam::RATIO;
}

void GlobalEffectable::cloneFrom(ModControllableAudio* other) {
Expand Down Expand Up @@ -267,7 +268,17 @@ bool GlobalEffectable::modEncoderButtonAction(uint8_t whichModEncoder, bool on,
else if (modKnobMode == 4) {
if (whichModEncoder == 0) { // Reverb
if (on) {
view.cycleThroughReverbPresets();
//if we're in full move/editingComp then we cycle through the comp params
//otherwise cycle reverb sizes
if (!editingComp) {
view.cycleThroughReverbPresets();
}
else {
currentCompParam =
static_cast<CompParam>((util::to_underlying(currentCompParam) + 1) % maxCompParam);
const char* params[3] = {"ratio", "attack", "release"};
display->popupTextTemporary(params[int(currentCompParam)]);
}
}
}
else {
Expand All @@ -282,50 +293,102 @@ bool GlobalEffectable::modEncoderButtonAction(uint8_t whichModEncoder, bool on,

return false; // Some cases could lead here
}
ActionResult GlobalEffectable::modEncoderActionForNonExistentParam(int32_t offset, int32_t whichModEncoder,
ModelStackWithAutoParam* modelStack) {

int32_t GlobalEffectable::getKnobPosForNonExistentParam(int32_t whichModEncoder, ModelStackWithAutoParam* modelStack) {
int displayLevel = -64;
if (*getModKnobMode() == 4) {
int current;

//this is only reachable in comp editing mode, otherwise it's an existent param
if (whichModEncoder == 1) { //sidechain (threshold)
int current = AudioEngine::mastercompressor.threshold >> 24;
current -= offset;
current = std::clamp(current, 1, 128);
indicator_leds::setKnobIndicatorLevel(1, std::max(0, 128 - current));
AudioEngine::mastercompressor.threshold = lshiftAndSaturate<24>(current);
return ActionResult::DEALT_WITH;
}
else if (whichModEncoder == 0) { //ratio/reverb (we can only get here in comp editing mode)
int current = AudioEngine::mastercompressor.ratio >> 24;
current += offset;
//this range is ratio of 2 to infinity
current = std::clamp(current, 48, 112);
indicator_leds::setKnobIndicatorLevel(0, (current - 48) * 2);
AudioEngine::mastercompressor.ratio = lshiftAndSaturate<24>(current);
return ActionResult::DEALT_WITH;
current = AudioEngine::mastercompressor.rawThreshold >> 24;
displayLevel = current;
}
else if (whichModEncoder == 0) {
switch (currentCompParam) {

case CompParam::RATIO:
current = AudioEngine::mastercompressor.rawRatio >> 24;
displayLevel = current;
break;

case CompParam::ATTACK:
current = getLookupIndexFromValue(AudioEngine::mastercompressor.attack >> 2, attackRateTable, 50);
displayLevel = (current * 128) / 50;
break;

case CompParam::RELEASE:
current = getLookupIndexFromValue(AudioEngine::mastercompressor.release >> 1, releaseRateTable, 50);
displayLevel = (current * 128) / 50;
break;
}
}
}
else if (*getModKnobMode() == 2) {
if (whichModEncoder == 1) { //attack
int current = getLookupIndexFromValue(AudioEngine::mastercompressor.attack >> 2, attackRateTable, 50);
return displayLevel - 64;
}

ActionResult GlobalEffectable::modEncoderActionForNonExistentParam(int32_t offset, int32_t whichModEncoder,
ModelStackWithAutoParam* modelStack) {
if (*getModKnobMode() == 4) {
int current;
int displayLevel;
int ledLevel;
//this is only reachable in comp editing mode, otherwise it's an existent param
if (whichModEncoder == 1) { //sidechain (threshold)
current = (AudioEngine::mastercompressor.rawThreshold >> 24) - 64;
current += offset;
current = std::clamp(current, 1, 50);
indicator_leds::setKnobIndicatorLevel(1, (current * 128) / 50);
AudioEngine::mastercompressor.attack = attackRateTable[current] << 2;
return ActionResult::DEALT_WITH;
current = std::clamp(current, -64, 64);
ledLevel = (64 + current);
displayLevel = ((ledLevel)*kMaxMenuValue) / 128;
AudioEngine::mastercompressor.rawThreshold = lshiftAndSaturate<24>(current + 64);
indicator_leds::setKnobIndicatorLevel(1, ledLevel);
}
if (whichModEncoder == 0) { //release
int current = getLookupIndexFromValue(AudioEngine::mastercompressor.release >> 1, releaseRateTable, 50);
current += offset;
current = std::clamp(current, 2, 50);
indicator_leds::setKnobIndicatorLevel(0, (current * 128) / 50);
AudioEngine::mastercompressor.release = releaseRateTable[current] << 1;
else if (whichModEncoder == 0) {
switch (currentCompParam) {

case CompParam::RATIO:
current = (AudioEngine::mastercompressor.rawRatio >> 24) - 64;
current += offset;
//this range is ratio of 2 to 20
current = std::clamp(current, -64, 64);
ledLevel = (64 + current);
displayLevel = ((ledLevel)*kMaxMenuValue) / 128;

AudioEngine::mastercompressor.rawRatio = lshiftAndSaturate<24>(current + 64);
break;

case CompParam::ATTACK:
current = getLookupIndexFromValue(AudioEngine::mastercompressor.attack >> 2, attackRateTable, 50);
current += offset;
current = std::clamp(current, 1, 50);
displayLevel = current;
ledLevel = (displayLevel * 128) / 50;

AudioEngine::mastercompressor.attack = attackRateTable[current] << 2;
break;

return ActionResult::DEALT_WITH;
case CompParam::RELEASE:

current = getLookupIndexFromValue(AudioEngine::mastercompressor.release, releaseRateTable, 50);
current += offset;
current = std::clamp(current, 0, 50);
displayLevel = current;
ledLevel = (displayLevel * 128) / 50;

AudioEngine::mastercompressor.release = releaseRateTable[current];

break;
}
indicator_leds::setKnobIndicatorLevel(0, ledLevel);
}
}
char buffer[5];
intToString(displayLevel, buffer);
display->displayPopup(buffer);

return ActionResult::DEALT_WITH;
}
return ActionResult::NOT_DEALT_WITH;
}

// Always check this doesn't return NULL!
int32_t GlobalEffectable::getParameterFromKnob(int32_t whichModEncoder) {

Expand Down
3 changes: 3 additions & 0 deletions src/deluge/model/global_effectable/global_effectable.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,17 @@ class GlobalEffectable : public ModControllableAudio {
void setupDelayWorkingState(DelayWorkingState* delayWorkingState, ParamManager* paramManager,
bool shouldLimitDelayFeedback = false);
bool isEditingComp() override { return editingComp; }
int32_t getKnobPosForNonExistentParam(int32_t whichModEncoder, ModelStackWithAutoParam* modelStack) override;
ActionResult modEncoderActionForNonExistentParam(int32_t offset, int32_t whichModEncoder,
ModelStackWithAutoParam* modelStack) override;
dsp::filter::FilterSet filterSet;
ModFXParam currentModFXParam;
FilterType currentFilterType;
bool editingComp;
CompParam currentCompParam;

protected:
int maxCompParam = 0;
virtual int32_t getParameterFromKnob(int32_t whichModEncoder);
ModFXType getActiveModFXType(ParamManager* paramManager);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@

GlobalEffectableForSong::GlobalEffectableForSong() {
modKnobMode = 1;
//attack and release can't go in the param manager so this keeps them from changing in clip comps
maxCompParam = 3;
}
2 changes: 1 addition & 1 deletion src/deluge/model/song/song.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ Song::Song() : backedUpParamManagers(sizeof(BackedUpParamManager)) {

masterCompressorAttack = attackRateTable[2] << 2;
masterCompressorRelease = releaseRateTable[5] << 2;
masterCompressorThresh = ONE_Q31;
masterCompressorThresh = 0;
masterCompressorRatio = ONE_Q31 >> 1;
AudioEngine::mastercompressor.gainReduction = 0.0;

Expand Down

0 comments on commit 1556628

Please sign in to comment.