Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Midi Takeover Mode #170

Merged
merged 12 commits into from Jul 14, 2023
Merged

Conversation

seangoodvibes
Copy link
Collaborator

@seangoodvibes seangoodvibes commented Jul 7, 2023

Midi Takeover Mode

A new item has been added to the Midi menu: Takeover

The Takeover menu consists of three modes that can be selected from:

Jump: This is the default mode for the Deluge. As soon as a Midi Knob/Fader position is changed, the Deluge's internal Knob position/Parameter value jumps to the position of the Midi Knob/Fader.

Pickup: The deluge will ignore changes to its internal Knob position/Parameter value until the Midi Knob/Fader's position is equal to the Deluge Knob position. After which the Midi Knob/Fader will move in sync with the Deluge.

Scale: The deluge will increase/decrease its internal Knob position/Parameter value relative to the change of the Midi Knob/Fader position and the amount of "runway" remaining on the Midi controller. Once the Midi controller reaches its maximum or minimum position, the Midi Knob/Fader will move in sync with the Deluge. The Deluge will value will always decrease/increase in the same direction as the Midi controller.

Summary of changes to Deluge's code:

Expanded MidiKnob class to include previous position info:

Deluge/src/deluge/modulation/knob.h

class MIDIKnob : public Knob {
public:
	MIDIKnob() {}
	bool isRelative() { return relative; }
	bool is14Bit() { return (midiInput.noteOrCC == 128); }
	bool topValueIs127() { return (midiInput.noteOrCC < 128 && !relative); }
	LearnedMIDI midiInput;
	bool relative;
	bool previousPositionSaved;
	int previousPosition;
};

Added code for Pickup and Takeover Modes

Deluge/src/deluge/model/model_controllable/mod_controllable_audio.cpp

#include "io/midi/midi_engine.h"

