Signed-off-by: falkTX <falktx@falktx.com>tags/v2.1-rc1
@@ -39,6 +39,7 @@ class CarlaHostSignals(QObject): | |||
ParameterValueChangedCallback = pyqtSignal(int, int, float) | |||
ParameterDefaultChangedCallback = pyqtSignal(int, int, float) | |||
ParameterMappedControlIndexChangedCallback = pyqtSignal(int, int, int) | |||
ParameterMappedRangeChangedCallback = pyqtSignal(int, int, float, float) | |||
ParameterMidiChannelChangedCallback = pyqtSignal(int, int, int) | |||
ProgramChangedCallback = pyqtSignal(int, int) | |||
MidiProgramChangedCallback = pyqtSignal(int, int) | |||
@@ -2751,6 +2751,9 @@ def engineCallback(host, action, pluginId, value1, value2, value3, valuef, value | |||
host.ParameterDefaultChangedCallback.emit(pluginId, value1, valuef) | |||
elif action == ENGINE_CALLBACK_PARAMETER_MAPPED_CONTROL_INDEX_CHANGED: | |||
host.ParameterMappedControlIndexChangedCallback.emit(pluginId, value1, value2) | |||
elif action == ENGINE_CALLBACK_PARAMETER_MAPPED_RANGE_CHANGED: | |||
minimum, maximum = (float(v) for v in valueStr.split(":", 2)) | |||
host.ParameterMappedRangeChangedCallback.emit(pluginId, value1, minimum, maximum) | |||
elif action == ENGINE_CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED: | |||
host.ParameterMidiChannelChangedCallback.emit(pluginId, value1, value2) | |||
elif action == ENGINE_CALLBACK_PROGRAM_CHANGED: | |||
@@ -119,58 +119,44 @@ del envPATH | |||
# Static MIDI CC list | |||
MIDI_CC_LIST = ( | |||
"0x01 Modulation", | |||
"0x02 Breath", | |||
"0x03 (Undefined)", | |||
"0x04 Foot", | |||
"0x05 Portamento", | |||
"0x07 Volume", | |||
"0x08 Balance", | |||
"0x09 (Undefined)", | |||
"0x0A Pan", | |||
"0x0B Expression", | |||
"0x0C FX Control 1", | |||
"0x0D FX Control 2", | |||
"0x0E (Undefined)", | |||
"0x0F (Undefined)", | |||
"0x10 General Purpose 1", | |||
"0x11 General Purpose 2", | |||
"0x12 General Purpose 3", | |||
"0x13 General Purpose 4", | |||
"0x14 (Undefined)", | |||
"0x15 (Undefined)", | |||
"0x16 (Undefined)", | |||
"0x17 (Undefined)", | |||
"0x18 (Undefined)", | |||
"0x19 (Undefined)", | |||
"0x1A (Undefined)", | |||
"0x1B (Undefined)", | |||
"0x1C (Undefined)", | |||
"0x1D (Undefined)", | |||
"0x1E (Undefined)", | |||
"0x1F (Undefined)", | |||
"0x46 Control 1 [Variation]", | |||
"0x47 Control 2 [Timbre]", | |||
"0x48 Control 3 [Release]", | |||
"0x49 Control 4 [Attack]", | |||
"0x4A Control 5 [Brightness]", | |||
"0x4B Control 6 [Decay]", | |||
"0x4C Control 7 [Vib Rate]", | |||
"0x4D Control 8 [Vib Depth]", | |||
"0x4E Control 9 [Vib Delay]", | |||
"0x4F Control 10 [Undefined]", | |||
"0x50 General Purpose 5", | |||
"0x51 General Purpose 6", | |||
"0x52 General Purpose 7", | |||
"0x53 General Purpose 8", | |||
"0x54 Portamento Control", | |||
"0x5B FX 1 Depth [Reverb]", | |||
"0x5C FX 2 Depth [Tremolo]", | |||
"0x5D FX 3 Depth [Chorus]", | |||
"0x5E FX 4 Depth [Detune]", | |||
"0x5F FX 5 Depth [Phaser]" | |||
"01 [0x01] Modulation", | |||
"02 [0x02] Breath", | |||
"04 [0x04] Foot", | |||
"05 [0x05] Portamento", | |||
"07 [0x07] Volume", | |||
"02 [0x08] Balance", | |||
"10 [0x0A] Pan", | |||
"11 [0x0B] Expression", | |||
"12 [0x0C] FX Control 1", | |||
"13 [0x0D] FX Control 2", | |||
"16 [0x10] General Purpose 1", | |||
"17 [0x11] General Purpose 2", | |||
"18 [0x12] General Purpose 3", | |||
"19 [0x13] General Purpose 4", | |||
"70 [0x46] Control 1 [Variation]", | |||
"71 [0x47] Control 2 [Timbre]", | |||
"72 [0x48] Control 3 [Release]", | |||
"73 [0x49] Control 4 [Attack]", | |||
"74 [0x4A] Control 5 [Brightness]", | |||
"75 [0x4B] Control 6 [Decay]", | |||
"76 [0x4C] Control 7 [Vib Rate]", | |||
"77 [0x4D] Control 8 [Vib Depth]", | |||
"78 [0x4E] Control 9 [Vib Delay]", | |||
"79 [0x4F] Control 10 [Undefined]", | |||
"80 [0x50] General Purpose 5", | |||
"81 [0x51] General Purpose 6", | |||
"82 [0x52] General Purpose 7", | |||
"83 [0x53] General Purpose 8", | |||
"84 [0x54] Portamento Control", | |||
"91 [0x5B] FX 1 Depth [Reverb]", | |||
"92 [0x5C] FX 2 Depth [Tremolo]", | |||
"93 [0x5D] FX 3 Depth [Chorus]", | |||
"94 [0x5E] FX 4 Depth [Detune]", | |||
"95 [0x5F] FX 5 Depth [Phaser]" | |||
) | |||
MAX_MIDI_CC_LIST_ITEM = 95 | |||
# ------------------------------------------------------------------------------------------------------------ | |||
# PatchCanvas defines | |||
@@ -287,6 +287,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||
host.ParameterValueChangedCallback.connect(self.slot_handleParameterValueChangedCallback) | |||
host.ParameterDefaultChangedCallback.connect(self.slot_handleParameterDefaultChangedCallback) | |||
host.ParameterMappedControlIndexChangedCallback.connect(self.slot_handleParameterMappedControlIndexChangedCallback) | |||
host.ParameterMappedRangeChangedCallback.connect(self.slot_handleParameterMappedRangeChangedCallback) | |||
host.ParameterMidiChannelChangedCallback.connect(self.slot_handleParameterMidiChannelChangedCallback) | |||
host.ProgramChangedCallback.connect(self.slot_handleProgramChangedCallback) | |||
host.MidiProgramChangedCallback.connect(self.slot_handleMidiProgramChangedCallback) | |||
@@ -326,6 +327,11 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||
if self.fPluginId == pluginId: | |||
self.setParameterMappedControlIndex(index, ctrl) | |||
@pyqtSlot(int, int, float, float) | |||
def slot_handleParameterMappedRangeChangedCallback(self, pluginId, index, minimum, maximum): | |||
if self.fPluginId == pluginId: | |||
self.setParameterMappedRange(index, minimum, maximum) | |||
@pyqtSlot(int, int, int) | |||
def slot_handleParameterMidiChannelChangedCallback(self, pluginId, index, channel): | |||
if self.fPluginId == pluginId: | |||
@@ -741,6 +747,9 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||
def setParameterMappedControlIndex(self, parameterId, control): | |||
self.fEditDialog.setParameterMappedControlIndex(parameterId, control) | |||
def setParameterMappedRange(self, parameterId, minimum, maximum): | |||
self.fEditDialog.setParameterMappedRange(parameterId, minimum, maximum) | |||
def setParameterMidiChannel(self, parameterId, channel): | |||
self.fEditDialog.setParameterMidiChannel(parameterId, channel) | |||
@@ -234,11 +234,13 @@ class PluginParameter(QWidget): | |||
# ------------------------------------------------------------- | |||
# Internal stuff | |||
self.fMappedCtrl = CONTROL_VALUE_NONE | |||
self.fMidiChannel = 1 | |||
self.fParameterId = pInfo['index'] | |||
self.fPluginId = pluginId | |||
self.fTabIndex = tabIndex | |||
self.fMappedCtrl = pInfo['mappedControlIndex'] | |||
self.fMappedMinimum = pInfo['mappedMinimum'] | |||
self.fMappedMaximum = pInfo['mappedMaximum'] | |||
self.fMidiChannel = pInfo['midiChannel'] | |||
self.fParameterId = pInfo['index'] | |||
self.fPluginId = pluginId | |||
self.fTabIndex = tabIndex | |||
# ------------------------------------------------------------- | |||
# Set-up GUI | |||
@@ -322,6 +324,10 @@ class PluginParameter(QWidget): | |||
def setMappedControlIndex(self, control): | |||
self.fMappedCtrl = control | |||
def setMappedRange(self, minimum, maximum): | |||
self.fMappedMinimum = minimum | |||
self.fMappedMaximum = maximum | |||
def setMidiChannel(self, channel): | |||
self.fMidiChannel = channel | |||
@@ -339,6 +345,9 @@ class PluginParameter(QWidget): | |||
else: | |||
title = self.tr("Mapped to CC %i, channel %i" % (self.fMappedCtrl, self.fMidiChannel)) | |||
if self.fMappedCtrl != CONTROL_VALUE_NONE: | |||
title += " (min %g, max %g)" % (self.fMappedMinimum, self.fMappedMaximum) | |||
actTitle = menu.addAction(title) | |||
actTitle.setEnabled(False) | |||
@@ -373,12 +382,12 @@ class PluginParameter(QWidget): | |||
action = menuMIDI.addAction(cc) | |||
actCCs.append(action) | |||
if self.fMappedCtrl >= 0: | |||
ccx = int(cc.split(" ", 1)[0], 16) | |||
if self.fMappedCtrl >= 0 and self.fMappedCtrl <= MAX_MIDI_CC_LIST_ITEM: | |||
ccx = int(cc.split(" [", 1)[0]) | |||
if ccx > self.fMappedCtrl and not inlist: | |||
inlist = True | |||
action = menuMIDI.addAction(self.tr("0x%x (Custom)" % self.fMappedCtrl)) | |||
action = menuMIDI.addAction(self.tr("%02i [0x%x] (Custom)" % (self.fMappedCtrl, self.fMappedCtrl))) | |||
action.setCheckable(True) | |||
action.setChecked(True) | |||
actCCs.append(action) | |||
@@ -388,6 +397,12 @@ class PluginParameter(QWidget): | |||
action.setCheckable(True) | |||
action.setChecked(True) | |||
if self.fMappedCtrl > MAX_MIDI_CC_LIST_ITEM and self.fMappedCtrl <= 0x77: | |||
action = menuMIDI.addAction(self.tr("%02i [0x%x] (Custom)" % (self.fMappedCtrl, self.fMappedCtrl))) | |||
action.setCheckable(True) | |||
action.setChecked(True) | |||
actCCs.append(action) | |||
actCustomCC = menuMIDI.addAction(self.tr("Custom...")) | |||
# TODO | |||
@@ -909,6 +924,8 @@ class PluginEdit(QDialog): | |||
'stepSmall': paramRanges['stepSmall'], | |||
'stepLarge': paramRanges['stepLarge'], | |||
'mappedControlIndex': paramData['mappedControlIndex'], | |||
'mappedMinimum': paramData['mappedMinimum'], | |||
'mappedMaximum': paramData['mappedMaximum'], | |||
'midiChannel': paramData['midiChannel']+1, | |||
'comment': paramInfo['comment'], | |||
@@ -1058,6 +1075,12 @@ class PluginEdit(QDialog): | |||
paramWidget.setMappedControlIndex(control) | |||
break | |||
def setParameterMappedRange(self, parameterId, minimum, maximum): | |||
for paramType, paramId, paramWidget in self.fParameterList: | |||
if paramId == parameterId: | |||
paramWidget.setMappedRange(minimum, maximum) | |||
break | |||
def setParameterMidiChannel(self, parameterId, channel): | |||
for paramType, paramId, paramWidget in self.fParameterList: | |||
if paramId == parameterId: | |||
@@ -35,8 +35,11 @@ struct CarlaStateSave { | |||
const char* symbol; | |||
float value; | |||
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | |||
int16_t mappedControlIndex; | |||
uint8_t midiChannel; | |||
int16_t mappedControlIndex; | |||
uint8_t midiChannel; | |||
bool mappedRangeValid; | |||
float mappedMinimum; | |||
float mappedMaximum; | |||
#endif | |||
Parameter() noexcept; | |||