bool ModControllableAudio::offerReceivedCCToLearnedParams(MIDIDevice* fromDevice, uint8_t channel, uint8_t ccNumber,
                                                          uint8_t value, ModelStackWithTimelineCounter* modelStack,
                                                          int noteRowIndex) {

***[...]***

else {
	if (midiEngine.midiTakeover == MIDI_TAKEOVER_JUMP) {//Midi Takeover Mode = Jump
		newKnobPos = 64;
		if (value < 127) {
			newKnobPos = (int)value - 64;
		}
		knob->previousPositionSaved = false;
	}
	else { //Midi Takeover Mode = Pickup or Value Scaling
		/*
		Step #1: Convert Midi Controller's CC Value to Deluge Knob Position Value

		- Midi CC Values for non endless encoders typically go from 0 to 127
		- Deluge Knob Position Value goes from -64 to 64

		To convert Midi CC Value to Deluge Knob Position Value, subtract 64 from the Midi CC Value

		So a Midi CC Value of 0 is equal to a Deluge Knob Position Value of -64 (0 less 64).

		Similarly a Midi CC Value of 127 is equal to a Deluge Knob Position Value of +63 (127 less 64)

		*/

		int midiKnobPos = value - 64;

		//Save previous knob position for first time
		//The first time a midi knob is turned in a session, no previous midi knob position information exists, so to start, it will be equal to the current midiKnobPos
		//This code is also executed when takeover mode is changed to Jump and back to Pickup/Scale because in Jump mode no previousPosition information gets saved

		if (!knob->previousPositionSaved) {
			knob->previousPosition = midiKnobPos;

			knob->previousPositionSaved = true;
		}

		//adjust previous knob position saved

		//Here we check to see if the midi knob position previously saved is greater or less than the current midi knob position +/- 1
		//If it's by more than 1, the previous position is adjusted.
		//This could happen for example if you changed banks and the previous position is no longer valid.
		//By resetting the previous position we ensure that the there isn't unwanted jumpyness in the calculation of the midi knob position change amount
		if (knob->previousPosition > (midiKnobPos + 1) || knob->previousPosition < (midiKnobPos - 1)) {

			knob->previousPosition = midiKnobPos;
		}

		//Here we obtain the current Parameter Value on the Deluge
		int32_t previousValue =
			modelStackWithParam->autoParam->getValuePossiblyAtPos(modPos, modelStackWithParam);

		//Here we convert the current Parameter Value on the Deluge to a Knob Position Value
		int knobPos =
			modelStackWithParam->paramCollection->paramValueToKnobPos(previousValue, modelStackWithParam);

		//Here is where we check if the Knob/Fader on the Midi Controller is out of sync with the Deluge Knob Position

		//First we check if the Midi Knob/Fader is sending a Value that is less the current Deluge Knob Position
		//If less, check by how much its less. If the difference is greater than 1, ignore the CC value change (or scale it if value scaling is on)
		if (midiKnobPos == (knobPos - 1)) {
			newKnobPos = knobPos - 1;
		}

		//Next we check if the Midi Knob/Fader is sending a Value that is greater than the current Deluge Knob Position
		//If greater, check by how much its greater. If the difference is greater than 1, ignore the CC value change (or scale it if value scaling is on)
		else if (midiKnobPos == (knobPos + 1)) {
			newKnobPos = knobPos + 1;
		}

		else {

			//if the first two conditions fail and pickup mode is enabled, then the Deluge Knob Position (and therefore the Parameter Value with it) remains unchanged
			if (midiEngine.midiTakeover == MIDI_TAKEOVER_PICKUP) {//(runtimeFeatureSettings.get(RuntimeFeatureSettingType::MidiTakeoverMode) == RuntimeFeatureStateToggle::PU) { //Midi Pickup Mode On
				newKnobPos = knobPos;
			}
			//if the first two conditions fail and value scaling mode is enabled, then the Deluge Knob Position is scaled upwards or downwards based on relative
			//positions of Midi Controller Knob and Deluge Knob to min/max of knob range.
			else { //Midi Value Scaling Mode On
				//Set the max and min of the deluge midi knob position range
				int knobMaxPos = 64;
				int knobMinPos = -64;

				//calculate amount of deluge "knob runway" is remaining from current knob position to max and min of knob position range
				int delugeKnobMaxPosDelta = knobMaxPos - knobPos; //calculate how far delugeKnobPos is from Max - Positive Runway
				int delugeKnobMinPosDelta = knobPos - knobMinPos; //calculate how far delugeKnobPos is from Min - Negative Runway

				//calculate amount of midi "knob runway" is remaining from current knob position to max and min of knob position range
				int midiKnobMaxPosDelta = knobMaxPos - midiKnobPos; //calculate how far midiKnobPos is from Max - Positive Runway
				int midiKnobMinPosDelta = midiKnobPos - knobMinPos; //calculate how far midiKnobPos is from Min - Negative Runway

				//calculate by how much the current midiKnobPos has changed from the previous midiKnobPos recorded
				int midiKnobPosChange = midiKnobPos - knob->previousPosition;

				//Set fixed point variable which will be used calculate the percentage in midi knob position
				int midiKnobPosChangePercentage;

				//if midi knob position change is greater than 0, then the midi knob position has increased (e.g. turned knob right)
				if (midiKnobPosChange > 0) {
					//fixed point math calculation of new deluge knob position when midi knob position has increased

					midiKnobPosChangePercentage = (midiKnobPosChange << 20) / midiKnobMaxPosDelta;

					newKnobPos = knobPos + ((delugeKnobMaxPosDelta * midiKnobPosChangePercentage) >> 20);
				}
				//if midi knob position change is less than 0, then the midi knob position has decreased (e.g. turned knob left)
				else if (midiKnobPosChange < 0) {
					//fixed point math calculation of new deluge knob position when midi knob position has decreased
					
					midiKnobPosChangePercentage = (midiKnobPosChange << 20) / midiKnobMinPosDelta;

					newKnobPos = knobPos + ((delugeKnobMinPosDelta * midiKnobPosChangePercentage) >> 20);
				}
				//if midi knob position change is 0, then the midi knob position has not changed and thus no change in deluge knob position / parameter value is required
				else {
					newKnobPos = knobPos;
				}

			}
		}

		//save the current midi knob position as the previous midi knob position so that it can be used next time the takeover code is executed
		knob->previousPosition = midiKnobPos;
	}
}

***[...]***

}

Defined Takeover menu values and number of modes

Deluge/src/definitions.h

#define MIDI_TAKEOVER_JUMP 0
#define MIDI_TAKEOVER_PICKUP 1
#define MIDI_TAKEOVER_SCALE 2
#define NUM_MIDI_TAKEOVER_MODES 3

Added Takeover Modes to Midi Engine (to store Takeover Mode selection from Midi menu)

Deluge/src/deluge/io/midi/midi_engine.h

class MidiEngine {
public:
uint8_t midiTakeover;
}

Deluge/src/deluge/io/midi/midi_engine.cpp

MidiEngine::MidiEngine() {
midiTakeover = 0;
}

Defined Takeover Menu

Deluge/src/deluge/gui/menu_item/midi/takeover.h

#pragma once
#include "gui/menu_item/selection.h"
#include "io/midi/midi_engine.h"
#include "gui/ui/sound_editor.h"

namespace menu_item::midi {
class Takeover final : public Selection {
public:
	using Selection::Selection;
	void readCurrentValue() { soundEditor.currentValue = midiEngine.midiTakeover; }
	void writeCurrentValue() { midiEngine.midiTakeover = soundEditor.currentValue; }
	char const** getOptions() {
		static char const* options[] = {"Jump", "Pickup", "Scale", NULL};
		return options;
	}
	int getNumOptions() { return NUM_MIDI_TAKEOVER_MODES; }
};
} // namespace menu_item::midi

Added Midi Takeover submenu

Deluge/src/deluge/gui/ui/menus.cpp

#include "gui/menu_item/midi/takeover.h"

// MIDI Takeover
midi::Takeover midiTakeoverMenu{HAVE_OLED ? "TAKEOVER" : "TOVR"};

//MIDI menu
MenuItem* midiMenuItems[] = {&midiClockMenu, &midiThruMenu, &midiTakeoverMenu, &midiCommandsMenu, &midiInputDifferentiationMenu, &midi::devicesMenu, NULL};

Added read/write to save Midi Takeover Settings to XML file

Deluge/src/deluge/storage/flash_storage.cpp

void resetSettings() {
midiEngine.midiTakeover = 0;
}

void readSettings() {
midiEngine.midiTakeover = buffer[113];
}

void writeSettings() {
buffer[113] = midiEngine.midiTakeover;
}

Midi Pickup Mode enables the Deluge to ignore Midi CC Values from Controllers that are out of Sync with the Deluge.

For example, if an External Midi Controller is sending a Midi CC Value of 0 to the Deluge for a Parameter on the Deluge that is currently set to an equivalent Midi CC Value of 127, then the devices are out of sync.

The Deluge will ignore Midi CC Values from the Midi Controller until the Midi Controller has been "reset" / matches the current Parameter Value on the Deluge.

It does this by comparing the incoming Midi CC Value with the Deluge's internal Knob Position (which is derived from the Current Parameter Value).

The Deluge Internal Knob Position can be converted to a Midi CC Value and Vice Versa by subtracting 64 from the Midi CC Value or adding 64 to the Deluge's Knob Position.

If the difference between the Deluge's Internal Knob Position and the Midi CC Value is greater than +/- 1, then the Midi CC Value is ignored the Parameter's Value will not be changed.

The feature can be disabled using the Community Features menu in Settings. on the Deluge.
@weavermedia
Copy link
Contributor

Could value scaling be added to this, similar to Ableton Live and many other MIDI controllable devices?

From the Ableton Live docs:

Value Scaling — This option ensures smooth value transitions. It compares the physical control’s value to the destination parameter’s value and calculates a smooth convergence of the two as the control is moved. As soon as they are equal, the destination value tracks the control’s value 1:1.

Or maybe as a future enhancement?

@seangoodvibes
Copy link
Collaborator Author

seangoodvibes commented Jul 7, 2023

Could value scaling be added to this, similar to Ableton Live and many other MIDI controllable devices?

From the Ableton Live docs:

Value Scaling — This option ensures smooth value transitions. It compares the physical control’s value to the destination parameter’s value and calculates a smooth convergence of the two as the control is moved. As soon as they are equal, the destination value tracks the control’s value 1:1.

Or maybe as a future enhancement?

Hey absolutely that is possible.

I would make it selectable. So you would have Midi Pickup Mode with or without scaling

I would just need to understand the intended behaviour.

If we take an example, could you please describe how you would expect the Deluge to react?

————-

Example #1

Let’s say the Deluge Parameter Value is 50 and the Midi Parameter Value is 0.

So Deluge’s Knob Position is all the way right and the MIDI Knob Position is all the way left.

When I turn the MIDI Knob right, how should the Deluge Parameter Value change?

Would for example the Deluge Value decrease until 25 when the knobs are in the same position and then they move together after that?

—————

Example #2

Deluge Value is 25
MIDI Value is 40

so midi knob is further right than deluge knob

When I turn Midi Knob right, what happens to the Deluge Value?

when I turn MIDI Knob left, what happens to the Deluge Value?

Thanks!

@weavermedia
Copy link
Contributor

While I'm sure there are 'proper' algorithms for this value scaling behavior this would be my two cents:


Example 1 (knob turns towards the current Deluge value)

Yes, exactly what you described. As the knob turns right the same value difference is deducted from the Deluge value, bringing the two values towards each other.

Knob moves 0 to 2 👉 Deluge value moves 50 to 48
Knob moves 2 to 10 👉 Deluge value moves 48 to 40
Knob moves 10 to 25 👉 Deluge value moes 40 to 25
After this point the values track 1:1


Example 2 (knob turns away from current Deluge value)

Here I think we use a multiple that takes into account how far is left to the end of the scale for each value.

Deluge value = 25
Knob value = 40
Deluge has 25 values left to end of scale (in the direction of change)
Knob has 10 values left to ned of scale (in the direction of change)
Ratio of change = 25:10 = 2.5:1
For every 1 value change by knob the Deluge value changes by 2.5x

Knob moves 40 to 42 👉 Deluge moves 25 to 30 (knob change 2 = Deluge change 2 x 2.5 = 5)
Knob moves 42 to 46 👉 Deluge moves 30 to 40 (knob change 4 = Deluge change 4 x 2.5 = 10)
Knob moves 46 to 50 👉 Deluge moves 40 to 50 (knob change 4 = Deluge change 4 x 2.5 = 10)

Of course this wouldn't be implemented in steps of 0-50 because the Deluge doesn't work at that resolution internally (I don't think?) so the full scale of vales would be used.


Although both of these examples will produce potentially unexpected behavior - example 1 would initially turn down a filter cutoff as you turn the knob up - in a live or performance situation I would still prefer this than an abrupt jump in value.

This boils down to 2 points on a line. When point A moves how should point B move in order to smoothly meet point A. The only two states are point A is moving towards point B or it's moving away from point B.

We could always do some tests in Ableton Live and adopt their approach. This will likely not only be a dependable and considered function but also one already familiar to the huge amount of Live users.

@seangoodvibes
Copy link
Collaborator Author

Perfect thanks for the explanations Dan! @weavermedia

this should be relatively simple for me to implement. I’ll be back home Sunday so I’ll start tackling it then :)

Cheers

@seangoodvibes seangoodvibes changed the title Midi Pickup Mode Midi Takeover Mode Jul 9, 2023
@seangoodvibes
Copy link
Collaborator Author

Changing this PR to draft as I'm working to incorporate the changes Dan requested above.

@seangoodvibes seangoodvibes marked this pull request as draft July 9, 2023 22:36
@m-m-adams
Copy link
Collaborator

I don't think the scaling describes above is correct - increasing the a MIDI value should always increase the deluge value. Dans suggested approach would cause the deluge value to drop while the knob is increased and that's almost certainly worse than the current behaviour.

What you want to do is scale the ranges

E.g.

Deluge value at 25
MIDI value at 10
Turn knob to 23 (+13)

Behaviour should be that the 10% (13/127) change in position brings the value 10% closer, leaving it at 27.5 (25+.1*(50-25))

With this behaviour the pot direction and parameter direction always match, and their values match at either end. Once their values match they will always stay in sync

@seangoodvibes
Copy link
Collaborator Author

seangoodvibes commented Jul 10, 2023

Thanks for your input Mark @m-m-adams :)! I’m going to double check how ableton does it one more time and I will post the results here. I’ll test a bunch of different scenarios.

keep in mind that deluge’s equivalent for the midi controller values of 0 to 127 is -64 to +64)

The actual parameter value of 0-50 is determined using a function that converts the deluge’s knob values to a parameter value.

cheers

@seangoodvibes
Copy link
Collaborator Author

seangoodvibes commented Jul 10, 2023

Ableton Value Scaling Scenarios: @m-m-adams @weavermedia

Scenario #1: Increase Midi Value to 127 (from 126) when Ableton Value is 0

Current Values:

Ableton Value = 0
Midi Value = 126

New Values:

Ableton Value = 127 (change: +127)
Midi Value = 127 (change: +1)

Formula for Ableton Value increase:

A) Midi Runway Left = Delta between Max Midi Value and Current Midi Value = 127 - 126 = 1 (amount of runway left for increasing midi knob)

B) Midi Value Increase = 1

C) % Increase in Midi Value = Midi Value Increase (B) / Midi Runway left (A) = 1/1 = 100%

D) Ableton Runway Left = Delta between max Ableton Value and Current Ableton Value = 127 - 0 = 127

E) Ableton Value Increase = % Increase in Midi Value (C) x Ableton Runway left (D) = 100% x 127 = +127 change in Ableton Value

Scenario #2: Decrease Midi Value to 64 (from 126) when Ableton Value is 0

Current Values:

Ableton Value = 0
Midi Value = 126

New Values:

Ableton Value = 0 (change: 0)
Midi Value = 64 (change: -62)

Formula for Ableton Value decrease:

A) Midi Runway Left = Delta between Current Midi Value and Min Midi Value = 126 - 0 = 126 (amount of runway left for decreasing midi knob)

B) Midi Value Decrease = -62

C) % Decrease in Midi Value = Midi Value Decrease (B) / Midi Runway left (A) = -62/126 = -49.20%

D) Ableton Runway Left = Delta between Current Ableton Value and Min Ableton Value = 0 - 0 = 0

E) Ableton Value Decrease = % Decrease in Midi Value (C) x Ableton Runway left (D) = -49.20% x 0 = 0 change in Ableton Value

Scenario #3: Increase Midi Value to 70 (from 64) when Ableton Value is 0

Current Values:

Ableton Value = 0
Midi Value = 64

New Values:

Ableton Value = 12 (change: +12)
Midi Value = 70 (change: +6)

Formula for Ableton Value increase:

A) Midi Runway Left = Delta between Max Midi Value and Current Midi Value = 127 - 64 = 63 (amount of runway left for increasing midi knob)

B) Midi Value Increase = 6

C) % Increase in Midi Value = Midi Value Increase (B) / Midi Runway left (A) = 6/63 = 9.52%

D) Ableton Runway Left = Delta between max Ableton Value and Current Ableton Value = 127 - 0 = 127

E) Ableton Value Increase = % Increase in Midi Value (C) x Ableton Runway left (D) = 9.52% x 127 = +12 change in Ableton Value

Scenario #4: Decrease Midi Value to 64 (from 70) when Ableton Value is 12

Current Values:

Ableton Value = 12
Midi Value = 70

New Values:

Ableton Value = 11 (change: -1)
Midi Value = 64 (change: -6)

Formula for Ableton Value decrease:

A) Midi Runway Left = Delta between Current Midi Value and Min Midi Value = 70 - 0 = 70 (amount of runway left for decreasing midi knob)

B) Midi Value Decrease = -6

C) % Decrease in Midi Value = Midi Value Decrease (B) / Midi Runway left (A) = -6/70 = -8.57%

D) Ableton Runway Left = Delta between Current Ableton Value and Min Ableton Value = 12 - 0 = 12

E) Ableton Value Decrease = % Decrease in Midi Value (C) x Ableton Runway left (D) = -8.57% x 12 = -1 change in Ableton Value

Scenario #5: Decrease Midi Value to 10 (from 64) when Ableton Value is 11

Current Values:

Ableton Value = 11
Midi Value = 64

New Values:

Ableton Value = 1 (change: -10)
Midi Value = 10 (change: -54)

Formula for Ableton Value decrease:

A) Midi Runway Left = Delta between Current Midi Value and Min Midi Value = 64 - 0 = 64 (amount of runway left for decreasing midi knob)

B) Midi Value Decrease = -54

C) % Decrease in Midi Value = Midi Value Decrease (B) / Midi Runway left (A) = -54/64 = -84.38%

D) Ableton Runway Left = Delta between Current Ableton Value and Min Ableton Value = 11 - 0 = 11

E) Ableton Value Decrease = % Decrease in Midi Value (C) x Ableton Runway left (D) = -84.38% x 11 = -9 change in Ableton Value

Scenario #6: Increase Midi Value to 64 (from 10) when Ableton Value is 1

Current Values:

Ableton Value = 1
Midi Value = 10

New Values:

Ableton Value = 59 (change: +58)
Midi Value = 64 (change: +54)

Formula for Ableton Value increase:

A) Midi Runway Left = Delta between Max Midi Value and Current Midi Value = 127 - 10 = 117 (amount of runway left for increasing midi knob)

B) Midi Value Increase = 54

C) % Increase in Midi Value = Midi Value Increase (B) / Midi Runway left (A) = 54/117 = 46.15%

D) Delta between max Ableton Value and Current Ableton Value = 127 - 1 = 126

E) Ableton Value Increase = % Increase in Midi Value (C) x Ableton Runway left (D) = 46.15% x 126 = +58 change in Ableton Value

@seangoodvibes
Copy link
Collaborator Author

If the Ableton implementation is not the desired "method" let me know. Maybe we can improve upon it? Or we implement Ableton's method and then add a second "value scaling" method to offer users more choice?

@weavermedia
Copy link
Contributor

weavermedia commented Jul 10, 2023

Agreed, the value scaling method used in Ableton Live is better than my initial thoughts. The only issue I have with it is if the Deluge value is close to one end of the scale and the MIDI controller is close to the other end, the movement of the MIDI control might seem to have no effect on the value until they match. That would bug me but it's the behavior known to all the Live (and likely other DAW) user out there.

@m-m-adams
Copy link
Collaborator

Awesome work @seangoodvibes! I think the ableton behaviour looks good, that description seems to match the hydrasynth as well which is the only synth I've used midi scaling with

@seangoodvibes
Copy link
Collaborator Author

seangoodvibes commented Jul 10, 2023

Documenting the different naming conventions and feature sets for Midi Takeover Mode across multiple Daw's and Device's. Goal is to align the Deluge's naming with something standard that users will recognize and also ensure that the functionality works as expected.

Ableton

Setting Name: Takeover Mode

Setting Values: None, Pick-Up, Value Scaling

When MIDI controls that send absolute values (such as faders) are used in a bank-switching setup, where they address a different destination parameter with each controller bank, you will need to decide how Live should handle the sudden jumps in values that will occur when moving a control for the first time after switching the bank. Three takeover modes are available:

None — As soon as the physical control is moved, its new value is sent immediately to its destination parameter, usually resulting in abrupt value changes.

Pick-Up — Moving the physical control has no effect until it reaches the value of its destination parameter. As soon as they are equal, the destination value tracks the control’s value 1:1. This option can provide smooth value changes, but it can be difficult to estimate exactly where the pick-up will take place.

Value Scaling — This option ensures smooth value transitions. It compares the physical control’s value to the destination parameter’s value and calculates a smooth convergence of the two as the control is moved. As soon as they are equal, the destination value tracks the control’s value 1:1.

Bitwig

Setting Name: Takeover mode

Setting Values: Immediate, Catch, Relative scaling

The global Takeover mode setting determines how individual controls and their associate software parameters interact before their values match. Options include:

Immediate, which fully applies any control message to its software parameter, moving it immediately.

Catch, which waits to move the software parameter until the control message matches or passes the current parameter value.

Relative scaling, which moves the software parameter incrementally in the same direction that the control is moving (for example, turning a knob up increases the parameter value, while turning a knob down decreases the value). This creates a relative motion based on your control gestures that will gradually meet the parameter value.

Korg Minilogue

Setting Name: Knob Mode

Setting Values: Jump, Catch, Scale

The front panel knobs can operate in one of three modes:

Jump: When you turn the knob, the parameter value will jump to the value indicated by the knob. Since this makes it easy to hear the results while editing, we recommend that you use this setting.

Catch: Turning the knob will not change the parameter value until the knob position matches the stored value. We recommend that you use this setting when you don’t want the sound to change abruptly, such as while performing.

Scale: When you turn the knob, the parameter value will increase or decrease in a relative manner in the direction that it is turned. When you turn the knob and it reaches the full extent of its motion, it will operate proportionate to the maximum or minimum value of the parameter. Once the knob position matches the parameter value, the knob position and parameter value will subsequently be linked

Elektron Analog Heat

Setting Name: Knob Mode

Setting Values: Jump, Catch

Sets how the knobs on the panel affect the parameters. When you load a preset, the knobs positions typically don’t match their parameter values.

JUMP immediately sets the value to the current knob position.

In CATCH mode, turning the knob do not change the parameter value until the knob position matches the presets stored value

Novation Summit

Setting Name: Pickup

Setting Values: Off, On

The setting of Pickup allows the current physical position of Summit’s rotary controls to be taken into account.

When Pickup is Off, adjusting any of Summit’s rotary controls will produce parameter change and a potentially immediately audible effect (a small difference between the parameter value corresponding to the control’s physical position and the value
currently in force for the Patch may result in the effect being inaudible).

When set to On, the control needs to be moved to the physical position corresponding to the value of the parameter saved for the currently loaded Patch, and will only alter the parameter value once that position is reached.

For parameters with a range of 0 to 255, this means the 12 o’clock position will correspond to a value of 127; for parameters with a range of -64 to +63, the 12 o’clock position will correspond to a value of zero.

Hydrasynth

Setting Name: Knob Mode

Setting Values: Absolute, Pickup, Scale

How Variable knobs edit values when
moved

Behringer BCR-2000

Setting Name: Controller Mode

Setting Values: Move, Pick-up

Sequential Prophet 10

Setting Name: Pot Mode

Setting Values: Relative, Passthru, Jump

Pot Mode: rEL, PAS, JUP (Relative, Passthru, Jump)—There are three pot (potentiometer) modes to determine how the synth reacts when the programmable parameters are edited. (Master volume is not programmable, so these modes don’t apply.)

In Relative mode, changes are relative to the stored setting. In Relative mode, the full value range is not available until either the minimum or maximum value and the respective lower or upper limit of the pot’s travel is reached.

For example, the resonance parameter has an internal value range of 0 to 127. Let’s say the physical position of the resonance pot is the equivalent to an internal value of 100. If you switch to a program that has a stored Resonance value of 63 and turn the pot all the way up, it will only go to 90. To get to the maximum value of 127, you first have to turn down until the value is at the other extreme and the pot is at the limit of its travel (in this case, 0 and fully counter-clockwise, respectively).

In Passthru mode, turning the pot has no effect until after the edited value equals the preset value (that is, until the edited value “passes through” the stored value).

Jump mode uses an absolute value based upon the position of the pot when edited: turn a pot and the value jumps immediately from the stored value to the edited value.

Eventide

Setting Name: Catch Up Knob Function

Setting Values: OFF, ON

When a Preset is loaded or when toggling between Parameters using , Knob positions will not align with their current Parameter values. As a result, turning a knob will likely cause an abrupt change in the sound.

With Catch Up ON, the sound does not change until the Knob is moved to the position corresponding to the current value. The LED Ladder indicates whether the knob must be turned CCW (top LED blinks) or CW (bottom LED blinks). The LED flashes more rapidly as the knob approaches the value set by the Preset. All five LEDs blink once when the knob matches the stored Parameter value.

@litui litui added the enhancement New feature or request label Jul 12, 2023
Updated the code to:
- Move Midi Takeover Mode settings from Community Menu to Midi Menu
- Add Value Scaling mode
- Save Midi Takeover Settings to Midi XML file
- Load Midi Takeover Settings from Midi XML file
Replaced file with latest version from community
@seangoodvibes seangoodvibes marked this pull request as ready for review July 12, 2023 22:24
@seangoodvibes
Copy link
Collaborator Author

seangoodvibes commented Jul 12, 2023

Hi :) I've updated the description for this commit above. It's ready to be tested and merged I think! @weavermedia @m-m-adams @litui @trappar

Copy link
Collaborator

@m-m-adams m-m-adams left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good and I appreciate the clear commenting, left a style suggestion and I think the big description should be moved to community feature

Note - untested in practice since I have no MIDI knobs this week

Per m-m-adams feedback, I have made the following changes:

1) moved takeover mode description to community features.md

2) replaced * 1000000 multiplication with << 20

3) replaced / 1000000 division with >> 20
@jamiefaye
Copy link
Collaborator

Please fix format issues and I will merge this one in.

@jamiefaye
Copy link
Collaborator

jamiefaye commented Jul 13, 2023 via email

@jamiefaye
Copy link
Collaborator

jamiefaye commented Jul 13, 2023 via email

Corrected formatting issues identified by clang-format style check
@jamiefaye
Copy link
Collaborator

jamiefaye commented Jul 14, 2023

reformatted.txt
Tests still failing. See above.
https://github.com/SynthstromAudible/DelugeFirmware/actions/runs/5549625586/jobs/10133928478?pr=170

Apologies for all the trouble here. Its possible some of our test scripting is wrong.

@seangoodvibes
Copy link
Collaborator Author

reformatted.txt Tests still failing. See above. https://github.com/SynthstromAudible/DelugeFirmware/actions/runs/5549625586/jobs/10133928478?pr=170

Apologies for all the trouble here. Its possible some of our test scripting is wrong.

No worries, let's try again!

Ok now I think I've got it! Let's try this :)! I ran the clang format script this time.
@seangoodvibes
Copy link
Collaborator Author

@jamiefaye I think we're good to merge now!

@jamiefaye jamiefaye added this pull request to the merge queue Jul 14, 2023
Merged via the queue into SynthstromAudible:community with commit 1124f4a Jul 14, 2023
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants