From 106fcaa19c81af2c5581bdc6df159fa5508484cd Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sat, 21 May 2022 12:33:36 +1000 Subject: [PATCH 01/65] Initial connection - debug mode --- icon/platformmplus/icon_platformmplus.js | 72 ++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 icon/platformmplus/icon_platformmplus.js diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js new file mode 100644 index 0000000..d06f3ab --- /dev/null +++ b/icon/platformmplus/icon_platformmplus.js @@ -0,0 +1,72 @@ +//----------------------------------------------------------------------------- +// 1. DRIVER SETUP - create driver object, midi ports and detection information +//----------------------------------------------------------------------------- + +// get the api's entry point +var midiremote_api = require('midiremote_api_v1') + +// create the device driver main object +var deviceDriver = midiremote_api.makeDeviceDriver('Icon', 'PlatformMPlus', 'Big Fat Wombat') + +// create objects representing the hardware's MIDI ports +var midiInput = deviceDriver.mPorts.makeMidiInput() +var midiOutput = deviceDriver.mPorts.makeMidiOutput() + +// define all possible namings the devices MIDI ports could have +// NOTE: Windows and MacOS handle port naming differently +deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput) + .expectInputNameEquals('PlatformMonOut') + .expectOutputNameEquals('PlatformMonIn') + +deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput) + .expectInputNameEquals('PlatformMonOut') + .expectOutputNameEquals('PlatformMonIn') + + +//----------------------------------------------------------------------------- +// 2. SURFACE LAYOUT - create control elements and midi bindings +//----------------------------------------------------------------------------- + +// create control element representing your hardware's surface +var knob1 = deviceDriver.mSurface.makeKnob(0, 0, 1, 1.5) +var knob2 = deviceDriver.mSurface.makeKnob(1, 0, 1, 1.5) +var knob3 = deviceDriver.mSurface.makeKnob(2, 0, 1, 1.5) +var knob4 = deviceDriver.mSurface.makeKnob(3, 0, 1, 1.5) + +// bind midi ports to surface elements +knob1.mSurfaceValue.mMidiBinding + .setInputPort(midiInput) + .setOutputPort(midiOutput) + .bindToControlChange (0, 16).setTypeRelativeSignedBit() + +knob2.mSurfaceValue.mMidiBinding + .setInputPort(midiInput) + .setOutputPort(midiOutput) + .bindToControlChange (0, 17).setTypeRelativeSignedBit() + +knob3.mSurfaceValue.mMidiBinding + .setInputPort(midiInput) + .setOutputPort(midiOutput) + .bindToControlChange (0, 18).setTypeRelativeSignedBit() + +knob4.mSurfaceValue.mMidiBinding + .setInputPort(midiInput) + .setOutputPort(midiOutput) + .bindToControlChange (0, 19).setTypeRelativeSignedBit() + +//----------------------------------------------------------------------------- +// 3. HOST MAPPING - create mapping pages and host bindings +//----------------------------------------------------------------------------- + +// create at least one mapping page +var page = deviceDriver.mMapping.makePage('Example Knobs Page') + +// create host accessing objects +var hostSelectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel + + +// bind surface elements to host accessing object values +page.makeValueBinding(knob1.mSurfaceValue, hostSelectedTrackChannel.mValue.mVolume) +page.makeValueBinding(knob2.mSurfaceValue, hostSelectedTrackChannel.mSends.getByIndex(0).mLevel) +page.makeValueBinding(knob3.mSurfaceValue, hostSelectedTrackChannel.mSends.getByIndex(1).mLevel) +page.makeValueBinding(knob4.mSurfaceValue, hostSelectedTrackChannel.mSends.getByIndex(2).mLevel) From 3a7cf8fa4ca20f26ff33eec17c46c745efa56bd7 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sat, 21 May 2022 13:55:12 +1000 Subject: [PATCH 02/65] Basic layout start --- icon/platformmplus/icon_platformmplus.js | 148 ++++++++++++++++------- 1 file changed, 104 insertions(+), 44 deletions(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index d06f3ab..e169ec0 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -15,58 +15,118 @@ var midiOutput = deviceDriver.mPorts.makeMidiOutput() // define all possible namings the devices MIDI ports could have // NOTE: Windows and MacOS handle port naming differently deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput) - .expectInputNameEquals('PlatformMonOut') - .expectOutputNameEquals('PlatformMonIn') - -deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput) - .expectInputNameEquals('PlatformMonOut') - .expectOutputNameEquals('PlatformMonIn') + .expectInputNameEquals('PlatformMonOut') // Platform M+ v2.15 + .expectOutputNameEquals('PlatformMonIn') // Platform M+ v2.15 +var surface = deviceDriver.mSurface //----------------------------------------------------------------------------- // 2. SURFACE LAYOUT - create control elements and midi bindings //----------------------------------------------------------------------------- -// create control element representing your hardware's surface -var knob1 = deviceDriver.mSurface.makeKnob(0, 0, 1, 1.5) -var knob2 = deviceDriver.mSurface.makeKnob(1, 0, 1, 1.5) -var knob3 = deviceDriver.mSurface.makeKnob(2, 0, 1, 1.5) -var knob4 = deviceDriver.mSurface.makeKnob(3, 0, 1, 1.5) - -// bind midi ports to surface elements -knob1.mSurfaceValue.mMidiBinding - .setInputPort(midiInput) - .setOutputPort(midiOutput) - .bindToControlChange (0, 16).setTypeRelativeSignedBit() - -knob2.mSurfaceValue.mMidiBinding - .setInputPort(midiInput) - .setOutputPort(midiOutput) - .bindToControlChange (0, 17).setTypeRelativeSignedBit() - -knob3.mSurfaceValue.mMidiBinding - .setInputPort(midiInput) - .setOutputPort(midiOutput) - .bindToControlChange (0, 18).setTypeRelativeSignedBit() - -knob4.mSurfaceValue.mMidiBinding - .setInputPort(midiInput) - .setOutputPort(midiOutput) - .bindToControlChange (0, 19).setTypeRelativeSignedBit() +function makeKnobStrip(knobIndex, x, y) { + var knobStrip = {} -//----------------------------------------------------------------------------- -// 3. HOST MAPPING - create mapping pages and host bindings -//----------------------------------------------------------------------------- + knobStrip.knob = surface.makeKnob(x + 2 * knobIndex, y, 1, 1) + knobStrip.knob.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToControlChange(0, 16 + knobIndex).setTypeRelativeSignedBit() + + return knobStrip +} + +function makeFaderStrip(channelIndex, x, y) { + var faderStrip = {} + + // Fader + Fader Touch + faderStrip.fader = surface.makeFader(x + 2 * channelIndex, y, 1, 8).setTypeVertical() + faderStrip.fader.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToPitchBend(channelIndex) + + faderStrip.touched = surface.makeButton(x + 1+ 2 * channelIndex, y, 1, 1) + faderStrip.touched.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, 104 + channelIndex) + + // Channel Buittons + faderStrip.sel_button = surface.makeButton(x + 1 + 2 * channelIndex, y + 4, 1, 1) + faderStrip.sel_button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, 24 + channelIndex) + + faderStrip.mute_button = surface.makeButton(x + 1 + 2 * channelIndex, y + 5, 1, 1) + faderStrip.mute_button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, 16 + channelIndex) + + faderStrip.solo_button = surface.makeButton(x + 1 + 2 * channelIndex, y + 6, 1, 1) + faderStrip.solo_button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, 8 + channelIndex) + + faderStrip.rec_button = surface.makeButton(x + 1 + 2 * channelIndex, y + 7, 1, 1) + faderStrip.rec_button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, 0 + channelIndex) + + return faderStrip +} + +function makeTransport(x, y) { + var transport = {} + + var w = 1 + var h = 1 + + function bindMidiNote(button, chn, num) { + button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(chn, num) + } -// create at least one mapping page -var page = deviceDriver.mMapping.makePage('Example Knobs Page') + transport.prevChn = surface.makeButton(x, y, w, h) + bindMidiNote(transport.prevChn, 0, 48) + transport.nextChn = surface.makeButton(x+1, y, w, h) + bindMidiNote(transport.nextChn, 0, 49) -// create host accessing objects -var hostSelectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel + transport.prevBnk = surface.makeButton(x, y+1, w, h) + bindMidiNote(transport.prevBnk, 0, 46) + transport.nextBnk = surface.makeButton(x+1, y+1, w, h) + bindMidiNote(transport.nextBnk, 0, 47) + transport.btnRewind = surface.makeButton(x, y+2, w, h) + bindMidiNote(transport.btnRewind, 0, 91) + transport.btnForward = surface.makeButton(x+1, y+2, w, h) + bindMidiNote(transport.btnForward, 0, 92) -// bind surface elements to host accessing object values -page.makeValueBinding(knob1.mSurfaceValue, hostSelectedTrackChannel.mValue.mVolume) -page.makeValueBinding(knob2.mSurfaceValue, hostSelectedTrackChannel.mSends.getByIndex(0).mLevel) -page.makeValueBinding(knob3.mSurfaceValue, hostSelectedTrackChannel.mSends.getByIndex(1).mLevel) -page.makeValueBinding(knob4.mSurfaceValue, hostSelectedTrackChannel.mSends.getByIndex(2).mLevel) + transport.btnStart = surface.makeButton(x, y+3, w, h) + bindMidiNote(transport.btnStart, 0, 94) + transport.btnStop = surface.makeButton(x+1, y+3, w, h) + bindMidiNote(transport.btnStop, 0, 93) + + transport.btnRecord = surface.makeButton(x, y+4, w, h) + bindMidiNote(transport.btnRecord, 0, 95) + transport.btnCycle = surface.makeButton(x+1, y+4, w, h) + bindMidiNote(transport.btnCycle, 0, 86) + + //jog wheel + transport.jog_wheel = surface.makeKnob(x, y + 6, 2, 2) + transport.jog_wheel.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToControlChange(0, 60).setTypeRelativeSignedBit() + transport.btnJog = surface.makeButton(x,y+8,2,1) + bindMidiNote(transport.btnJog, 0, 101) + + return transport +} + +function makeSurfaceElements() { + var surfaceElements = {} + + surfaceElements.numStrips = 8 + + surfaceElements.knobStrips = {} + surfaceElements.faderStrips = {} + + var xKnobStrip = 0 + var yKnobStrip = 0 + + for(var i = 0; i < surfaceElements.numStrips; ++i) { + surfaceElements.knobStrips[i] = makeKnobStrip(i, xKnobStrip, yKnobStrip) + surfaceElements.faderStrips[i] = makeFaderStrip(i, xKnobStrip, yKnobStrip+2) + } + + surfaceElements.transport = makeTransport(20, 3) + + return surfaceElements +} + +var surfaceElements = makeSurfaceElements() + + +//----------------------------------------------------------------------------- +// 3. HOST MAPPING - create mapping pages and host bindings +//----------------------------------------------------------------------------- From 5078af19200d1bf430a768ebc51e5ee933dcaf11 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sat, 21 May 2022 14:44:11 +1000 Subject: [PATCH 03/65] Seemingly complete input surface --- icon/platformmplus/icon_platformmplus.js | 40 ++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index e169ec0..d136e6c 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -6,7 +6,7 @@ var midiremote_api = require('midiremote_api_v1') // create the device driver main object -var deviceDriver = midiremote_api.makeDeviceDriver('Icon', 'PlatformMPlus', 'Big Fat Wombat') +var deviceDriver = midiremote_api.makeDeviceDriver('Icon', 'Platform Mplus', 'Big Fat Wombat') // create objects representing the hardware's MIDI ports var midiInput = deviceDriver.mPorts.makeMidiInput() @@ -29,6 +29,8 @@ function makeKnobStrip(knobIndex, x, y) { knobStrip.knob = surface.makeKnob(x + 2 * knobIndex, y, 1, 1) knobStrip.knob.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToControlChange(0, 16 + knobIndex).setTypeRelativeSignedBit() + knobStrip.touched = surface.makeButton(x + 2 * knobIndex, y+1, 1, 1) + knobStrip.touched.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, 32 + knobIndex) return knobStrip } @@ -94,12 +96,43 @@ function makeTransport(x, y) { transport.btnCycle = surface.makeButton(x+1, y+4, w, h) bindMidiNote(transport.btnCycle, 0, 86) + // ! The Note on/off events for the special functioans are timestamped at the same time + // ! cubase midi remote doesn't show anything on screen though a note is sent + + // Flip - Simultaneous press of Pre Chn+Pre Bank + transport.btnFlip = surface.makeButton(x+3, y+4, 1, 1) + bindMidiNote(transport.btnFlip, 0, 50) + + // Pressing the Zoom keys simultaneously will toggle on and off a note event. If on + // either zoom button will send a Note 100 when zoom is activated or deactivated by either button + // If zoom is active and you simply press then other button the event will not be sent + // + transport.btnZoomOnOff= surface.makeButton(x+4, y+4, 1, 1) + bindMidiNote(transport.btnZoomOnOff, 0, 100) + + + // The Jog wheel will change CC/Note based on which of thte Zoom buttons have been activated + // None - CC 60 + // Vertical - Note Clockwise 97, CounterClockwise 96 + // Horizontal - Note Clockwise 99, CounterClockwise 98 //jog wheel transport.jog_wheel = surface.makeKnob(x, y + 6, 2, 2) transport.jog_wheel.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToControlChange(0, 60).setTypeRelativeSignedBit() transport.btnJog = surface.makeButton(x,y+8,2,1) bindMidiNote(transport.btnJog, 0, 101) + //Zoom Vertical + transport.zoomVertOut = surface.makeButton(x+3, y + 6, 1, 1) + bindMidiNote(transport.zoomVertOut, 0, 96) + transport.zoomVertIn = surface.makeButton(x+4, y + 6, 1, 1) + bindMidiNote(transport.zoomVertIn, 0, 97) + + //Zoom Horizontal + transport.zoomHorizOut = surface.makeButton(x+3, y + 7, 1, 1) + bindMidiNote(transport.zoomHorizOut, 0, 98) + transport.zoomHorizIn = surface.makeButton(x+4, y + 7, 1, 1) + bindMidiNote(transport.zoomHorizIn, 0, 99) + return transport } @@ -116,10 +149,11 @@ function makeSurfaceElements() { for(var i = 0; i < surfaceElements.numStrips; ++i) { surfaceElements.knobStrips[i] = makeKnobStrip(i, xKnobStrip, yKnobStrip) - surfaceElements.faderStrips[i] = makeFaderStrip(i, xKnobStrip, yKnobStrip+2) + surfaceElements.faderStrips[i] = makeFaderStrip(i, xKnobStrip, yKnobStrip+3) } - surfaceElements.transport = makeTransport(20, 3) + surfaceElements.faderMaster = makeFaderStrip(surfaceElements.numStrips, xKnobStrip+1, yKnobStrip+3) + surfaceElements.transport = makeTransport(xKnobStrip+20, yKnobStrip+3) return surfaceElements } From 1901512297416e3535b10e0cde417b45bddd4836 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 22 May 2022 09:47:36 +1000 Subject: [PATCH 04/65] Add zoom mapping --- icon/platformmplus/icon_platformmplus.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index d136e6c..7aa1fb8 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -122,15 +122,15 @@ function makeTransport(x, y) { bindMidiNote(transport.btnJog, 0, 101) //Zoom Vertical - transport.zoomVertOut = surface.makeButton(x+3, y + 6, 1, 1) + transport.zoomVertOut = surface.makeButton(x+3, y + 6, 1, 1).setShapeCircle() bindMidiNote(transport.zoomVertOut, 0, 96) - transport.zoomVertIn = surface.makeButton(x+4, y + 6, 1, 1) + transport.zoomVertIn = surface.makeButton(x+4, y + 6, 1, 1).setShapeCircle() bindMidiNote(transport.zoomVertIn, 0, 97) //Zoom Horizontal - transport.zoomHorizOut = surface.makeButton(x+3, y + 7, 1, 1) + transport.zoomHorizOut = surface.makeButton(x+3, y + 7, 1, 1).setShapeCircle() bindMidiNote(transport.zoomHorizOut, 0, 98) - transport.zoomHorizIn = surface.makeButton(x+4, y + 7, 1, 1) + transport.zoomHorizIn = surface.makeButton(x+4, y + 7, 1, 1).setShapeCircle() bindMidiNote(transport.zoomHorizIn, 0, 99) return transport @@ -164,3 +164,12 @@ var surfaceElements = makeSurfaceElements() //----------------------------------------------------------------------------- // 3. HOST MAPPING - create mapping pages and host bindings //----------------------------------------------------------------------------- + +var page = deviceDriver.mMapping.makePage('Default') + +page.makeCommandBinding(surfaceElements.transport.zoomVertIn.mSurfaceValue, 'Zoom', 'Zoom In Vertically') +page.makeCommandBinding(surfaceElements.transport.zoomVertOut.mSurfaceValue, 'Zoom', 'Zoom Out Vertically') + +page.makeCommandBinding(surfaceElements.transport.zoomHorizIn.mSurfaceValue, 'Zoom', 'Zoom In') +page.makeCommandBinding(surfaceElements.transport.zoomHorizOut.mSurfaceValue, 'Zoom', 'Zoom Out') + From 2916d8ae8eac148dbab39c7f40308e967c006f9e Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 22 May 2022 11:51:41 +1000 Subject: [PATCH 05/65] Now with some jog and zoom functions mapped --- icon/platformmplus/icon_platformmplus.js | 49 +++++++++++++++++++++--- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 7aa1fb8..9963f98 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -110,16 +110,19 @@ function makeTransport(x, y) { transport.btnZoomOnOff= surface.makeButton(x+4, y+4, 1, 1) bindMidiNote(transport.btnZoomOnOff, 0, 100) - // The Jog wheel will change CC/Note based on which of thte Zoom buttons have been activated // None - CC 60 // Vertical - Note Clockwise 97, CounterClockwise 96 // Horizontal - Note Clockwise 99, CounterClockwise 98 - //jog wheel - transport.jog_wheel = surface.makeKnob(x, y + 6, 2, 2) - transport.jog_wheel.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToControlChange(0, 60).setTypeRelativeSignedBit() - transport.btnJog = surface.makeButton(x,y+8,2,1) - bindMidiNote(transport.btnJog, 0, 101) + // The Jog wheel is an endless encoder but the surface Push Encoder is control value 0-127 + // In this case it pays to use the Absolute binding type as the Platform M+ produces a rate based + // CC value - turn clockwise slowly -> 1, turn it rapidly -> 7 (counter clockwise values are offset by 50, turn CCW slowly -> 51) + // In the Jog (or more correctly Nudge Cursor) mapping we use this to "tap the key severel times" - giving the impact of fine grain control if turned slowly + // or large nudges if turned quickly + + transport.jog_wheel = surface.makePushEncoder(x, y + 6, 2, 2) + transport.jog_wheel.mEncoderValue.mMidiBinding.setInputPort(midiInput).bindToControlChange(0, 60).setTypeAbsolute() + transport.jog_wheel.mPushValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, 101) //Zoom Vertical transport.zoomVertOut = surface.makeButton(x+3, y + 6, 1, 1).setShapeCircle() @@ -173,3 +176,37 @@ page.makeCommandBinding(surfaceElements.transport.zoomVertOut.mSurfaceValue, 'Zo page.makeCommandBinding(surfaceElements.transport.zoomHorizIn.mSurfaceValue, 'Zoom', 'Zoom In') page.makeCommandBinding(surfaceElements.transport.zoomHorizOut.mSurfaceValue, 'Zoom', 'Zoom Out') +// Jog Knob +var jogLeftVariable = deviceDriver.mSurface.makeCustomValueVariable('jogLeft') +var jogRightVariable = deviceDriver.mSurface.makeCustomValueVariable('jogRight') + +page.makeCommandBinding(jogLeftVariable, 'Transport', 'Nudge Cursor Left') +page.makeCommandBinding(jogRightVariable, 'Transport', 'Nudge Cursor Right') + +createCommandKnob(surfaceElements.transport.jog_wheel, jogRightVariable, jogLeftVariable); + + +function repeatCommand(activeDevice, command, repeats) { + for(var i = 0; i < repeats; i++) { + command.setProcessValue(activeDevice, 1) + } +} + +/** + * @param {MR_PushEncoder} pushEncoder + * @param {MR_SurfaceCustomValueVariable} commandIncrease + * @param {MR_SurfaceCustomValueVariable} commandDecrease + */ +function createCommandKnob(pushEncoder, commandIncrease, commandDecrease) { + // console.log('from script: createCommandKnob') + pushEncoder.mEncoderValue.mOnProcessValueChange = function(activeDevice, value) { + console.log('value changed: ' + value) + if(value < 0.5 ) { + var jump_rate = Math.floor(value*127) + repeatCommand(activeDevice, commandIncrease, jump_rate) + } else if (value > 0.5) { + var jump_rate = Math.floor((value-0.5)*127) + repeatCommand(activeDevice, commandDecrease, jump_rate) + } + } + } \ No newline at end of file From 416ae0136022f7f9f32f42e22d224130b7f4e7bc Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 22 May 2022 11:57:58 +1000 Subject: [PATCH 06/65] Add comment on the weird knob behaviour side effect --- icon/platformmplus/icon_platformmplus.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 9963f98..1e7724e 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -118,7 +118,9 @@ function makeTransport(x, y) { // In this case it pays to use the Absolute binding type as the Platform M+ produces a rate based // CC value - turn clockwise slowly -> 1, turn it rapidly -> 7 (counter clockwise values are offset by 50, turn CCW slowly -> 51) // In the Jog (or more correctly Nudge Cursor) mapping we use this to "tap the key severel times" - giving the impact of fine grain control if turned slowly - // or large nudges if turned quickly + // or large nudges if turned quickly. + // ? One weird side effect of this is the Knob displayed in Cubase will show its "value" in a weird way. + // todo I wonder if there is a way to change that behaviour? transport.jog_wheel = surface.makePushEncoder(x, y + 6, 2, 2) transport.jog_wheel.mEncoderValue.mMidiBinding.setInputPort(midiInput).bindToControlChange(0, 60).setTypeAbsolute() From 22ba5fac6d1f9b6e07b0128f79c9819f1d04aed1 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 22 May 2022 15:56:14 +1000 Subject: [PATCH 07/65] Refactor surface elements Start button and Led now work WIP Still getting CC messages from Jog wheel (works but CC messages pass through to track?) --- icon/platformmplus/icon_elements.js | 92 +++++++++++++ icon/platformmplus/icon_platformmplus.js | 160 +++++++++++------------ 2 files changed, 168 insertions(+), 84 deletions(-) create mode 100644 icon/platformmplus/icon_elements.js diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js new file mode 100644 index 0000000..d48bd28 --- /dev/null +++ b/icon/platformmplus/icon_elements.js @@ -0,0 +1,92 @@ +/** + * @constructor + * @param {MR_DeviceSurface} surface + * @param {MR_DeviceMidiInput} midiInput + * @param {MR_DeviceMidiOutput} midiOutput + * @param {number} x - x location of the push encoder in the gui + * @param {Number} y - y location of the push encoder in the gui + * @param {Number} w - width of the push encoder. + * @param {Number} h - height of the push encoder. + * @param {Number} instance - instance of the push encoder. + */ +function channelControl(surface, midiInput, midiOutput, x, y, instance) { + // Position on GUI + this.surface = surface; + this.midiInput = midiInput; + this.midiOutput = midiOutput; + this.x = x + 2 * instance; + this.y = y; + this.instance = instance; // Channel number, 1-8 + + this.ident = function () { + return ("Class channelControl"); + } + + this.vPotValue = 0; + this.vPotPushValue = 0; + this.vFaderValue = 0; + this.vFaderTouched = 0; + this.vSelLedOn = 0; + this.vMuteLedOn = 0; + this.vSoloLedOn = 0; + this.vRecLedOn = 0; + + // Pot encoder + this.pushEncoder = this.surface.makePushEncoder(this.x, y, 2, 2) + + this.pushEncoder.mEncoderValue.mMidiBinding + .setInputPort(midiInput) + .bindToControlChange(0, 16 + this.instance) + .setTypeRelativeSignedBit(); + + this.pushEncoder.mPushValue.mMidiBinding + .setInputPort(midiInput) + .bindToNote(0, 32 + this.instance); + + // Fader + Fader Touch + var fader_x = this.x + var fader_y = y + 3 + this.fader = surface.makeFader(fader_x, fader_y, 1, 8).setTypeVertical() + this.fader.mSurfaceValue.mMidiBinding + .setInputPort(midiInput) + .bindToPitchBend(this.instance) + + this.fader_touch = surface.makeButton(fader_x + 1, fader_y, 1, 1) + this.fader_touch.mSurfaceValue.mMidiBinding + .setInputPort(midiInput) + .bindToNote(0, 104 + this.instance) + + // Channel Buittons + this.sel_button = surface.makeButton(fader_x + 1, fader_y + 4, 1, 1) + this.sel_button.mSurfaceValue.mMidiBinding + .setInputPort(midiInput) + .setOutputPort(midiOutput) + .bindToNote(0, 24 + this.instance) + + this.mute_button = surface.makeButton(fader_x + 1, fader_y + 5, 1, 1) + this.mute_button.mSurfaceValue.mMidiBinding + .setInputPort(midiInput) + .bindToNote(0, 16 + this.instance) + + this.solo_button = surface.makeButton(fader_x + 1, fader_y + 6, 1, 1) + this.solo_button.mSurfaceValue.mMidiBinding + .setInputPort(midiInput) + .bindToNote(0, 8 + this.instance) + + this.rec_button = surface.makeButton(fader_x + 1, fader_y + 7, 1, 1) + this.rec_button.mSurfaceValue.mMidiBinding + .setInputPort(midiInput) + .bindToNote(0, 0 + this.instance) +} + +// channelControl.prototype.setSelLedOn = function (value) { +// this.vSelLedOn = value; +// } + +// channelControl.prototype.sendSelLed = function (context) { +// this.midiOutput.sendMidi(context, [0x90, this.instance + 24, this.vSelLedOn]); +// } + +module.exports = { + channelControl +} diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 1e7724e..93d3f13 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -1,3 +1,14 @@ +// Icon Platform M+ midi Remote +// Robert Woodcock +// +// Portions of this implementation where inspired by other midi remote creates to whom I wish to say thank you! +// - Mackie C4 by Ron Garrison https://github.com/rwgarrison/midiremote-userscripts + +var sw_rev = '0.0.0' + +var iconElements = require('./icon_elements.js'); +var channelControl = iconElements.channelControl; + //----------------------------------------------------------------------------- // 1. DRIVER SETUP - create driver object, midi ports and detection information //----------------------------------------------------------------------------- @@ -6,7 +17,7 @@ var midiremote_api = require('midiremote_api_v1') // create the device driver main object -var deviceDriver = midiremote_api.makeDeviceDriver('Icon', 'Platform Mplus', 'Big Fat Wombat') +var deviceDriver = midiremote_api.makeDeviceDriver('Icon', 'Platform Mplus', 'Big Fat Wombats') // create objects representing the hardware's MIDI ports var midiInput = deviceDriver.mPorts.makeMidiInput() @@ -15,8 +26,8 @@ var midiOutput = deviceDriver.mPorts.makeMidiOutput() // define all possible namings the devices MIDI ports could have // NOTE: Windows and MacOS handle port naming differently deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput) - .expectInputNameEquals('PlatformMonOut') // Platform M+ v2.15 - .expectOutputNameEquals('PlatformMonIn') // Platform M+ v2.15 + .expectInputNameEquals('Platform M+ V2.15') // Platform M+ v2.15 PlatformMonOut + .expectOutputNameEquals('Platform M+ V2.15') // Platform M+ v2.15 PlatformMonIn var surface = deviceDriver.mSurface @@ -24,46 +35,8 @@ var surface = deviceDriver.mSurface // 2. SURFACE LAYOUT - create control elements and midi bindings //----------------------------------------------------------------------------- -function makeKnobStrip(knobIndex, x, y) { - var knobStrip = {} - - knobStrip.knob = surface.makeKnob(x + 2 * knobIndex, y, 1, 1) - knobStrip.knob.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToControlChange(0, 16 + knobIndex).setTypeRelativeSignedBit() - knobStrip.touched = surface.makeButton(x + 2 * knobIndex, y+1, 1, 1) - knobStrip.touched.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, 32 + knobIndex) - - return knobStrip -} - -function makeFaderStrip(channelIndex, x, y) { - var faderStrip = {} - - // Fader + Fader Touch - faderStrip.fader = surface.makeFader(x + 2 * channelIndex, y, 1, 8).setTypeVertical() - faderStrip.fader.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToPitchBend(channelIndex) - - faderStrip.touched = surface.makeButton(x + 1+ 2 * channelIndex, y, 1, 1) - faderStrip.touched.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, 104 + channelIndex) - - // Channel Buittons - faderStrip.sel_button = surface.makeButton(x + 1 + 2 * channelIndex, y + 4, 1, 1) - faderStrip.sel_button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, 24 + channelIndex) - - faderStrip.mute_button = surface.makeButton(x + 1 + 2 * channelIndex, y + 5, 1, 1) - faderStrip.mute_button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, 16 + channelIndex) - - faderStrip.solo_button = surface.makeButton(x + 1 + 2 * channelIndex, y + 6, 1, 1) - faderStrip.solo_button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, 8 + channelIndex) - - faderStrip.rec_button = surface.makeButton(x + 1 + 2 * channelIndex, y + 7, 1, 1) - faderStrip.rec_button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, 0 + channelIndex) - - return faderStrip -} - function makeTransport(x, y) { var transport = {} - var w = 1 var h = 1 @@ -73,41 +46,44 @@ function makeTransport(x, y) { transport.prevChn = surface.makeButton(x, y, w, h) bindMidiNote(transport.prevChn, 0, 48) - transport.nextChn = surface.makeButton(x+1, y, w, h) + transport.nextChn = surface.makeButton(x + 1, y, w, h) bindMidiNote(transport.nextChn, 0, 49) - transport.prevBnk = surface.makeButton(x, y+1, w, h) + transport.prevBnk = surface.makeButton(x, y + 1, w, h) bindMidiNote(transport.prevBnk, 0, 46) - transport.nextBnk = surface.makeButton(x+1, y+1, w, h) + transport.nextBnk = surface.makeButton(x + 1, y + 1, w, h) bindMidiNote(transport.nextBnk, 0, 47) - transport.btnRewind = surface.makeButton(x, y+2, w, h) + transport.btnRewind = surface.makeButton(x, y + 2, w, h) bindMidiNote(transport.btnRewind, 0, 91) - transport.btnForward = surface.makeButton(x+1, y+2, w, h) + transport.btnForward = surface.makeButton(x + 1, y + 2, w, h) bindMidiNote(transport.btnForward, 0, 92) - transport.btnStart = surface.makeButton(x, y+3, w, h) - bindMidiNote(transport.btnStart, 0, 94) - transport.btnStop = surface.makeButton(x+1, y+3, w, h) + transport.btnStart = surface.makeButton(x, y + 3, w, h) + // bindMidiNote(transport.btnStart, 0, 94) + transport.start_state = deviceDriver.mSurface.makeCustomValueVariable('start_state') + transport.start_state.mMidiBinding.setInputPort(midiInput).bindToNote(0, 94) + + transport.btnStop = surface.makeButton(x + 1, y + 3, w, h) bindMidiNote(transport.btnStop, 0, 93) - transport.btnRecord = surface.makeButton(x, y+4, w, h) + transport.btnRecord = surface.makeButton(x, y + 4, w, h) bindMidiNote(transport.btnRecord, 0, 95) - transport.btnCycle = surface.makeButton(x+1, y+4, w, h) + transport.btnCycle = surface.makeButton(x + 1, y + 4, w, h) bindMidiNote(transport.btnCycle, 0, 86) // ! The Note on/off events for the special functioans are timestamped at the same time // ! cubase midi remote doesn't show anything on screen though a note is sent // Flip - Simultaneous press of Pre Chn+Pre Bank - transport.btnFlip = surface.makeButton(x+3, y+4, 1, 1) + transport.btnFlip = surface.makeButton(x + 3, y + 4, 1, 1) bindMidiNote(transport.btnFlip, 0, 50) // Pressing the Zoom keys simultaneously will toggle on and off a note event. If on // either zoom button will send a Note 100 when zoom is activated or deactivated by either button // If zoom is active and you simply press then other button the event will not be sent // - transport.btnZoomOnOff= surface.makeButton(x+4, y+4, 1, 1) + transport.btnZoomOnOff = surface.makeButton(x + 4, y + 4, 1, 1) bindMidiNote(transport.btnZoomOnOff, 0, 100) // The Jog wheel will change CC/Note based on which of thte Zoom buttons have been activated @@ -127,15 +103,15 @@ function makeTransport(x, y) { transport.jog_wheel.mPushValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, 101) //Zoom Vertical - transport.zoomVertOut = surface.makeButton(x+3, y + 6, 1, 1).setShapeCircle() + transport.zoomVertOut = surface.makeButton(x + 3, y + 6, 1, 1).setShapeCircle() bindMidiNote(transport.zoomVertOut, 0, 96) - transport.zoomVertIn = surface.makeButton(x+4, y + 6, 1, 1).setShapeCircle() + transport.zoomVertIn = surface.makeButton(x + 4, y + 6, 1, 1).setShapeCircle() bindMidiNote(transport.zoomVertIn, 0, 97) //Zoom Horizontal - transport.zoomHorizOut = surface.makeButton(x+3, y + 7, 1, 1).setShapeCircle() + transport.zoomHorizOut = surface.makeButton(x + 3, y + 7, 1, 1).setShapeCircle() bindMidiNote(transport.zoomHorizOut, 0, 98) - transport.zoomHorizIn = surface.makeButton(x+4, y + 7, 1, 1).setShapeCircle() + transport.zoomHorizIn = surface.makeButton(x + 4, y + 7, 1, 1).setShapeCircle() bindMidiNote(transport.zoomHorizIn, 0, 99) return transport @@ -146,50 +122,66 @@ function makeSurfaceElements() { surfaceElements.numStrips = 8 - surfaceElements.knobStrips = {} - surfaceElements.faderStrips = {} + surfaceElements.channelControls = {} var xKnobStrip = 0 var yKnobStrip = 0 - for(var i = 0; i < surfaceElements.numStrips; ++i) { - surfaceElements.knobStrips[i] = makeKnobStrip(i, xKnobStrip, yKnobStrip) - surfaceElements.faderStrips[i] = makeFaderStrip(i, xKnobStrip, yKnobStrip+3) + for (var i = 0; i < surfaceElements.numStrips; ++i) { + surfaceElements.channelControls[i] = new channelControl(surface, midiInput, midiOutput, xKnobStrip, yKnobStrip, i) } - surfaceElements.faderMaster = makeFaderStrip(surfaceElements.numStrips, xKnobStrip+1, yKnobStrip+3) - surfaceElements.transport = makeTransport(xKnobStrip+20, yKnobStrip+3) + // surfaceElements.faderMaster = makeFaderStrip(surfaceElements.numStrips, xKnobStrip+1, yKnobStrip+3) + surfaceElements.transport = makeTransport(xKnobStrip + 20, yKnobStrip + 3) return surfaceElements } var surfaceElements = makeSurfaceElements() +function makeTransportDisplayFeedback(button, ledID) { + button.mSurfaceValue.mOnProcessValueChange = function (context, newValue) { + midiOutput.sendMidi(context, [0x90, ledID, newValue]) + } +} +makeTransportDisplayFeedback(surfaceElements.transport.btnStart, 94) //----------------------------------------------------------------------------- -// 3. HOST MAPPING - create mapping pages and host bindings +// 3. HOST MAPPING - create mapping defaultPages and host bindings //----------------------------------------------------------------------------- -var page = deviceDriver.mMapping.makePage('Default') +var defaultPage = deviceDriver.mMapping.makePage('Default') -page.makeCommandBinding(surfaceElements.transport.zoomVertIn.mSurfaceValue, 'Zoom', 'Zoom In Vertically') -page.makeCommandBinding(surfaceElements.transport.zoomVertOut.mSurfaceValue, 'Zoom', 'Zoom Out Vertically') +defaultPage.makeCommandBinding(surfaceElements.transport.zoomVertIn.mSurfaceValue, 'Zoom', 'Zoom In Vertically') +defaultPage.makeCommandBinding(surfaceElements.transport.zoomVertOut.mSurfaceValue, 'Zoom', 'Zoom Out Vertically') -page.makeCommandBinding(surfaceElements.transport.zoomHorizIn.mSurfaceValue, 'Zoom', 'Zoom In') -page.makeCommandBinding(surfaceElements.transport.zoomHorizOut.mSurfaceValue, 'Zoom', 'Zoom Out') +defaultPage.makeCommandBinding(surfaceElements.transport.zoomHorizIn.mSurfaceValue, 'Zoom', 'Zoom In') +defaultPage.makeCommandBinding(surfaceElements.transport.zoomHorizOut.mSurfaceValue, 'Zoom', 'Zoom Out') + +// Start button +// var startStatus = deviceDriver.mSurface.makeCustomValueVariable('startStatus') + +defaultPage.makeValueBinding(surfaceElements.transport.btnStart.mSurfaceValue, defaultPage.mHostAccess.mTransport.mValue.mStart).setTypeToggle() + +surfaceElements.transport.start_state.mOnProcessValueChange = function (activeDevice, value) { + // Only send on press - process value change will be received for both press (1)and release (0) + if (value == 1) { + // console.log('Start pressed') + surfaceElements.transport.btnStart.mSurfaceValue.setProcessValue(activeDevice, value) + } +} // Jog Knob var jogLeftVariable = deviceDriver.mSurface.makeCustomValueVariable('jogLeft') var jogRightVariable = deviceDriver.mSurface.makeCustomValueVariable('jogRight') -page.makeCommandBinding(jogLeftVariable, 'Transport', 'Nudge Cursor Left') -page.makeCommandBinding(jogRightVariable, 'Transport', 'Nudge Cursor Right') +defaultPage.makeCommandBinding(jogLeftVariable, 'Transport', 'Nudge Cursor Left') +defaultPage.makeCommandBinding(jogRightVariable, 'Transport', 'Nudge Cursor Right') createCommandKnob(surfaceElements.transport.jog_wheel, jogRightVariable, jogLeftVariable); - function repeatCommand(activeDevice, command, repeats) { - for(var i = 0; i < repeats; i++) { + for (var i = 0; i < repeats; i++) { command.setProcessValue(activeDevice, 1) } } @@ -201,14 +193,14 @@ function repeatCommand(activeDevice, command, repeats) { */ function createCommandKnob(pushEncoder, commandIncrease, commandDecrease) { // console.log('from script: createCommandKnob') - pushEncoder.mEncoderValue.mOnProcessValueChange = function(activeDevice, value) { - console.log('value changed: ' + value) - if(value < 0.5 ) { - var jump_rate = Math.floor(value*127) - repeatCommand(activeDevice, commandIncrease, jump_rate) - } else if (value > 0.5) { - var jump_rate = Math.floor((value-0.5)*127) - repeatCommand(activeDevice, commandDecrease, jump_rate) - } + pushEncoder.mEncoderValue.mOnProcessValueChange = function (activeDevice, value) { + console.log('value changed: ' + value) + if (value < 0.5) { + var jump_rate = Math.floor(value * 127) + repeatCommand(activeDevice, commandIncrease, jump_rate) + } else if (value > 0.5) { + var jump_rate = Math.floor((value - 0.5) * 127) + repeatCommand(activeDevice, commandDecrease, jump_rate) + } } - } \ No newline at end of file +} \ No newline at end of file From 98704fa88d5c6a9ca4be52ca8597cc5a992b8450 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 22 May 2022 23:05:57 +1000 Subject: [PATCH 08/65] Led buttons all active, some are even bound to functions --- icon/platformmplus/icon_elements.js | 69 +++++++-------- icon/platformmplus/icon_platformmplus.js | 104 +++++++++-------------- 2 files changed, 73 insertions(+), 100 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index d48bd28..29d99c3 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -1,3 +1,27 @@ +/** + * @param {MR_DeviceSurface} surface + * @param {String} name + * @param {number} note + * @param {Boolean} toggle + * @param {number} x + * @param {number} y + * @param {number} w + * @param {number} h + * + */ + function makeLedButton(surface, note, x, y, w, h) { + var button = surface.makeButton(x, y, w, h) + button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, note) + button.mSurfaceValue.mOnProcessValueChange = (function (activeDevice, value) { + if (value > 0) + this.midiOutput.sendMidi(activeDevice, [0x90, note, 127]) + else { + this.midiOutput.sendMidi(activeDevice, [0x90, note, 0]) + } + }).bind({ midiOutput }) + return button +} + /** * @constructor * @param {MR_DeviceSurface} surface @@ -22,15 +46,6 @@ function channelControl(surface, midiInput, midiOutput, x, y, instance) { return ("Class channelControl"); } - this.vPotValue = 0; - this.vPotPushValue = 0; - this.vFaderValue = 0; - this.vFaderTouched = 0; - this.vSelLedOn = 0; - this.vMuteLedOn = 0; - this.vSoloLedOn = 0; - this.vRecLedOn = 0; - // Pot encoder this.pushEncoder = this.surface.makePushEncoder(this.x, y, 2, 2) @@ -56,37 +71,15 @@ function channelControl(surface, midiInput, midiOutput, x, y, instance) { .setInputPort(midiInput) .bindToNote(0, 104 + this.instance) - // Channel Buittons - this.sel_button = surface.makeButton(fader_x + 1, fader_y + 4, 1, 1) - this.sel_button.mSurfaceValue.mMidiBinding - .setInputPort(midiInput) - .setOutputPort(midiOutput) - .bindToNote(0, 24 + this.instance) - - this.mute_button = surface.makeButton(fader_x + 1, fader_y + 5, 1, 1) - this.mute_button.mSurfaceValue.mMidiBinding - .setInputPort(midiInput) - .bindToNote(0, 16 + this.instance) - - this.solo_button = surface.makeButton(fader_x + 1, fader_y + 6, 1, 1) - this.solo_button.mSurfaceValue.mMidiBinding - .setInputPort(midiInput) - .bindToNote(0, 8 + this.instance) + // Channel Buttons + this.sel_button = makeLedButton(surface, 24 + this.instance, fader_x + 1, fader_y + 4, 1, 1) + this.mute_button = makeLedButton(surface, 16 + this.instance, fader_x + 1, fader_y + 5, 1, 1) + this.solo_button = makeLedButton(surface, 8 + this.instance, fader_x + 1, fader_y + 6, 1, 1) + this.sel_button = makeLedButton(surface, 0 + this.instance, fader_x + 1, fader_y + 7, 1, 1) - this.rec_button = surface.makeButton(fader_x + 1, fader_y + 7, 1, 1) - this.rec_button.mSurfaceValue.mMidiBinding - .setInputPort(midiInput) - .bindToNote(0, 0 + this.instance) } -// channelControl.prototype.setSelLedOn = function (value) { -// this.vSelLedOn = value; -// } - -// channelControl.prototype.sendSelLed = function (context) { -// this.midiOutput.sendMidi(context, [0x90, this.instance + 24, this.vSelLedOn]); -// } - module.exports = { - channelControl + channelControl, + makeLedButton } diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 93d3f13..702ebbd 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -8,6 +8,7 @@ var sw_rev = '0.0.0' var iconElements = require('./icon_elements.js'); var channelControl = iconElements.channelControl; +var makeLedButton = iconElements.makeLedButton; //----------------------------------------------------------------------------- // 1. DRIVER SETUP - create driver object, midi ports and detection information @@ -35,6 +36,25 @@ var surface = deviceDriver.mSurface // 2. SURFACE LAYOUT - create control elements and midi bindings //----------------------------------------------------------------------------- +/** + * @param {MR_PushEncoder} pushEncoder + * @param {MR_SurfaceCustomValueVariable} commandIncrease + * @param {MR_SurfaceCustomValueVariable} commandDecrease + */ +function createCommandKnob(pushEncoder, commandIncrease, commandDecrease) { + // console.log('from script: createCommandKnob') + pushEncoder.mEncoderValue.mOnProcessValueChange = function (activeDevice, value) { + console.log('value changed: ' + value) + if (value < 0.5) { + var jump_rate = Math.floor(value * 127) + repeatCommand(activeDevice, commandIncrease, jump_rate) + } else if (value > 0.5) { + var jump_rate = Math.floor((value - 0.5) * 127) + repeatCommand(activeDevice, commandDecrease, jump_rate) + } + } +} + function makeTransport(x, y) { var transport = {} var w = 1 @@ -44,37 +64,25 @@ function makeTransport(x, y) { button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(chn, num) } - transport.prevChn = surface.makeButton(x, y, w, h) - bindMidiNote(transport.prevChn, 0, 48) - transport.nextChn = surface.makeButton(x + 1, y, w, h) - bindMidiNote(transport.nextChn, 0, 49) - - transport.prevBnk = surface.makeButton(x, y + 1, w, h) - bindMidiNote(transport.prevBnk, 0, 46) - transport.nextBnk = surface.makeButton(x + 1, y + 1, w, h) - bindMidiNote(transport.nextBnk, 0, 47) - - transport.btnRewind = surface.makeButton(x, y + 2, w, h) - bindMidiNote(transport.btnRewind, 0, 91) - transport.btnForward = surface.makeButton(x + 1, y + 2, w, h) - bindMidiNote(transport.btnForward, 0, 92) + transport.prevChn = makeLedButton(surface, 48, x, y, w, h) + transport.nextChn = makeLedButton(surface, 49, x + 1, y, w, h) - transport.btnStart = surface.makeButton(x, y + 3, w, h) - // bindMidiNote(transport.btnStart, 0, 94) - transport.start_state = deviceDriver.mSurface.makeCustomValueVariable('start_state') - transport.start_state.mMidiBinding.setInputPort(midiInput).bindToNote(0, 94) + // TODO Not implemented yet - not sure what to use them for + transport.prevBnk = makeLedButton(surface, 46, x, y + 1, w, h) + // TODO Not implemented yet - not sure what to use them for + transport.nextBnk = makeLedButton(surface, 47, x + 1, y + 1, w, h) - transport.btnStop = surface.makeButton(x + 1, y + 3, w, h) - bindMidiNote(transport.btnStop, 0, 93) + transport.btnRewind = makeLedButton(surface, 91, x, y + 2, w, h) + transport.btnForward = makeLedButton(surface, 92, x + 1, y + 2, w, h) - transport.btnRecord = surface.makeButton(x, y + 4, w, h) - bindMidiNote(transport.btnRecord, 0, 95) - transport.btnCycle = surface.makeButton(x + 1, y + 4, w, h) - bindMidiNote(transport.btnCycle, 0, 86) + transport.btnStart = makeLedButton(surface, 94, x, y + 3, w, h) + transport.btnStop = makeLedButton(surface, 93, x + 1, y + 3, w, h) - // ! The Note on/off events for the special functioans are timestamped at the same time - // ! cubase midi remote doesn't show anything on screen though a note is sent + transport.btnRecord = makeLedButton(surface, 95, x, y + 4, w, h) + transport.btnCycle = makeLedButton(surface, 86, x + 1, y + 4, w, h) + // The Note on/off events for the special functioans are timestamped at the same time + // cubase midi remote doesn't show anything on screen though a note is sent // Flip - Simultaneous press of Pre Chn+Pre Bank transport.btnFlip = surface.makeButton(x + 3, y + 4, 1, 1) bindMidiNote(transport.btnFlip, 0, 50) @@ -139,13 +147,6 @@ function makeSurfaceElements() { var surfaceElements = makeSurfaceElements() -function makeTransportDisplayFeedback(button, ledID) { - button.mSurfaceValue.mOnProcessValueChange = function (context, newValue) { - midiOutput.sendMidi(context, [0x90, ledID, newValue]) - } -} -makeTransportDisplayFeedback(surfaceElements.transport.btnStart, 94) - //----------------------------------------------------------------------------- // 3. HOST MAPPING - create mapping defaultPages and host bindings //----------------------------------------------------------------------------- @@ -158,18 +159,15 @@ defaultPage.makeCommandBinding(surfaceElements.transport.zoomVertOut.mSurfaceVal defaultPage.makeCommandBinding(surfaceElements.transport.zoomHorizIn.mSurfaceValue, 'Zoom', 'Zoom In') defaultPage.makeCommandBinding(surfaceElements.transport.zoomHorizOut.mSurfaceValue, 'Zoom', 'Zoom Out') -// Start button -// var startStatus = deviceDriver.mSurface.makeCustomValueVariable('startStatus') - +// Transport controls +defaultPage.makeActionBinding(surfaceElements.transport.prevChn.mSurfaceValue, defaultPage.mHostAccess.mTrackSelection.mAction.mPrevTrack) +defaultPage.makeActionBinding(surfaceElements.transport.nextChn.mSurfaceValue, defaultPage.mHostAccess.mTrackSelection.mAction.mNextTrack) +defaultPage.makeValueBinding(surfaceElements.transport.btnForward.mSurfaceValue, defaultPage.mHostAccess.mTransport.mValue.mForward) +defaultPage.makeValueBinding(surfaceElements.transport.btnRewind.mSurfaceValue, defaultPage.mHostAccess.mTransport.mValue.mRewind) defaultPage.makeValueBinding(surfaceElements.transport.btnStart.mSurfaceValue, defaultPage.mHostAccess.mTransport.mValue.mStart).setTypeToggle() - -surfaceElements.transport.start_state.mOnProcessValueChange = function (activeDevice, value) { - // Only send on press - process value change will be received for both press (1)and release (0) - if (value == 1) { - // console.log('Start pressed') - surfaceElements.transport.btnStart.mSurfaceValue.setProcessValue(activeDevice, value) - } -} +defaultPage.makeValueBinding(surfaceElements.transport.btnStop.mSurfaceValue, defaultPage.mHostAccess.mTransport.mValue.mStop).setTypeToggle() +defaultPage.makeValueBinding(surfaceElements.transport.btnRecord.mSurfaceValue, defaultPage.mHostAccess.mTransport.mValue.mRecord).setTypeToggle() +defaultPage.makeValueBinding(surfaceElements.transport.btnCycle.mSurfaceValue, defaultPage.mHostAccess.mTransport.mValue.mCycleActive).setTypeToggle() // Jog Knob var jogLeftVariable = deviceDriver.mSurface.makeCustomValueVariable('jogLeft') @@ -186,21 +184,3 @@ function repeatCommand(activeDevice, command, repeats) { } } -/** - * @param {MR_PushEncoder} pushEncoder - * @param {MR_SurfaceCustomValueVariable} commandIncrease - * @param {MR_SurfaceCustomValueVariable} commandDecrease - */ -function createCommandKnob(pushEncoder, commandIncrease, commandDecrease) { - // console.log('from script: createCommandKnob') - pushEncoder.mEncoderValue.mOnProcessValueChange = function (activeDevice, value) { - console.log('value changed: ' + value) - if (value < 0.5) { - var jump_rate = Math.floor(value * 127) - repeatCommand(activeDevice, commandIncrease, jump_rate) - } else if (value > 0.5) { - var jump_rate = Math.floor((value - 0.5) * 127) - repeatCommand(activeDevice, commandDecrease, jump_rate) - } - } -} \ No newline at end of file From 66c0a589f7cbbae4bb5542aa2c2dd49962e564c8 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Tue, 24 May 2022 22:30:53 +1000 Subject: [PATCH 09/65] Now with Mixer, auto bank and much flashing lights --- icon/platformmplus/icon_elements.js | 80 ++++++++++++++++++++---- icon/platformmplus/icon_platformmplus.js | 36 ++++++++++- 2 files changed, 102 insertions(+), 14 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 29d99c3..245ce39 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -22,6 +22,31 @@ return button } +/** + * @param {MR_DeviceSurface} surface + * @param {MR_DeviceMidiInput} midiInput + * @param {Number} channel - instance of the push encoder. + * @param {number} x - x location of the push encoder in the gui + * @param {Number} y - y location of the push encoder in the gui + * @param {Number} w - width of the push encoder. + * @param {Number} h - height of the push encoder. + */ +function makeTouchFader(surface, midiInput, midiOutput, channel, x, y, w, h) { + // Fader + Fader Touch + var fader = surface.makeFader(x, y, w, h).setTypeVertical() + fader.mSurfaceValue.mMidiBinding + .setInputPort(midiInput) + .setOutputPort(midiOutput) + .bindToPitchBend(channel) + + var fader_touch = surface.makeButton(x + 1, y, 1, 1) + fader_touch.mSurfaceValue.mMidiBinding + .setInputPort(midiInput) + .bindToNote(0, 104 + channel) + + return [fader,fader_touch] +} + /** * @constructor * @param {MR_DeviceSurface} surface @@ -61,25 +86,58 @@ function channelControl(surface, midiInput, midiOutput, x, y, instance) { // Fader + Fader Touch var fader_x = this.x var fader_y = y + 3 - this.fader = surface.makeFader(fader_x, fader_y, 1, 8).setTypeVertical() - this.fader.mSurfaceValue.mMidiBinding - .setInputPort(midiInput) - .bindToPitchBend(this.instance) - - this.fader_touch = surface.makeButton(fader_x + 1, fader_y, 1, 1) - this.fader_touch.mSurfaceValue.mMidiBinding - .setInputPort(midiInput) - .bindToNote(0, 104 + this.instance) + var tf = makeTouchFader(surface, midiInput, this.midiOutput, instance, fader_x, fader_y, 1, 8) + this.fader = tf[0] + this.fader_touch = tf[1] // Channel Buttons this.sel_button = makeLedButton(surface, 24 + this.instance, fader_x + 1, fader_y + 4, 1, 1) this.mute_button = makeLedButton(surface, 16 + this.instance, fader_x + 1, fader_y + 5, 1, 1) this.solo_button = makeLedButton(surface, 8 + this.instance, fader_x + 1, fader_y + 6, 1, 1) - this.sel_button = makeLedButton(surface, 0 + this.instance, fader_x + 1, fader_y + 7, 1, 1) + this.rec_button = makeLedButton(surface, 0 + this.instance, fader_x + 1, fader_y + 7, 1, 1) + +} + +/** + * @param {MR_DeviceSurface} surface + * @param {MR_DeviceMidiInput} midiInput + * @param {MR_DeviceMidiOutput} midiOutput + * @param {number} x - x location of the push encoder in the gui + * @param {Number} y - y location of the push encoder in the gui + * @param {Number} w - width of the push encoder. + * @param {Number} h - height of the push encoder. + * @param {Number} instance - instance of the push encoder. + */ + function masterControl(surface, midiInput, midiOutput, x, y, instance) { + // Position on GUI + this.surface = surface; + this.midiInput = midiInput; + this.midiOutput = midiOutput; + this.x = x + 2 * instance; + this.y = y; + this.instance = instance; // 9 - Master + + this.ident = function () { + return ("Class masterControl"); + } + + // Fader + Fader Touch + var fader_x = this.x + var fader_y = y + 3 + var tf = makeTouchFader(surface, midiInput, midiOutput, instance, fader_x, fader_y, 1, 8) + this.fader = tf[0] + this.fader_touch = tf[1] + + // Channel Buttons + this.mixer_button = makeLedButton(surface, 84, fader_x + 1, fader_y + 4, 1, 1) + this.read_button = makeLedButton(surface, 74, fader_x + 1, fader_y + 5, 1, 1) + this.write_button = makeLedButton(surface, 75, fader_x + 1, fader_y + 6, 1, 1) } module.exports = { channelControl, - makeLedButton + masterControl, + makeLedButton, + makeTouchFader } diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 702ebbd..4d0dbbe 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -8,6 +8,7 @@ var sw_rev = '0.0.0' var iconElements = require('./icon_elements.js'); var channelControl = iconElements.channelControl; +var masterControl = iconElements.masterControl; var makeLedButton = iconElements.makeLedButton; //----------------------------------------------------------------------------- @@ -68,6 +69,7 @@ function makeTransport(x, y) { transport.nextChn = makeLedButton(surface, 49, x + 1, y, w, h) // TODO Not implemented yet - not sure what to use them for + // TODO Perhaps Change the Page in the midi remote?? transport.prevBnk = makeLedButton(surface, 46, x, y + 1, w, h) // TODO Not implemented yet - not sure what to use them for transport.nextBnk = makeLedButton(surface, 47, x + 1, y + 1, w, h) @@ -107,8 +109,13 @@ function makeTransport(x, y) { // todo I wonder if there is a way to change that behaviour? transport.jog_wheel = surface.makePushEncoder(x, y + 6, 2, 2) - transport.jog_wheel.mEncoderValue.mMidiBinding.setInputPort(midiInput).bindToControlChange(0, 60).setTypeAbsolute() - transport.jog_wheel.mPushValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, 101) + transport.jog_wheel.mEncoderValue.mMidiBinding + .setInputPort(midiInput) + .bindToControlChange(0, 60) + .setTypeAbsolute() + transport.jog_wheel.mPushValue.mMidiBinding + .setInputPort(midiInput) + .bindToNote(0, 101) //Zoom Vertical transport.zoomVertOut = surface.makeButton(x + 3, y + 6, 1, 1).setShapeCircle() @@ -139,7 +146,7 @@ function makeSurfaceElements() { surfaceElements.channelControls[i] = new channelControl(surface, midiInput, midiOutput, xKnobStrip, yKnobStrip, i) } - // surfaceElements.faderMaster = makeFaderStrip(surfaceElements.numStrips, xKnobStrip+1, yKnobStrip+3) + surfaceElements.faderMaster = new masterControl(surface, midiInput, midiOutput, xKnobStrip+1, yKnobStrip, surfaceElements.numStrips) surfaceElements.transport = makeTransport(xKnobStrip + 20, yKnobStrip + 3) return surfaceElements @@ -170,6 +177,7 @@ defaultPage.makeValueBinding(surfaceElements.transport.btnRecord.mSurfaceValue, defaultPage.makeValueBinding(surfaceElements.transport.btnCycle.mSurfaceValue, defaultPage.mHostAccess.mTransport.mValue.mCycleActive).setTypeToggle() // Jog Knob +// TODO This is still passing midi events through. It's unclear how to stop the midi CC messages passing through? var jogLeftVariable = deviceDriver.mSurface.makeCustomValueVariable('jogLeft') var jogRightVariable = deviceDriver.mSurface.makeCustomValueVariable('jogRight') @@ -184,3 +192,25 @@ function repeatCommand(activeDevice, command, repeats) { } } +// Mixer +var hostMixerBankZone = defaultPage.mHostAccess.mMixConsole.makeMixerBankZone() + .excludeOutputChannels() + .excludeInputChannels() + +for(var channelIndex = 0; channelIndex < 8; ++channelIndex) { + var hostMixerBankChannel = hostMixerBankZone.makeMixerBankChannel() + + var knobSurfaceValue = surfaceElements.channelControls[channelIndex].pushEncoder.mEncoderValue; + var faderSurfaceValue = surfaceElements.channelControls[channelIndex].fader.mSurfaceValue; + var sel_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].sel_button.mSurfaceValue; + var mute_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].mute_button.mSurfaceValue; + var solo_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].solo_button.mSurfaceValue; + var rec_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].rec_button.mSurfaceValue; + + defaultPage.makeValueBinding(knobSurfaceValue, hostMixerBankChannel.mValue.mPan) + defaultPage.makeValueBinding(faderSurfaceValue, hostMixerBankChannel.mValue.mVolume) + defaultPage.makeValueBinding(sel_buttonSurfaceValue, hostMixerBankChannel.mValue.mSelected) + defaultPage.makeValueBinding(mute_buttonSurfaceValue, hostMixerBankChannel.mValue.mMute).setTypeToggle() + defaultPage.makeValueBinding(solo_buttonSurfaceValue, hostMixerBankChannel.mValue.mSolo).setTypeToggle() + defaultPage.makeValueBinding(rec_buttonSurfaceValue, hostMixerBankChannel.mValue.mRecordEnable).setTypeToggle() +} \ No newline at end of file From 138a45ea0d473fabbf28fe53c904477e99a3808f Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Thu, 26 May 2022 20:57:54 +1000 Subject: [PATCH 10/65] Assign a function to every button --- icon/platformmplus/icon_platformmplus.js | 26 ++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 4d0dbbe..bad8116 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -30,7 +30,7 @@ var midiOutput = deviceDriver.mPorts.makeMidiOutput() deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput) .expectInputNameEquals('Platform M+ V2.15') // Platform M+ v2.15 PlatformMonOut .expectOutputNameEquals('Platform M+ V2.15') // Platform M+ v2.15 PlatformMonIn - +. var surface = deviceDriver.mSurface //----------------------------------------------------------------------------- @@ -167,8 +167,10 @@ defaultPage.makeCommandBinding(surfaceElements.transport.zoomHorizIn.mSurfaceVal defaultPage.makeCommandBinding(surfaceElements.transport.zoomHorizOut.mSurfaceValue, 'Zoom', 'Zoom Out') // Transport controls -defaultPage.makeActionBinding(surfaceElements.transport.prevChn.mSurfaceValue, defaultPage.mHostAccess.mTrackSelection.mAction.mPrevTrack) -defaultPage.makeActionBinding(surfaceElements.transport.nextChn.mSurfaceValue, defaultPage.mHostAccess.mTrackSelection.mAction.mNextTrack) +defaultPage.makeCommandBinding(surfaceElements.transport.prevChn.mSurfaceValue, 'Transport', 'Locate Previous Marker') +defaultPage.makeCommandBinding(surfaceElements.transport.nextChn.mSurfaceValue, 'Transport', 'Locate Next Marker') +defaultPage.makeCommandBinding(surfaceElements.transport.prevBnk.mSurfaceValue, 'Transport', 'Set Punch In Position') +defaultPage.makeCommandBinding(surfaceElements.transport.nextBnk.mSurfaceValue, 'Transport', 'Set Punch Out Position') defaultPage.makeValueBinding(surfaceElements.transport.btnForward.mSurfaceValue, defaultPage.mHostAccess.mTransport.mValue.mForward) defaultPage.makeValueBinding(surfaceElements.transport.btnRewind.mSurfaceValue, defaultPage.mHostAccess.mTransport.mValue.mRewind) defaultPage.makeValueBinding(surfaceElements.transport.btnStart.mSurfaceValue, defaultPage.mHostAccess.mTransport.mValue.mStart).setTypeToggle() @@ -201,6 +203,7 @@ for(var channelIndex = 0; channelIndex < 8; ++channelIndex) { var hostMixerBankChannel = hostMixerBankZone.makeMixerBankChannel() var knobSurfaceValue = surfaceElements.channelControls[channelIndex].pushEncoder.mEncoderValue; + var knobPushValue = surfaceElements.channelControls[channelIndex].pushEncoder.mPushValue; var faderSurfaceValue = surfaceElements.channelControls[channelIndex].fader.mSurfaceValue; var sel_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].sel_button.mSurfaceValue; var mute_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].mute_button.mSurfaceValue; @@ -208,9 +211,24 @@ for(var channelIndex = 0; channelIndex < 8; ++channelIndex) { var rec_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].rec_button.mSurfaceValue; defaultPage.makeValueBinding(knobSurfaceValue, hostMixerBankChannel.mValue.mPan) + defaultPage.makeValueBinding(knobPushValue, hostMixerBankChannel.mValue.mInstrumentOpen).setTypeToggle() defaultPage.makeValueBinding(faderSurfaceValue, hostMixerBankChannel.mValue.mVolume) defaultPage.makeValueBinding(sel_buttonSurfaceValue, hostMixerBankChannel.mValue.mSelected) defaultPage.makeValueBinding(mute_buttonSurfaceValue, hostMixerBankChannel.mValue.mMute).setTypeToggle() defaultPage.makeValueBinding(solo_buttonSurfaceValue, hostMixerBankChannel.mValue.mSolo).setTypeToggle() defaultPage.makeValueBinding(rec_buttonSurfaceValue, hostMixerBankChannel.mValue.mRecordEnable).setTypeToggle() -} \ No newline at end of file +} + +// Master Fader +// If there is only One output it will be Main +// ? If there is more than one then this will be the first one +var ouputMixerBanks = defaultPage.mHostAccess.mMixConsole.makeMixerBankZone().includeOutputChannels() +var outputMixerBankChannels = ouputMixerBanks.makeMixerBankChannel() +defaultPage.makeValueBinding( surfaceElements.faderMaster.fader.mSurfaceValue, outputMixerBankChannels.mValue.mVolume) +// ? Or connect to headphones +// defaultPage.makeValueBinding( surfaceElements.faderMaster.fader.mSurfaceValue, defaultPage.mHostAccess.mControlRoom.getPhonesChannelByIndex(0).mLevelValue) + +// ? Would be nice to use the read and write buttons as read and write automation for selected track - but haven't figured out how to code that yet +defaultPage.makeValueBinding( surfaceElements.faderMaster.mixer_button.mSurfaceValue, defaultPage.mHostAccess.mTransport.mValue.mMetronomeActive).setTypeToggle() +defaultPage.makeValueBinding( surfaceElements.faderMaster.read_button.mSurfaceValue, defaultPage.mHostAccess.mControlRoom.mMainChannel.mDimActiveValue).setTypeToggle() +defaultPage.makeValueBinding( surfaceElements.faderMaster.write_button.mSurfaceValue, defaultPage.mHostAccess.mControlRoom.mMainChannel.mReferenceLevelEnabledValue).setTypeToggle() \ No newline at end of file From bdfb5a72d4d4e7ecce210585c93aa0fcbb3b1438 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sat, 28 May 2022 09:27:42 +1000 Subject: [PATCH 11/65] Fix typo in script --- icon/platformmplus/icon_platformmplus.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index bad8116..0c74873 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -4,7 +4,7 @@ // Portions of this implementation where inspired by other midi remote creates to whom I wish to say thank you! // - Mackie C4 by Ron Garrison https://github.com/rwgarrison/midiremote-userscripts -var sw_rev = '0.0.0' +var sw_rev = '0.0.1' var iconElements = require('./icon_elements.js'); var channelControl = iconElements.channelControl; @@ -28,9 +28,9 @@ var midiOutput = deviceDriver.mPorts.makeMidiOutput() // define all possible namings the devices MIDI ports could have // NOTE: Windows and MacOS handle port naming differently deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput) - .expectInputNameEquals('Platform M+ V2.15') // Platform M+ v2.15 PlatformMonOut - .expectOutputNameEquals('Platform M+ V2.15') // Platform M+ v2.15 PlatformMonIn -. + .expectInputNameEquals('Platform M+ V2.15') // Platform M+ v2.15 + .expectOutputNameEquals('Platform M+ V2.15') // Platform M+ v2.15 + var surface = deviceDriver.mSurface //----------------------------------------------------------------------------- From 141da6c020dbb7b895be7243811a37b342a8d947 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sat, 28 May 2022 16:52:18 +1000 Subject: [PATCH 12/65] Full MixerPage running - with subpages Start of SelectedTrack page --- icon/platformmplus/icon_elements.js | 104 ++++++- icon/platformmplus/icon_platformmplus.js | 337 +++++++++++------------ 2 files changed, 271 insertions(+), 170 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 245ce39..50d8323 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -135,9 +135,111 @@ function channelControl(surface, midiInput, midiOutput, x, y, instance) { } +function repeatCommand(activeDevice, command, repeats) { + for (var i = 0; i < repeats; i++) { + command.setProcessValue(activeDevice, 1) + } +} +/** + * @param {MR_PushEncoder} pushEncoder + * @param {MR_SurfaceCustomValueVariable} commandIncrease + * @param {MR_SurfaceCustomValueVariable} commandDecrease + */ + function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { + // console.log('from script: createCommandKnob') + pushEncoder.mEncoderValue.mOnProcessValueChange = function (activeDevice, value) { + console.log('value changed: ' + value) + if (value < 0.5) { + var jump_rate = Math.floor(value * 127) + repeatCommand(activeDevice, commandIncrease, jump_rate) + } else if (value > 0.5) { + var jump_rate = Math.floor((value - 0.5) * 127) + repeatCommand(activeDevice, commandDecrease, jump_rate) + } + } +} + +function makeTransport(surface, x, y) { + var transport = {} + var w = 1 + var h = 1 + + function bindMidiNote(button, chn, num) { + button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(chn, num) + } + + transport.prevChn = makeLedButton(surface, 48, x, y, w, h) + transport.nextChn = makeLedButton(surface, 49, x + 1, y, w, h) + + // TODO Not implemented yet - not sure what to use them for + // TODO Perhaps Change the Page in the midi remote?? + transport.prevBnk = makeLedButton(surface, 46, x, y + 1, w, h) + // TODO Not implemented yet - not sure what to use them for + transport.nextBnk = makeLedButton(surface, 47, x + 1, y + 1, w, h) + + transport.btnRewind = makeLedButton(surface, 91, x, y + 2, w, h) + transport.btnForward = makeLedButton(surface, 92, x + 1, y + 2, w, h) + + transport.btnStart = makeLedButton(surface, 94, x, y + 3, w, h) + transport.btnStop = makeLedButton(surface, 93, x + 1, y + 3, w, h) + + transport.btnRecord = makeLedButton(surface, 95, x, y + 4, w, h) + transport.btnCycle = makeLedButton(surface, 86, x + 1, y + 4, w, h) + + // The Note on/off events for the special functioans are timestamped at the same time + // cubase midi remote doesn't show anything on screen though a note is sent + // Flip - Simultaneous press of Pre Chn+Pre Bank + transport.btnFlip = surface.makeButton(x + 3, y + 4, 1, 1) + bindMidiNote(transport.btnFlip, 0, 50) + + // Pressing the Zoom keys simultaneously will toggle on and off a note event. If on + // either zoom button will send a Note 100 when zoom is activated or deactivated by either button + // If zoom is active and you simply press then other button the event will not be sent + // + transport.btnZoomOnOff = surface.makeButton(x + 4, y + 4, 1, 1) + bindMidiNote(transport.btnZoomOnOff, 0, 100) + + // The Jog wheel will change CC/Note based on which of thte Zoom buttons have been activated + // None - CC 60 + // Vertical - Note Clockwise 97, CounterClockwise 96 + // Horizontal - Note Clockwise 99, CounterClockwise 98 + // The Jog wheel is an endless encoder but the surface Push Encoder is control value 0-127 + // In this case it pays to use the Absolute binding type as the Platform M+ produces a rate based + // CC value - turn clockwise slowly -> 1, turn it rapidly -> 7 (counter clockwise values are offset by 50, turn CCW slowly -> 51) + // In the Jog (or more correctly Nudge Cursor) mapping we use this to "tap the key severel times" - giving the impact of fine grain control if turned slowly + // or large nudges if turned quickly. + // ? One weird side effect of this is the Knob displayed in Cubase will show its "value" in a weird way. + // todo I wonder if there is a way to change that behaviour? + + transport.jog_wheel = surface.makePushEncoder(x, y + 6, 2, 2) + transport.jog_wheel.mEncoderValue.mMidiBinding + .setInputPort(midiInput) + .bindToControlChange(0, 60) + .setTypeAbsolute() + transport.jog_wheel.mPushValue.mMidiBinding + .setInputPort(midiInput) + .bindToNote(0, 101) + + //Zoom Vertical + transport.zoomVertOut = surface.makeButton(x + 3, y + 6, 1, 1).setShapeCircle() + bindMidiNote(transport.zoomVertOut, 0, 96) + transport.zoomVertIn = surface.makeButton(x + 4, y + 6, 1, 1).setShapeCircle() + bindMidiNote(transport.zoomVertIn, 0, 97) + + //Zoom Horizontal + transport.zoomHorizOut = surface.makeButton(x + 3, y + 7, 1, 1).setShapeCircle() + bindMidiNote(transport.zoomHorizOut, 0, 98) + transport.zoomHorizIn = surface.makeButton(x + 4, y + 7, 1, 1).setShapeCircle() + bindMidiNote(transport.zoomHorizIn, 0, 99) + + return transport +} + module.exports = { channelControl, masterControl, makeLedButton, - makeTouchFader + makeTouchFader, + makeTransport, + bindCommandKnob } diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 0c74873..716382f 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -4,12 +4,11 @@ // Portions of this implementation where inspired by other midi remote creates to whom I wish to say thank you! // - Mackie C4 by Ron Garrison https://github.com/rwgarrison/midiremote-userscripts -var sw_rev = '0.0.1' - -var iconElements = require('./icon_elements.js'); -var channelControl = iconElements.channelControl; -var masterControl = iconElements.masterControl; -var makeLedButton = iconElements.makeLedButton; +var iconElements = require('./icon_elements.js') +var channelControl = iconElements.channelControl +var masterControl = iconElements.masterControl +var makeTransport = iconElements.makeTransport +var bindCommandKnob = iconElements.bindCommandKnob //----------------------------------------------------------------------------- // 1. DRIVER SETUP - create driver object, midi ports and detection information @@ -27,111 +26,20 @@ var midiOutput = deviceDriver.mPorts.makeMidiOutput() // define all possible namings the devices MIDI ports could have // NOTE: Windows and MacOS handle port naming differently +// deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput) +// .expectInputNameEquals('Platform M+ V2.15') // Platform M+ v2.15 +// .expectOutputNameEquals('Platform M+ V2.15') // Platform M+ v2.15 deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput) - .expectInputNameEquals('Platform M+ V2.15') // Platform M+ v2.15 - .expectOutputNameEquals('Platform M+ V2.15') // Platform M+ v2.15 + .expectInputNameContains('Platform M+') + .expectOutputNameContains('Platform M+') +// ? I wonder if this can be figured out? +// .expectSysexIdentityResponse(/*vendor id (1 or 3 bytes, here: 3 bytes)*/'00n1n2', /*device family*/'n1n2', /*model number*/'n1n2') var surface = deviceDriver.mSurface //----------------------------------------------------------------------------- // 2. SURFACE LAYOUT - create control elements and midi bindings //----------------------------------------------------------------------------- - -/** - * @param {MR_PushEncoder} pushEncoder - * @param {MR_SurfaceCustomValueVariable} commandIncrease - * @param {MR_SurfaceCustomValueVariable} commandDecrease - */ -function createCommandKnob(pushEncoder, commandIncrease, commandDecrease) { - // console.log('from script: createCommandKnob') - pushEncoder.mEncoderValue.mOnProcessValueChange = function (activeDevice, value) { - console.log('value changed: ' + value) - if (value < 0.5) { - var jump_rate = Math.floor(value * 127) - repeatCommand(activeDevice, commandIncrease, jump_rate) - } else if (value > 0.5) { - var jump_rate = Math.floor((value - 0.5) * 127) - repeatCommand(activeDevice, commandDecrease, jump_rate) - } - } -} - -function makeTransport(x, y) { - var transport = {} - var w = 1 - var h = 1 - - function bindMidiNote(button, chn, num) { - button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(chn, num) - } - - transport.prevChn = makeLedButton(surface, 48, x, y, w, h) - transport.nextChn = makeLedButton(surface, 49, x + 1, y, w, h) - - // TODO Not implemented yet - not sure what to use them for - // TODO Perhaps Change the Page in the midi remote?? - transport.prevBnk = makeLedButton(surface, 46, x, y + 1, w, h) - // TODO Not implemented yet - not sure what to use them for - transport.nextBnk = makeLedButton(surface, 47, x + 1, y + 1, w, h) - - transport.btnRewind = makeLedButton(surface, 91, x, y + 2, w, h) - transport.btnForward = makeLedButton(surface, 92, x + 1, y + 2, w, h) - - transport.btnStart = makeLedButton(surface, 94, x, y + 3, w, h) - transport.btnStop = makeLedButton(surface, 93, x + 1, y + 3, w, h) - - transport.btnRecord = makeLedButton(surface, 95, x, y + 4, w, h) - transport.btnCycle = makeLedButton(surface, 86, x + 1, y + 4, w, h) - - // The Note on/off events for the special functioans are timestamped at the same time - // cubase midi remote doesn't show anything on screen though a note is sent - // Flip - Simultaneous press of Pre Chn+Pre Bank - transport.btnFlip = surface.makeButton(x + 3, y + 4, 1, 1) - bindMidiNote(transport.btnFlip, 0, 50) - - // Pressing the Zoom keys simultaneously will toggle on and off a note event. If on - // either zoom button will send a Note 100 when zoom is activated or deactivated by either button - // If zoom is active and you simply press then other button the event will not be sent - // - transport.btnZoomOnOff = surface.makeButton(x + 4, y + 4, 1, 1) - bindMidiNote(transport.btnZoomOnOff, 0, 100) - - // The Jog wheel will change CC/Note based on which of thte Zoom buttons have been activated - // None - CC 60 - // Vertical - Note Clockwise 97, CounterClockwise 96 - // Horizontal - Note Clockwise 99, CounterClockwise 98 - // The Jog wheel is an endless encoder but the surface Push Encoder is control value 0-127 - // In this case it pays to use the Absolute binding type as the Platform M+ produces a rate based - // CC value - turn clockwise slowly -> 1, turn it rapidly -> 7 (counter clockwise values are offset by 50, turn CCW slowly -> 51) - // In the Jog (or more correctly Nudge Cursor) mapping we use this to "tap the key severel times" - giving the impact of fine grain control if turned slowly - // or large nudges if turned quickly. - // ? One weird side effect of this is the Knob displayed in Cubase will show its "value" in a weird way. - // todo I wonder if there is a way to change that behaviour? - - transport.jog_wheel = surface.makePushEncoder(x, y + 6, 2, 2) - transport.jog_wheel.mEncoderValue.mMidiBinding - .setInputPort(midiInput) - .bindToControlChange(0, 60) - .setTypeAbsolute() - transport.jog_wheel.mPushValue.mMidiBinding - .setInputPort(midiInput) - .bindToNote(0, 101) - - //Zoom Vertical - transport.zoomVertOut = surface.makeButton(x + 3, y + 6, 1, 1).setShapeCircle() - bindMidiNote(transport.zoomVertOut, 0, 96) - transport.zoomVertIn = surface.makeButton(x + 4, y + 6, 1, 1).setShapeCircle() - bindMidiNote(transport.zoomVertIn, 0, 97) - - //Zoom Horizontal - transport.zoomHorizOut = surface.makeButton(x + 3, y + 7, 1, 1).setShapeCircle() - bindMidiNote(transport.zoomHorizOut, 0, 98) - transport.zoomHorizIn = surface.makeButton(x + 4, y + 7, 1, 1).setShapeCircle() - bindMidiNote(transport.zoomHorizIn, 0, 99) - - return transport -} - function makeSurfaceElements() { var surfaceElements = {} @@ -146,8 +54,8 @@ function makeSurfaceElements() { surfaceElements.channelControls[i] = new channelControl(surface, midiInput, midiOutput, xKnobStrip, yKnobStrip, i) } - surfaceElements.faderMaster = new masterControl(surface, midiInput, midiOutput, xKnobStrip+1, yKnobStrip, surfaceElements.numStrips) - surfaceElements.transport = makeTransport(xKnobStrip + 20, yKnobStrip + 3) + surfaceElements.faderMaster = new masterControl(surface, midiInput, midiOutput, xKnobStrip + 1, yKnobStrip, surfaceElements.numStrips) + surfaceElements.transport = makeTransport(surface, xKnobStrip + 20, yKnobStrip + 3) return surfaceElements } @@ -155,80 +63,171 @@ function makeSurfaceElements() { var surfaceElements = makeSurfaceElements() //----------------------------------------------------------------------------- -// 3. HOST MAPPING - create mapping defaultPages and host bindings +// 3. HOST MAPPING - create mapping mixerPages and host bindings //----------------------------------------------------------------------------- -var defaultPage = deviceDriver.mMapping.makePage('Default') +// Helper functions +function makeSubPage(subPageArea, name) { + var subPage = subPageArea.makeSubPage(name) + var msgText = 'sub page ' + name + ' activated' + subPage.mOnActivate = function (activeDevice) { + console.log(msgText) + } + return subPage +} +/** + * @param {string} name +*/ +// Mappings for the default areas - transport, zoom, knob +function makePageWithDefaults(name) { + var page = deviceDriver.mMapping.makePage(name) + var jogSubPageArea = page.makeSubPageArea('Jog') + var zoomSubPageArea = page.makeSubPageArea('Zoom') + var subPageJogNudge = makeSubPage(jogSubPageArea, 'Nudge') + var subPageJogScrub = makeSubPage(jogSubPageArea, 'Srcub') + var subPageJogZoom = makeSubPage(zoomSubPageArea, 'Zoom') + var subPageJobNav = makeSubPage(zoomSubPageArea, 'Nav') + + // Transport controls + page.makeActionBinding(surfaceElements.transport.prevChn.mSurfaceValue, deviceDriver.mAction.mPrevPage) + page.makeActionBinding(surfaceElements.transport.nextChn.mSurfaceValue, deviceDriver.mAction.mNextPage) + page.makeCommandBinding(surfaceElements.transport.prevBnk.mSurfaceValue, 'Transport', 'Locate Previous Marker') + page.makeCommandBinding(surfaceElements.transport.nextBnk.mSurfaceValue, 'Transport', 'Locate Next Marker') + page.makeValueBinding(surfaceElements.transport.btnForward.mSurfaceValue, page.mHostAccess.mTransport.mValue.mForward) + page.makeValueBinding(surfaceElements.transport.btnRewind.mSurfaceValue, page.mHostAccess.mTransport.mValue.mRewind) + page.makeValueBinding(surfaceElements.transport.btnStart.mSurfaceValue, page.mHostAccess.mTransport.mValue.mStart).setTypeToggle() + page.makeValueBinding(surfaceElements.transport.btnStop.mSurfaceValue, page.mHostAccess.mTransport.mValue.mStop).setTypeToggle() + page.makeValueBinding(surfaceElements.transport.btnRecord.mSurfaceValue, page.mHostAccess.mTransport.mValue.mRecord).setTypeToggle() + page.makeValueBinding(surfaceElements.transport.btnCycle.mSurfaceValue, page.mHostAccess.mTransport.mValue.mCycleActive).setTypeToggle() + + // Zoom Pages - when either Zoom light is on + page.makeCommandBinding(surfaceElements.transport.zoomVertIn.mSurfaceValue, 'Zoom', 'Zoom In Vertically').setSubPage(subPageJogZoom) + page.makeCommandBinding(surfaceElements.transport.zoomVertOut.mSurfaceValue, 'Zoom', 'Zoom Out Vertically').setSubPage(subPageJogZoom) + page.makeCommandBinding(surfaceElements.transport.zoomHorizIn.mSurfaceValue, 'Zoom', 'Zoom In').setSubPage(subPageJogZoom) + page.makeCommandBinding(surfaceElements.transport.zoomHorizOut.mSurfaceValue, 'Zoom', 'Zoom Out').setSubPage(subPageJogZoom) + // Nav Pages + page.makeActionBinding(surfaceElements.transport.zoomVertIn.mSurfaceValue, page.mHostAccess.mTrackSelection.mAction.mNextTrack).setSubPage(subPageJobNav) + page.makeActionBinding(surfaceElements.transport.zoomVertOut.mSurfaceValue, page.mHostAccess.mTrackSelection.mAction.mPrevTrack).setSubPage(subPageJobNav) + page.makeCommandBinding(surfaceElements.transport.zoomHorizIn.mSurfaceValue, 'Transport', 'Locate Next Event').setSubPage(subPageJobNav) + page.makeCommandBinding(surfaceElements.transport.zoomHorizOut.mSurfaceValue, 'Transport', 'Locate Previous Event').setSubPage(subPageJobNav) + // Switch Zoom and Nav via simultaneous press of Zoom buttons + page.makeActionBinding(surfaceElements.transport.btnZoomOnOff.mSurfaceValue, zoomSubPageArea.mAction.mNext) + + // Jog Pages - when Zoom lights are off + // ? This is still passing midi events through. It's unclear how to stop the midi CC messages passing through other then removing the MIDI port from All In + var jogLeftVariable = deviceDriver.mSurface.makeCustomValueVariable('jogLeft') + var jogRightVariable = deviceDriver.mSurface.makeCustomValueVariable('jogRight') + + bindCommandKnob(surfaceElements.transport.jog_wheel, jogRightVariable, jogLeftVariable); + // Nuge + page.makeCommandBinding(jogLeftVariable, 'Transport', 'Nudge Cursor Left').setSubPage(subPageJogNudge) + page.makeCommandBinding(jogRightVariable, 'Transport', 'Nudge Cursor Right').setSubPage(subPageJogNudge) + // Scrub (Jog in Cubase) + page.makeCommandBinding(jogLeftVariable, 'Transport', 'Jog Left').setSubPage(subPageJogScrub) + page.makeCommandBinding(jogRightVariable, 'Transport', 'Jog Right').setSubPage(subPageJogScrub) + // Switch between Nudge and Scrub by tapping knob + page.makeActionBinding(surfaceElements.transport.jog_wheel.mPushValue, jogSubPageArea.mAction.mNext) + + return page +} + +function makePageMixer() { + var page = makePageWithDefaults('Mixer') -defaultPage.makeCommandBinding(surfaceElements.transport.zoomVertIn.mSurfaceValue, 'Zoom', 'Zoom In Vertically') -defaultPage.makeCommandBinding(surfaceElements.transport.zoomVertOut.mSurfaceValue, 'Zoom', 'Zoom Out Vertically') -defaultPage.makeCommandBinding(surfaceElements.transport.zoomHorizIn.mSurfaceValue, 'Zoom', 'Zoom In') -defaultPage.makeCommandBinding(surfaceElements.transport.zoomHorizOut.mSurfaceValue, 'Zoom', 'Zoom Out') + var FaderSubPageArea = page.makeSubPageArea('FadersKnobs') + var ButtonSubPageArea = page.makeSubPageArea('Buttons') + var MasterFaderSubPageArea = page.makeSubPageArea('MasterFader') -// Transport controls -defaultPage.makeCommandBinding(surfaceElements.transport.prevChn.mSurfaceValue, 'Transport', 'Locate Previous Marker') -defaultPage.makeCommandBinding(surfaceElements.transport.nextChn.mSurfaceValue, 'Transport', 'Locate Next Marker') -defaultPage.makeCommandBinding(surfaceElements.transport.prevBnk.mSurfaceValue, 'Transport', 'Set Punch In Position') -defaultPage.makeCommandBinding(surfaceElements.transport.nextBnk.mSurfaceValue, 'Transport', 'Set Punch Out Position') -defaultPage.makeValueBinding(surfaceElements.transport.btnForward.mSurfaceValue, defaultPage.mHostAccess.mTransport.mValue.mForward) -defaultPage.makeValueBinding(surfaceElements.transport.btnRewind.mSurfaceValue, defaultPage.mHostAccess.mTransport.mValue.mRewind) -defaultPage.makeValueBinding(surfaceElements.transport.btnStart.mSurfaceValue, defaultPage.mHostAccess.mTransport.mValue.mStart).setTypeToggle() -defaultPage.makeValueBinding(surfaceElements.transport.btnStop.mSurfaceValue, defaultPage.mHostAccess.mTransport.mValue.mStop).setTypeToggle() -defaultPage.makeValueBinding(surfaceElements.transport.btnRecord.mSurfaceValue, defaultPage.mHostAccess.mTransport.mValue.mRecord).setTypeToggle() -defaultPage.makeValueBinding(surfaceElements.transport.btnCycle.mSurfaceValue, defaultPage.mHostAccess.mTransport.mValue.mCycleActive).setTypeToggle() + var subPageFaderVolume = makeSubPage(FaderSubPageArea, 'Volume') -// Jog Knob -// TODO This is still passing midi events through. It's unclear how to stop the midi CC messages passing through? -var jogLeftVariable = deviceDriver.mSurface.makeCustomValueVariable('jogLeft') -var jogRightVariable = deviceDriver.mSurface.makeCustomValueVariable('jogRight') + var subPageButtonDefaultSet = makeSubPage(ButtonSubPageArea, 'DefaultSet') + var subPageMasterFaderMain = makeSubPage(MasterFaderSubPageArea, 'MF_MainOut') + var subPageMasterFaderHeadphone = makeSubPage(MasterFaderSubPageArea, 'MF_HeadphoneOut') + var subPageMasterCMain = makeSubPage(MasterFaderSubPageArea, 'MF_CMain') + var subPageMasterFaderValue = makeSubPage(MasterFaderSubPageArea, 'MF_ValueUnderCursor') -defaultPage.makeCommandBinding(jogLeftVariable, 'Transport', 'Nudge Cursor Left') -defaultPage.makeCommandBinding(jogRightVariable, 'Transport', 'Nudge Cursor Right') + var hostMixerBankZone = page.mHostAccess.mMixConsole.makeMixerBankZone() + .excludeOutputChannels() + .excludeInputChannels() -createCommandKnob(surfaceElements.transport.jog_wheel, jogRightVariable, jogLeftVariable); + for (var channelIndex = 0; channelIndex < 8; ++channelIndex) { + var hostMixerBankChannel = hostMixerBankZone.makeMixerBankChannel() -function repeatCommand(activeDevice, command, repeats) { - for (var i = 0; i < repeats; i++) { - command.setProcessValue(activeDevice, 1) + var knobSurfaceValue = surfaceElements.channelControls[channelIndex].pushEncoder.mEncoderValue; + var knobPushValue = surfaceElements.channelControls[channelIndex].pushEncoder.mPushValue; + var faderSurfaceValue = surfaceElements.channelControls[channelIndex].fader.mSurfaceValue; + var sel_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].sel_button.mSurfaceValue; + var mute_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].mute_button.mSurfaceValue; + var solo_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].solo_button.mSurfaceValue; + var rec_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].rec_button.mSurfaceValue; + + // FaderKnobs - Volume, Pan, Editor Open + page.makeValueBinding(knobSurfaceValue, hostMixerBankChannel.mValue.mPan).setSubPage(subPageFaderVolume) + page.makeValueBinding(knobPushValue, hostMixerBankChannel.mValue.mEditorOpen).setTypeToggle().setSubPage(subPageFaderVolume) + page.makeValueBinding(faderSurfaceValue, hostMixerBankChannel.mValue.mVolume).setValueTakeOverModeJump().setSubPage(subPageFaderVolume) + page.makeValueBinding(sel_buttonSurfaceValue, hostMixerBankChannel.mValue.mSelected).setTypeToggle().setValueTakeOverModeJump().setSubPage(subPageButtonDefaultSet) + + page.makeValueBinding(mute_buttonSurfaceValue, hostMixerBankChannel.mValue.mMute).setTypeToggle().setSubPage(subPageButtonDefaultSet) + page.makeValueBinding(solo_buttonSurfaceValue, hostMixerBankChannel.mValue.mSolo).setTypeToggle().setSubPage(subPageButtonDefaultSet) + page.makeValueBinding(rec_buttonSurfaceValue, hostMixerBankChannel.mValue.mRecordEnable).setTypeToggle().setSubPage(subPageButtonDefaultSet) + } + // Automation for selected tracks + page.makeCommandBinding(surfaceElements.faderMaster.read_button.mSurfaceValue, 'Automation', 'Toggle Read Enable Selected Tracks') + page.makeCommandBinding(surfaceElements.faderMaster.write_button.mSurfaceValue, 'Automation', 'Toggle Write Enable Selected Tracks') + + // Master Fader + // If there is only One output it will be Main + // If there is more than one out then this will be the first one - there doesn't appear to be a way to verify this + var outputMixerBanks = page.mHostAccess.mMixConsole.makeMixerBankZone().includeOutputChannels() + var outputMixerBankChannels = outputMixerBanks.makeMixerBankChannel() + page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, outputMixerBankChannels.mValue.mVolume).setValueTakeOverModeJump().setSubPage(subPageMasterFaderMain) + page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, page.mHostAccess.mMouseCursor.mValueUnderMouse).setValueTakeOverModeJump().setSubPage(subPageMasterFaderValue) + page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, page.mHostAccess.mControlRoom.getPhonesChannelByIndex(0).mLevelValue).setValueTakeOverModeJump().setSubPage(subPageMasterFaderHeadphone) + page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, page.mHostAccess.mControlRoom.mMainChannel.mLevelValue).setValueTakeOverModeJump().setSubPage(subPageMasterCMain) + + + // Switch Master Fader to Main Out->Headphone->Value Under Cursor (AI) + page.makeActionBinding(surfaceElements.faderMaster.mixer_button.mSurfaceValue, MasterFaderSubPageArea.mAction.mNext) + + return page +} + +function makePageSelectedTrack() { + var page = makePageWithDefaults('Selected Track') + + var selectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel + + // Automation for selected tracks + page.makeValueBinding(surfaceElements.faderMaster.read_button.mSurfaceValue, selectedTrackChannel.mValue.mAutomationRead).setTypeToggle() + page.makeValueBinding(surfaceElements.faderMaster.write_button.mSurfaceValue, selectedTrackChannel.mValue.mAutomationWrite).setTypeToggle() + + for (var idx = 0; idx < 8; ++idx) { + var knobSurfaceValue = surfaceElements.channelControls[idx].pushEncoder.mEncoderValue; + var knobPushValue = surfaceElements.channelControls[idx].pushEncoder.mPushValue; + var faderSurfaceValue = surfaceElements.channelControls[idx].fader.mSurfaceValue; + var sel_buttonSurfaceValue = surfaceElements.channelControls[idx].sel_button.mSurfaceValue; + var mute_buttonSurfaceValue = surfaceElements.channelControls[idx].mute_button.mSurfaceValue; + var solo_buttonSurfaceValue = surfaceElements.channelControls[idx].solo_button.mSurfaceValue; + var rec_buttonSurfaceValue = surfaceElements.channelControls[idx].rec_button.mSurfaceValue; + + page.makeValueBinding(knobSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mLevel) + page.makeValueBinding(sel_buttonSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mOn).setTypeToggle() + page.makeValueBinding(mute_buttonSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mPrePost).setTypeToggle() + page.makeValueBinding(faderSurfaceValue, selectedTrackChannel.mQuickControls.getByIndex(idx)).setValueTakeOverModeJump() } + + return page } -// Mixer -var hostMixerBankZone = defaultPage.mHostAccess.mMixConsole.makeMixerBankZone() - .excludeOutputChannels() - .excludeInputChannels() - -for(var channelIndex = 0; channelIndex < 8; ++channelIndex) { - var hostMixerBankChannel = hostMixerBankZone.makeMixerBankChannel() - - var knobSurfaceValue = surfaceElements.channelControls[channelIndex].pushEncoder.mEncoderValue; - var knobPushValue = surfaceElements.channelControls[channelIndex].pushEncoder.mPushValue; - var faderSurfaceValue = surfaceElements.channelControls[channelIndex].fader.mSurfaceValue; - var sel_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].sel_button.mSurfaceValue; - var mute_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].mute_button.mSurfaceValue; - var solo_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].solo_button.mSurfaceValue; - var rec_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].rec_button.mSurfaceValue; - - defaultPage.makeValueBinding(knobSurfaceValue, hostMixerBankChannel.mValue.mPan) - defaultPage.makeValueBinding(knobPushValue, hostMixerBankChannel.mValue.mInstrumentOpen).setTypeToggle() - defaultPage.makeValueBinding(faderSurfaceValue, hostMixerBankChannel.mValue.mVolume) - defaultPage.makeValueBinding(sel_buttonSurfaceValue, hostMixerBankChannel.mValue.mSelected) - defaultPage.makeValueBinding(mute_buttonSurfaceValue, hostMixerBankChannel.mValue.mMute).setTypeToggle() - defaultPage.makeValueBinding(solo_buttonSurfaceValue, hostMixerBankChannel.mValue.mSolo).setTypeToggle() - defaultPage.makeValueBinding(rec_buttonSurfaceValue, hostMixerBankChannel.mValue.mRecordEnable).setTypeToggle() +var mixerPage = makePageMixer() +var selectedTrackPage = makePageSelectedTrack() +// var quadPage = makePageQuad() + +mixerPage.mOnActivate = function (device) { + console.log('from script: Platform M+ page "Mixer" activated') } -// Master Fader -// If there is only One output it will be Main -// ? If there is more than one then this will be the first one -var ouputMixerBanks = defaultPage.mHostAccess.mMixConsole.makeMixerBankZone().includeOutputChannels() -var outputMixerBankChannels = ouputMixerBanks.makeMixerBankChannel() -defaultPage.makeValueBinding( surfaceElements.faderMaster.fader.mSurfaceValue, outputMixerBankChannels.mValue.mVolume) -// ? Or connect to headphones -// defaultPage.makeValueBinding( surfaceElements.faderMaster.fader.mSurfaceValue, defaultPage.mHostAccess.mControlRoom.getPhonesChannelByIndex(0).mLevelValue) - -// ? Would be nice to use the read and write buttons as read and write automation for selected track - but haven't figured out how to code that yet -defaultPage.makeValueBinding( surfaceElements.faderMaster.mixer_button.mSurfaceValue, defaultPage.mHostAccess.mTransport.mValue.mMetronomeActive).setTypeToggle() -defaultPage.makeValueBinding( surfaceElements.faderMaster.read_button.mSurfaceValue, defaultPage.mHostAccess.mControlRoom.mMainChannel.mDimActiveValue).setTypeToggle() -defaultPage.makeValueBinding( surfaceElements.faderMaster.write_button.mSurfaceValue, defaultPage.mHostAccess.mControlRoom.mMainChannel.mReferenceLevelEnabledValue).setTypeToggle() \ No newline at end of file +selectedTrackPage.mOnActivate = function (device) { + console.log('from script: Platform M+ page "Selected Track" activated') +} From 0b2fbbea01e08fac11be5928dcdc5cc1d28895a9 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sat, 28 May 2022 22:17:05 +1000 Subject: [PATCH 13/65] focus quick controls on selected Track --- icon/platformmplus/icon_platformmplus.js | 56 +++++++++++++----------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 716382f..9b65660 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -128,24 +128,35 @@ function makePageWithDefaults(name) { // Switch between Nudge and Scrub by tapping knob page.makeActionBinding(surfaceElements.transport.jog_wheel.mPushValue, jogSubPageArea.mAction.mNext) + var MasterFaderSubPageArea = page.makeSubPageArea('MasterFader') + var subPageMasterFaderMain = makeSubPage(MasterFaderSubPageArea, 'MF_MainOut') + var subPageMasterFaderHeadphone = makeSubPage(MasterFaderSubPageArea, 'MF_HeadphoneOut') + var subPageMasterCMain = makeSubPage(MasterFaderSubPageArea, 'MF_CMain') + var subPageMasterFaderValue = makeSubPage(MasterFaderSubPageArea, 'MF_ValueUnderCursor') + + // Master Fader + // If there is only One output it will be Main + // If there is more than one out then this will be the first one - there doesn't appear to be a way to verify this + var outputMixerBanks = page.mHostAccess.mMixConsole.makeMixerBankZone().includeOutputChannels() + var outputMixerBankChannels = outputMixerBanks.makeMixerBankChannel() + page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, outputMixerBankChannels.mValue.mVolume).setValueTakeOverModeJump().setSubPage(subPageMasterFaderMain) + page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, page.mHostAccess.mMouseCursor.mValueUnderMouse).setValueTakeOverModeJump().setSubPage(subPageMasterFaderValue) + page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, page.mHostAccess.mControlRoom.getPhonesChannelByIndex(0).mLevelValue).setValueTakeOverModeJump().setSubPage(subPageMasterFaderHeadphone) + page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, page.mHostAccess.mControlRoom.mMainChannel.mLevelValue).setValueTakeOverModeJump().setSubPage(subPageMasterCMain) + // Switch Master Fader to Main Out->Headphone->Value Under Cursor (AI) + page.makeActionBinding(surfaceElements.faderMaster.mixer_button.mSurfaceValue, MasterFaderSubPageArea.mAction.mNext) + return page } function makePageMixer() { var page = makePageWithDefaults('Mixer') - var FaderSubPageArea = page.makeSubPageArea('FadersKnobs') - var ButtonSubPageArea = page.makeSubPageArea('Buttons') - var MasterFaderSubPageArea = page.makeSubPageArea('MasterFader') - var subPageFaderVolume = makeSubPage(FaderSubPageArea, 'Volume') + var ButtonSubPageArea = page.makeSubPageArea('Buttons') var subPageButtonDefaultSet = makeSubPage(ButtonSubPageArea, 'DefaultSet') - var subPageMasterFaderMain = makeSubPage(MasterFaderSubPageArea, 'MF_MainOut') - var subPageMasterFaderHeadphone = makeSubPage(MasterFaderSubPageArea, 'MF_HeadphoneOut') - var subPageMasterCMain = makeSubPage(MasterFaderSubPageArea, 'MF_CMain') - var subPageMasterFaderValue = makeSubPage(MasterFaderSubPageArea, 'MF_ValueUnderCursor') var hostMixerBankZone = page.mHostAccess.mMixConsole.makeMixerBankZone() .excludeOutputChannels() @@ -176,20 +187,6 @@ function makePageMixer() { page.makeCommandBinding(surfaceElements.faderMaster.read_button.mSurfaceValue, 'Automation', 'Toggle Read Enable Selected Tracks') page.makeCommandBinding(surfaceElements.faderMaster.write_button.mSurfaceValue, 'Automation', 'Toggle Write Enable Selected Tracks') - // Master Fader - // If there is only One output it will be Main - // If there is more than one out then this will be the first one - there doesn't appear to be a way to verify this - var outputMixerBanks = page.mHostAccess.mMixConsole.makeMixerBankZone().includeOutputChannels() - var outputMixerBankChannels = outputMixerBanks.makeMixerBankChannel() - page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, outputMixerBankChannels.mValue.mVolume).setValueTakeOverModeJump().setSubPage(subPageMasterFaderMain) - page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, page.mHostAccess.mMouseCursor.mValueUnderMouse).setValueTakeOverModeJump().setSubPage(subPageMasterFaderValue) - page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, page.mHostAccess.mControlRoom.getPhonesChannelByIndex(0).mLevelValue).setValueTakeOverModeJump().setSubPage(subPageMasterFaderHeadphone) - page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, page.mHostAccess.mControlRoom.mMainChannel.mLevelValue).setValueTakeOverModeJump().setSubPage(subPageMasterCMain) - - - // Switch Master Fader to Main Out->Headphone->Value Under Cursor (AI) - page.makeActionBinding(surfaceElements.faderMaster.mixer_button.mSurfaceValue, MasterFaderSubPageArea.mAction.mNext) - return page } @@ -212,11 +209,20 @@ function makePageSelectedTrack() { var rec_buttonSurfaceValue = surfaceElements.channelControls[idx].rec_button.mSurfaceValue; page.makeValueBinding(knobSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mLevel) - page.makeValueBinding(sel_buttonSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mOn).setTypeToggle() - page.makeValueBinding(mute_buttonSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mPrePost).setTypeToggle() - page.makeValueBinding(faderSurfaceValue, selectedTrackChannel.mQuickControls.getByIndex(idx)).setValueTakeOverModeJump() + page.makeValueBinding(knobPushValue, selectedTrackChannel.mSends.getByIndex(idx).mOn).setTypeToggle() + page.makeValueBinding(faderSurfaceValue, page.mHostAccess.mFocusedQuickControls.getByIndex(idx)).setValueTakeOverModeJump() } + page.makeValueBinding(surfaceElements.channelControls[6].sel_button.mSurfaceValue, selectedTrackChannel.mValue.mEditorOpen).setTypeToggle() + page.makeValueBinding(surfaceElements.channelControls[6].mute_button.mSurfaceValue, selectedTrackChannel.mValue.mInstrumentOpen).setTypeToggle() + page.makeCommandBinding(surfaceElements.channelControls[6].solo_button.mSurfaceValue, 'Automation', 'Show Used Automation (Selected Tracks)') + page.makeCommandBinding(surfaceElements.channelControls[6].rec_button.mSurfaceValue, 'Automation', 'Hide Automation') + + page.makeValueBinding(surfaceElements.channelControls[7].sel_button.mSurfaceValue, selectedTrackChannel.mValue.mMonitorEnable).setTypeToggle() + page.makeValueBinding(surfaceElements.channelControls[7].mute_button.mSurfaceValue, selectedTrackChannel.mValue.mMute).setTypeToggle() + page.makeValueBinding(surfaceElements.channelControls[7].solo_button.mSurfaceValue, selectedTrackChannel.mValue.mSolo).setTypeToggle() + page.makeValueBinding(surfaceElements.channelControls[7].rec_button.mSurfaceValue, selectedTrackChannel.mValue.mRecordEnable).setTypeToggle() + return page } From 1473ed7c338134cf6ee5ec34bfba6e590ce3848f Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sat, 28 May 2022 22:19:16 +1000 Subject: [PATCH 14/65] Mixer Select track button is now monitor enable --- icon/platformmplus/icon_platformmplus.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 9b65660..61fa701 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -177,7 +177,7 @@ function makePageMixer() { page.makeValueBinding(knobSurfaceValue, hostMixerBankChannel.mValue.mPan).setSubPage(subPageFaderVolume) page.makeValueBinding(knobPushValue, hostMixerBankChannel.mValue.mEditorOpen).setTypeToggle().setSubPage(subPageFaderVolume) page.makeValueBinding(faderSurfaceValue, hostMixerBankChannel.mValue.mVolume).setValueTakeOverModeJump().setSubPage(subPageFaderVolume) - page.makeValueBinding(sel_buttonSurfaceValue, hostMixerBankChannel.mValue.mSelected).setTypeToggle().setValueTakeOverModeJump().setSubPage(subPageButtonDefaultSet) + page.makeValueBinding(sel_buttonSurfaceValue, hostMixerBankChannel.mValue.mMonitorEnable).setTypeToggle().setValueTakeOverModeJump().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(mute_buttonSurfaceValue, hostMixerBankChannel.mValue.mMute).setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(solo_buttonSurfaceValue, hostMixerBankChannel.mValue.mSolo).setTypeToggle().setSubPage(subPageButtonDefaultSet) From ca9cc31fb6b3fb82be588e5c449d78d3e5a88260 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 29 May 2022 14:23:27 +1000 Subject: [PATCH 15/65] Modify Transport area so it works consistently across pages --- icon/platformmplus/icon_elements.js | 76 ++++++++++++++---------- icon/platformmplus/icon_platformmplus.js | 35 +++++------ 2 files changed, 59 insertions(+), 52 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 50d8323..c18866e 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -141,13 +141,13 @@ function repeatCommand(activeDevice, command, repeats) { } } /** - * @param {MR_PushEncoder} pushEncoder + * @param {MR_SurfaceElementValue} pushEncoder * @param {MR_SurfaceCustomValueVariable} commandIncrease * @param {MR_SurfaceCustomValueVariable} commandDecrease */ function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { // console.log('from script: createCommandKnob') - pushEncoder.mEncoderValue.mOnProcessValueChange = function (activeDevice, value) { + pushEncoder.mOnProcessValueChange = function (activeDevice, value) { console.log('value changed: ' + value) if (value < 0.5) { var jump_rate = Math.floor(value * 127) @@ -159,45 +159,54 @@ function repeatCommand(activeDevice, command, repeats) { } } -function makeTransport(surface, x, y) { - var transport = {} +function Transport(surface, midiInput, midiOutput, x, y) { + this.surface = surface; + this.midiInput = midiInput; + this.midiOutput = midiOutput; + this.x = x; + this.y = y; + var w = 1 var h = 1 + this.ident = function () { + return ("Class Transport"); + } + function bindMidiNote(button, chn, num) { button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(chn, num) } - transport.prevChn = makeLedButton(surface, 48, x, y, w, h) - transport.nextChn = makeLedButton(surface, 49, x + 1, y, w, h) + this.prevChn = makeLedButton(surface, 48, x, y, w, h) + this.nextChn = makeLedButton(surface, 49, x + 1, y, w, h) // TODO Not implemented yet - not sure what to use them for // TODO Perhaps Change the Page in the midi remote?? - transport.prevBnk = makeLedButton(surface, 46, x, y + 1, w, h) + this.prevBnk = makeLedButton(surface, 46, x, y + 1, w, h) // TODO Not implemented yet - not sure what to use them for - transport.nextBnk = makeLedButton(surface, 47, x + 1, y + 1, w, h) + this.nextBnk = makeLedButton(surface, 47, x + 1, y + 1, w, h) - transport.btnRewind = makeLedButton(surface, 91, x, y + 2, w, h) - transport.btnForward = makeLedButton(surface, 92, x + 1, y + 2, w, h) + this.btnRewind = makeLedButton(surface, 91, x, y + 2, w, h) + this.btnForward = makeLedButton(surface, 92, x + 1, y + 2, w, h) - transport.btnStart = makeLedButton(surface, 94, x, y + 3, w, h) - transport.btnStop = makeLedButton(surface, 93, x + 1, y + 3, w, h) + this.btnStart = makeLedButton(surface, 94, x, y + 3, w, h) + this.btnStop = makeLedButton(surface, 93, x + 1, y + 3, w, h) - transport.btnRecord = makeLedButton(surface, 95, x, y + 4, w, h) - transport.btnCycle = makeLedButton(surface, 86, x + 1, y + 4, w, h) + this.btnRecord = makeLedButton(surface, 95, x, y + 4, w, h) + this.btnCycle = makeLedButton(surface, 86, x + 1, y + 4, w, h) // The Note on/off events for the special functioans are timestamped at the same time // cubase midi remote doesn't show anything on screen though a note is sent // Flip - Simultaneous press of Pre Chn+Pre Bank - transport.btnFlip = surface.makeButton(x + 3, y + 4, 1, 1) - bindMidiNote(transport.btnFlip, 0, 50) + this.btnFlip = surface.makeButton(x + 3, y + 4, 1, 1) + bindMidiNote(this.btnFlip, 0, 50) // Pressing the Zoom keys simultaneously will toggle on and off a note event. If on // either zoom button will send a Note 100 when zoom is activated or deactivated by either button // If zoom is active and you simply press then other button the event will not be sent // - transport.btnZoomOnOff = surface.makeButton(x + 4, y + 4, 1, 1) - bindMidiNote(transport.btnZoomOnOff, 0, 100) + this.btnZoomOnOff = surface.makeButton(x + 4, y + 4, 1, 1) + bindMidiNote(this.btnZoomOnOff, 0, 100) // The Jog wheel will change CC/Note based on which of thte Zoom buttons have been activated // None - CC 60 @@ -211,28 +220,31 @@ function makeTransport(surface, x, y) { // ? One weird side effect of this is the Knob displayed in Cubase will show its "value" in a weird way. // todo I wonder if there is a way to change that behaviour? - transport.jog_wheel = surface.makePushEncoder(x, y + 6, 2, 2) - transport.jog_wheel.mEncoderValue.mMidiBinding + this.jog_wheel = surface.makePushEncoder(x, y + 6, 2, 2) + this.jog_wheel.mEncoderValue.mMidiBinding .setInputPort(midiInput) .bindToControlChange(0, 60) .setTypeAbsolute() - transport.jog_wheel.mPushValue.mMidiBinding + this.jog_wheel.mPushValue.mMidiBinding .setInputPort(midiInput) .bindToNote(0, 101) + // ? This is still passing midi events through. It's unclear how to stop the midi CC messages passing through other then removing the MIDI port from All In + this.jogLeftVariable = surface.makeCustomValueVariable('jogLeft') + this.jogRightVariable = surface.makeCustomValueVariable('jogRight') + + bindCommandKnob(this.jog_wheel.mEncoderValue, this.jogRightVariable, this.jogLeftVariable); //Zoom Vertical - transport.zoomVertOut = surface.makeButton(x + 3, y + 6, 1, 1).setShapeCircle() - bindMidiNote(transport.zoomVertOut, 0, 96) - transport.zoomVertIn = surface.makeButton(x + 4, y + 6, 1, 1).setShapeCircle() - bindMidiNote(transport.zoomVertIn, 0, 97) + this.zoomVertOut = surface.makeButton(x + 3, y + 6, 1, 1).setShapeCircle() + bindMidiNote(this.zoomVertOut, 0, 96) + this.zoomVertIn = surface.makeButton(x + 4, y + 6, 1, 1).setShapeCircle() + bindMidiNote(this.zoomVertIn, 0, 97) //Zoom Horizontal - transport.zoomHorizOut = surface.makeButton(x + 3, y + 7, 1, 1).setShapeCircle() - bindMidiNote(transport.zoomHorizOut, 0, 98) - transport.zoomHorizIn = surface.makeButton(x + 4, y + 7, 1, 1).setShapeCircle() - bindMidiNote(transport.zoomHorizIn, 0, 99) - - return transport + this.zoomHorizOut = surface.makeButton(x + 3, y + 7, 1, 1).setShapeCircle() + bindMidiNote(this.zoomHorizOut, 0, 98) + this.zoomHorizIn = surface.makeButton(x + 4, y + 7, 1, 1).setShapeCircle() + bindMidiNote(this.zoomHorizIn, 0, 99) } module.exports = { @@ -240,6 +252,6 @@ module.exports = { masterControl, makeLedButton, makeTouchFader, - makeTransport, + Transport, bindCommandKnob } diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 61fa701..1230c28 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -7,7 +7,7 @@ var iconElements = require('./icon_elements.js') var channelControl = iconElements.channelControl var masterControl = iconElements.masterControl -var makeTransport = iconElements.makeTransport +var Transport = iconElements.Transport var bindCommandKnob = iconElements.bindCommandKnob //----------------------------------------------------------------------------- @@ -55,7 +55,7 @@ function makeSurfaceElements() { } surfaceElements.faderMaster = new masterControl(surface, midiInput, midiOutput, xKnobStrip + 1, yKnobStrip, surfaceElements.numStrips) - surfaceElements.transport = makeTransport(surface, xKnobStrip + 20, yKnobStrip + 3) + surfaceElements.transport = new Transport(surface, midiInput, midiOutput, xKnobStrip + 20, yKnobStrip + 3) return surfaceElements } @@ -114,17 +114,12 @@ function makePageWithDefaults(name) { page.makeActionBinding(surfaceElements.transport.btnZoomOnOff.mSurfaceValue, zoomSubPageArea.mAction.mNext) // Jog Pages - when Zoom lights are off - // ? This is still passing midi events through. It's unclear how to stop the midi CC messages passing through other then removing the MIDI port from All In - var jogLeftVariable = deviceDriver.mSurface.makeCustomValueVariable('jogLeft') - var jogRightVariable = deviceDriver.mSurface.makeCustomValueVariable('jogRight') - - bindCommandKnob(surfaceElements.transport.jog_wheel, jogRightVariable, jogLeftVariable); - // Nuge - page.makeCommandBinding(jogLeftVariable, 'Transport', 'Nudge Cursor Left').setSubPage(subPageJogNudge) - page.makeCommandBinding(jogRightVariable, 'Transport', 'Nudge Cursor Right').setSubPage(subPageJogNudge) + // Nuge + page.makeCommandBinding(surfaceElements.transport.jogLeftVariable, 'Transport', 'Nudge Cursor Left').setSubPage(subPageJogNudge) + page.makeCommandBinding(surfaceElements.transport.jogRightVariable, 'Transport', 'Nudge Cursor Right').setSubPage(subPageJogNudge) // Scrub (Jog in Cubase) - page.makeCommandBinding(jogLeftVariable, 'Transport', 'Jog Left').setSubPage(subPageJogScrub) - page.makeCommandBinding(jogRightVariable, 'Transport', 'Jog Right').setSubPage(subPageJogScrub) + page.makeCommandBinding(surfaceElements.transport.jogLeftVariable, 'Transport', 'Jog Left').setSubPage(subPageJogScrub) + page.makeCommandBinding(surfaceElements.transport.jogRightVariable, 'Transport', 'Jog Right').setSubPage(subPageJogScrub) // Switch between Nudge and Scrub by tapping knob page.makeActionBinding(surfaceElements.transport.jog_wheel.mPushValue, jogSubPageArea.mAction.mNext) @@ -146,6 +141,13 @@ function makePageWithDefaults(name) { // Switch Master Fader to Main Out->Headphone->Value Under Cursor (AI) page.makeActionBinding(surfaceElements.faderMaster.mixer_button.mSurfaceValue, MasterFaderSubPageArea.mAction.mNext) + // Automation for selected tracks + var selectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel + + // Automation for selected tracks + page.makeValueBinding(surfaceElements.faderMaster.read_button.mSurfaceValue, selectedTrackChannel.mValue.mAutomationRead).setTypeToggle() + page.makeValueBinding(surfaceElements.faderMaster.write_button.mSurfaceValue, selectedTrackChannel.mValue.mAutomationWrite).setTypeToggle() + return page } @@ -177,15 +179,11 @@ function makePageMixer() { page.makeValueBinding(knobSurfaceValue, hostMixerBankChannel.mValue.mPan).setSubPage(subPageFaderVolume) page.makeValueBinding(knobPushValue, hostMixerBankChannel.mValue.mEditorOpen).setTypeToggle().setSubPage(subPageFaderVolume) page.makeValueBinding(faderSurfaceValue, hostMixerBankChannel.mValue.mVolume).setValueTakeOverModeJump().setSubPage(subPageFaderVolume) - page.makeValueBinding(sel_buttonSurfaceValue, hostMixerBankChannel.mValue.mMonitorEnable).setTypeToggle().setValueTakeOverModeJump().setSubPage(subPageButtonDefaultSet) - + page.makeValueBinding(sel_buttonSurfaceValue, hostMixerBankChannel.mValue.mSelected).setTypeToggle().setValueTakeOverModeJump().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(mute_buttonSurfaceValue, hostMixerBankChannel.mValue.mMute).setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(solo_buttonSurfaceValue, hostMixerBankChannel.mValue.mSolo).setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(rec_buttonSurfaceValue, hostMixerBankChannel.mValue.mRecordEnable).setTypeToggle().setSubPage(subPageButtonDefaultSet) } - // Automation for selected tracks - page.makeCommandBinding(surfaceElements.faderMaster.read_button.mSurfaceValue, 'Automation', 'Toggle Read Enable Selected Tracks') - page.makeCommandBinding(surfaceElements.faderMaster.write_button.mSurfaceValue, 'Automation', 'Toggle Write Enable Selected Tracks') return page } @@ -195,9 +193,6 @@ function makePageSelectedTrack() { var selectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel - // Automation for selected tracks - page.makeValueBinding(surfaceElements.faderMaster.read_button.mSurfaceValue, selectedTrackChannel.mValue.mAutomationRead).setTypeToggle() - page.makeValueBinding(surfaceElements.faderMaster.write_button.mSurfaceValue, selectedTrackChannel.mValue.mAutomationWrite).setTypeToggle() for (var idx = 0; idx < 8; ++idx) { var knobSurfaceValue = surfaceElements.channelControls[idx].pushEncoder.mEncoderValue; From 1f7f8a211f83831bbe9b71d54de1a1304c4d0e57 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 29 May 2022 16:26:43 +1000 Subject: [PATCH 16/65] Debugging select and led failure cases - WIP --- icon/platformmplus/icon_elements.js | 97 ++++++++++++------------ icon/platformmplus/icon_platformmplus.js | 15 ++-- 2 files changed, 57 insertions(+), 55 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index c18866e..d7e4d65 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -9,16 +9,16 @@ * @param {number} h * */ - function makeLedButton(surface, note, x, y, w, h) { +function makeLedButton(surface, midiInput, midiOutput, note, x, y, w, h) { var button = surface.makeButton(x, y, w, h) button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, note) - button.mSurfaceValue.mOnProcessValueChange = (function (activeDevice, value) { - if (value > 0) - this.midiOutput.sendMidi(activeDevice, [0x90, note, 127]) - else { - this.midiOutput.sendMidi(activeDevice, [0x90, note, 0]) - } - }).bind({ midiOutput }) + button.mSurfaceValue.mOnProcessValueChange = function (activeDevice) { + if (button.mSurfaceValue.getProcessValue(activeDevice) > 0) + midiOutput.sendMidi(activeDevice, [0x90, note, 127]) + else { + midiOutput.sendMidi(activeDevice, [0x90, note, 0]) + } + } return button } @@ -44,7 +44,7 @@ function makeTouchFader(surface, midiInput, midiOutput, channel, x, y, w, h) { .setInputPort(midiInput) .bindToNote(0, 104 + channel) - return [fader,fader_touch] + return [fader, fader_touch] } /** @@ -91,10 +91,10 @@ function channelControl(surface, midiInput, midiOutput, x, y, instance) { this.fader_touch = tf[1] // Channel Buttons - this.sel_button = makeLedButton(surface, 24 + this.instance, fader_x + 1, fader_y + 4, 1, 1) - this.mute_button = makeLedButton(surface, 16 + this.instance, fader_x + 1, fader_y + 5, 1, 1) - this.solo_button = makeLedButton(surface, 8 + this.instance, fader_x + 1, fader_y + 6, 1, 1) - this.rec_button = makeLedButton(surface, 0 + this.instance, fader_x + 1, fader_y + 7, 1, 1) + this.sel_button = makeLedButton(surface, midiInput, midiOutput, 24 + this.instance, fader_x + 1, fader_y + 4, 1, 1) + this.mute_button = makeLedButton(surface, midiInput, midiOutput, 16 + this.instance, fader_x + 1, fader_y + 5, 1, 1) + this.solo_button = makeLedButton(surface, midiInput, midiOutput, 8 + this.instance, fader_x + 1, fader_y + 6, 1, 1) + this.rec_button = makeLedButton(surface, midiInput, midiOutput, 0 + this.instance, fader_x + 1, fader_y + 7, 1, 1) } @@ -108,7 +108,7 @@ function channelControl(surface, midiInput, midiOutput, x, y, instance) { * @param {Number} h - height of the push encoder. * @param {Number} instance - instance of the push encoder. */ - function masterControl(surface, midiInput, midiOutput, x, y, instance) { +function masterControl(surface, midiInput, midiOutput, x, y, instance) { // Position on GUI this.surface = surface; this.midiInput = midiInput; @@ -129,15 +129,18 @@ function channelControl(surface, midiInput, midiOutput, x, y, instance) { this.fader_touch = tf[1] // Channel Buttons - this.mixer_button = makeLedButton(surface, 84, fader_x + 1, fader_y + 4, 1, 1) - this.read_button = makeLedButton(surface, 74, fader_x + 1, fader_y + 5, 1, 1) - this.write_button = makeLedButton(surface, 75, fader_x + 1, fader_y + 6, 1, 1) + // this.mixer_button = makeLedButton(surface, midiInput, midiOutput, 84, fader_x + 1, fader_y + 4, 1, 1) + var mixer_button = surface.makeButton(fader_x + 1, fader_y + 4, 1, 1) + this.mixer_button = mixer_button + mixer_button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, 84) + this.read_button = makeLedButton(surface, midiInput, midiOutput, 74, fader_x + 1, fader_y + 5, 1, 1) + this.write_button = makeLedButton(surface, midiInput, midiOutput, 75, fader_x + 1, fader_y + 6, 1, 1) } function repeatCommand(activeDevice, command, repeats) { for (var i = 0; i < repeats; i++) { - command.setProcessValue(activeDevice, 1) + command.setProcessValue(activeDevice, 1) } } /** @@ -145,17 +148,17 @@ function repeatCommand(activeDevice, command, repeats) { * @param {MR_SurfaceCustomValueVariable} commandIncrease * @param {MR_SurfaceCustomValueVariable} commandDecrease */ - function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { +function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { // console.log('from script: createCommandKnob') pushEncoder.mOnProcessValueChange = function (activeDevice, value) { - console.log('value changed: ' + value) - if (value < 0.5) { - var jump_rate = Math.floor(value * 127) - repeatCommand(activeDevice, commandIncrease, jump_rate) - } else if (value > 0.5) { - var jump_rate = Math.floor((value - 0.5) * 127) - repeatCommand(activeDevice, commandDecrease, jump_rate) - } + console.log('value changed: ' + value) + if (value < 0.5) { + var jump_rate = Math.floor(value * 127) + repeatCommand(activeDevice, commandIncrease, jump_rate) + } else if (value > 0.5) { + var jump_rate = Math.floor((value - 0.5) * 127) + repeatCommand(activeDevice, commandDecrease, jump_rate) + } } } @@ -174,26 +177,26 @@ function Transport(surface, midiInput, midiOutput, x, y) { } function bindMidiNote(button, chn, num) { - button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(chn, num) + button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(chn, num) } - this.prevChn = makeLedButton(surface, 48, x, y, w, h) - this.nextChn = makeLedButton(surface, 49, x + 1, y, w, h) + this.prevChn = makeLedButton(surface, midiInput, midiOutput, 48, x, y, w, h) + this.nextChn = makeLedButton(surface, midiInput, midiOutput, 49, x + 1, y, w, h) // TODO Not implemented yet - not sure what to use them for // TODO Perhaps Change the Page in the midi remote?? - this.prevBnk = makeLedButton(surface, 46, x, y + 1, w, h) + this.prevBnk = makeLedButton(surface, midiInput, midiOutput, 46, x, y + 1, w, h) // TODO Not implemented yet - not sure what to use them for - this.nextBnk = makeLedButton(surface, 47, x + 1, y + 1, w, h) + this.nextBnk = makeLedButton(surface, midiInput, midiOutput, 47, x + 1, y + 1, w, h) - this.btnRewind = makeLedButton(surface, 91, x, y + 2, w, h) - this.btnForward = makeLedButton(surface, 92, x + 1, y + 2, w, h) + this.btnRewind = makeLedButton(surface, midiInput, midiOutput, 91, x, y + 2, w, h) + this.btnForward = makeLedButton(surface, midiInput, midiOutput, 92, x + 1, y + 2, w, h) - this.btnStart = makeLedButton(surface, 94, x, y + 3, w, h) - this.btnStop = makeLedButton(surface, 93, x + 1, y + 3, w, h) + this.btnStart = makeLedButton(surface, midiInput, midiOutput, 94, x, y + 3, w, h) + this.btnStop = makeLedButton(surface, midiInput, midiOutput, 93, x + 1, y + 3, w, h) - this.btnRecord = makeLedButton(surface, 95, x, y + 4, w, h) - this.btnCycle = makeLedButton(surface, 86, x + 1, y + 4, w, h) + this.btnRecord = makeLedButton(surface, midiInput, midiOutput, 95, x, y + 4, w, h) + this.btnCycle = makeLedButton(surface, midiInput, midiOutput, 86, x + 1, y + 4, w, h) // The Note on/off events for the special functioans are timestamped at the same time // cubase midi remote doesn't show anything on screen though a note is sent @@ -222,17 +225,17 @@ function Transport(surface, midiInput, midiOutput, x, y) { this.jog_wheel = surface.makePushEncoder(x, y + 6, 2, 2) this.jog_wheel.mEncoderValue.mMidiBinding - .setInputPort(midiInput) - .bindToControlChange(0, 60) - .setTypeAbsolute() + .setInputPort(midiInput) + .bindToControlChange(0, 60) + .setTypeAbsolute() this.jog_wheel.mPushValue.mMidiBinding - .setInputPort(midiInput) - .bindToNote(0, 101) - // ? This is still passing midi events through. It's unclear how to stop the midi CC messages passing through other then removing the MIDI port from All In - this.jogLeftVariable = surface.makeCustomValueVariable('jogLeft') - this.jogRightVariable = surface.makeCustomValueVariable('jogRight') + .setInputPort(midiInput) + .bindToNote(0, 101) + // ? This is still passing midi events through. It's unclear how to stop the midi CC messages passing through other then removing the MIDI port from All In + this.jogLeftVariable = surface.makeCustomValueVariable('jogLeft') + this.jogRightVariable = surface.makeCustomValueVariable('jogRight') - bindCommandKnob(this.jog_wheel.mEncoderValue, this.jogRightVariable, this.jogLeftVariable); + bindCommandKnob(this.jog_wheel.mEncoderValue, this.jogRightVariable, this.jogLeftVariable); //Zoom Vertical this.zoomVertOut = surface.makeButton(x + 3, y + 6, 1, 1).setShapeCircle() diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 1230c28..4f9a42e 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -8,7 +8,6 @@ var iconElements = require('./icon_elements.js') var channelControl = iconElements.channelControl var masterControl = iconElements.masterControl var Transport = iconElements.Transport -var bindCommandKnob = iconElements.bindCommandKnob //----------------------------------------------------------------------------- // 1. DRIVER SETUP - create driver object, midi ports and detection information @@ -24,6 +23,10 @@ var deviceDriver = midiremote_api.makeDeviceDriver('Icon', 'Platform Mplus', 'Bi var midiInput = deviceDriver.mPorts.makeMidiInput() var midiOutput = deviceDriver.mPorts.makeMidiOutput() +deviceDriver.mOnActivate = function (activeDevice) { + console.log('Icon Platform M+ Initialized'); +}; + // define all possible namings the devices MIDI ports could have // NOTE: Windows and MacOS handle port naming differently // deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput) @@ -164,7 +167,7 @@ function makePageMixer() { .excludeOutputChannels() .excludeInputChannels() - for (var channelIndex = 0; channelIndex < 8; ++channelIndex) { + for (var channelIndex = 0; channelIndex < surfaceElements.numStrips; ++channelIndex) { var hostMixerBankChannel = hostMixerBankZone.makeMixerBankChannel() var knobSurfaceValue = surfaceElements.channelControls[channelIndex].pushEncoder.mEncoderValue; @@ -179,7 +182,7 @@ function makePageMixer() { page.makeValueBinding(knobSurfaceValue, hostMixerBankChannel.mValue.mPan).setSubPage(subPageFaderVolume) page.makeValueBinding(knobPushValue, hostMixerBankChannel.mValue.mEditorOpen).setTypeToggle().setSubPage(subPageFaderVolume) page.makeValueBinding(faderSurfaceValue, hostMixerBankChannel.mValue.mVolume).setValueTakeOverModeJump().setSubPage(subPageFaderVolume) - page.makeValueBinding(sel_buttonSurfaceValue, hostMixerBankChannel.mValue.mSelected).setTypeToggle().setValueTakeOverModeJump().setSubPage(subPageButtonDefaultSet) + page.makeValueBinding(sel_buttonSurfaceValue, hostMixerBankChannel.mValue.mSelected).setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(mute_buttonSurfaceValue, hostMixerBankChannel.mValue.mMute).setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(solo_buttonSurfaceValue, hostMixerBankChannel.mValue.mSolo).setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(rec_buttonSurfaceValue, hostMixerBankChannel.mValue.mRecordEnable).setTypeToggle().setSubPage(subPageButtonDefaultSet) @@ -194,14 +197,10 @@ function makePageSelectedTrack() { var selectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel - for (var idx = 0; idx < 8; ++idx) { + for (var idx = 0; idx < surfaceElements.numStrips; ++idx) { var knobSurfaceValue = surfaceElements.channelControls[idx].pushEncoder.mEncoderValue; var knobPushValue = surfaceElements.channelControls[idx].pushEncoder.mPushValue; var faderSurfaceValue = surfaceElements.channelControls[idx].fader.mSurfaceValue; - var sel_buttonSurfaceValue = surfaceElements.channelControls[idx].sel_button.mSurfaceValue; - var mute_buttonSurfaceValue = surfaceElements.channelControls[idx].mute_button.mSurfaceValue; - var solo_buttonSurfaceValue = surfaceElements.channelControls[idx].solo_button.mSurfaceValue; - var rec_buttonSurfaceValue = surfaceElements.channelControls[idx].rec_button.mSurfaceValue; page.makeValueBinding(knobSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mLevel) page.makeValueBinding(knobPushValue, selectedTrackChannel.mSends.getByIndex(idx).mOn).setTypeToggle() From 92d836c2d9dd4c6bbcf191d94299a3f3f8c64347 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 29 May 2022 16:37:43 +1000 Subject: [PATCH 17/65] Still debugging --- icon/platformmplus/icon_platformmplus.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 4f9a42e..ebdf327 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -164,8 +164,8 @@ function makePageMixer() { var subPageButtonDefaultSet = makeSubPage(ButtonSubPageArea, 'DefaultSet') var hostMixerBankZone = page.mHostAccess.mMixConsole.makeMixerBankZone() - .excludeOutputChannels() - .excludeInputChannels() + .includeAudioChannels() + .includeInstrumentChannels() for (var channelIndex = 0; channelIndex < surfaceElements.numStrips; ++channelIndex) { var hostMixerBankChannel = hostMixerBankZone.makeMixerBankChannel() @@ -173,6 +173,7 @@ function makePageMixer() { var knobSurfaceValue = surfaceElements.channelControls[channelIndex].pushEncoder.mEncoderValue; var knobPushValue = surfaceElements.channelControls[channelIndex].pushEncoder.mPushValue; var faderSurfaceValue = surfaceElements.channelControls[channelIndex].fader.mSurfaceValue; + var faderTouchSurfaceValue = surfaceElements.channelControls[channelIndex].fader_touch.mSurfaceValue; var sel_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].sel_button.mSurfaceValue; var mute_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].mute_button.mSurfaceValue; var solo_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].solo_button.mSurfaceValue; @@ -182,7 +183,8 @@ function makePageMixer() { page.makeValueBinding(knobSurfaceValue, hostMixerBankChannel.mValue.mPan).setSubPage(subPageFaderVolume) page.makeValueBinding(knobPushValue, hostMixerBankChannel.mValue.mEditorOpen).setTypeToggle().setSubPage(subPageFaderVolume) page.makeValueBinding(faderSurfaceValue, hostMixerBankChannel.mValue.mVolume).setValueTakeOverModeJump().setSubPage(subPageFaderVolume) - page.makeValueBinding(sel_buttonSurfaceValue, hostMixerBankChannel.mValue.mSelected).setTypeToggle().setSubPage(subPageButtonDefaultSet) + page.makeValueBinding(faderTouchSurfaceValue, hostMixerBankChannel.mValue.mSelected).setValueTakeOverModeJump().setSubPage(subPageFaderVolume) + page.makeValueBinding(sel_buttonSurfaceValue, hostMixerBankChannel.mValue.mMonitorEnable).setTypeToggle().setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(mute_buttonSurfaceValue, hostMixerBankChannel.mValue.mMute).setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(solo_buttonSurfaceValue, hostMixerBankChannel.mValue.mSolo).setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(rec_buttonSurfaceValue, hostMixerBankChannel.mValue.mRecordEnable).setTypeToggle().setSubPage(subPageButtonDefaultSet) From d8fb1c1845c63376557662b1226fd599fdde13eb Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 29 May 2022 17:05:32 +1000 Subject: [PATCH 18/65] Cleaning code up in attempt to find script causing failure on first selection in page --- icon/platformmplus/icon_elements.js | 211 ++++++++++++----------- icon/platformmplus/icon_platformmplus.js | 18 +- 2 files changed, 115 insertions(+), 114 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index d7e4d65..c497c86 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -47,6 +47,31 @@ function makeTouchFader(surface, midiInput, midiOutput, channel, x, y, w, h) { return [fader, fader_touch] } +function repeatCommand(activeDevice, command, repeats) { + for (var i = 0; i < repeats; i++) { + command.setProcessValue(activeDevice, 1) + } +} + +/** + * @param {MR_SurfaceElementValue} pushEncoder + * @param {MR_SurfaceCustomValueVariable} commandIncrease + * @param {MR_SurfaceCustomValueVariable} commandDecrease + */ +function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { + // console.log('from script: createCommandKnob') + pushEncoder.mOnProcessValueChange = function (activeDevice, value) { + console.log('value changed: ' + value) + if (value < 0.5) { + var jump_rate = Math.floor(value * 127) + repeatCommand(activeDevice, commandIncrease, jump_rate) + } else if (value > 0.5) { + var jump_rate = Math.floor((value - 0.5) * 127) + repeatCommand(activeDevice, commandDecrease, jump_rate) + } + } +} + /** * @constructor * @param {MR_DeviceSurface} surface @@ -58,43 +83,41 @@ function makeTouchFader(surface, midiInput, midiOutput, channel, x, y, w, h) { * @param {Number} h - height of the push encoder. * @param {Number} instance - instance of the push encoder. */ -function channelControl(surface, midiInput, midiOutput, x, y, instance) { - // Position on GUI - this.surface = surface; - this.midiInput = midiInput; - this.midiOutput = midiOutput; - this.x = x + 2 * instance; - this.y = y; - this.instance = instance; // Channel number, 1-8 - - this.ident = function () { - return ("Class channelControl"); - } + function makeChannelControl(surface, midiInput, midiOutput, x, y, instance) { + var channelControl = {} + channelControl.surface = surface; + channelControl.midiInput = midiInput; + channelControl.midiOutput = midiOutput; + channelControl.x = x + 2 * instance; + channelControl.y = y; + channelControl.instance = instance; // Channel number, 1-8 // Pot encoder - this.pushEncoder = this.surface.makePushEncoder(this.x, y, 2, 2) + channelControl.pushEncoder = channelControl.surface.makePushEncoder(channelControl.x, y, 2, 2) - this.pushEncoder.mEncoderValue.mMidiBinding + channelControl.pushEncoder.mEncoderValue.mMidiBinding .setInputPort(midiInput) - .bindToControlChange(0, 16 + this.instance) + .bindToControlChange(0, 16 + channelControl.instance) .setTypeRelativeSignedBit(); - this.pushEncoder.mPushValue.mMidiBinding + channelControl.pushEncoder.mPushValue.mMidiBinding .setInputPort(midiInput) - .bindToNote(0, 32 + this.instance); + .bindToNote(0, 32 + channelControl.instance); // Fader + Fader Touch - var fader_x = this.x + var fader_x = channelControl.x var fader_y = y + 3 - var tf = makeTouchFader(surface, midiInput, this.midiOutput, instance, fader_x, fader_y, 1, 8) - this.fader = tf[0] - this.fader_touch = tf[1] + var tf = makeTouchFader(surface, midiInput, channelControl.midiOutput, instance, fader_x, fader_y, 1, 8) + channelControl.fader = tf[0] + channelControl.fader_touch = tf[1] // Channel Buttons - this.sel_button = makeLedButton(surface, midiInput, midiOutput, 24 + this.instance, fader_x + 1, fader_y + 4, 1, 1) - this.mute_button = makeLedButton(surface, midiInput, midiOutput, 16 + this.instance, fader_x + 1, fader_y + 5, 1, 1) - this.solo_button = makeLedButton(surface, midiInput, midiOutput, 8 + this.instance, fader_x + 1, fader_y + 6, 1, 1) - this.rec_button = makeLedButton(surface, midiInput, midiOutput, 0 + this.instance, fader_x + 1, fader_y + 7, 1, 1) + channelControl.sel_button = makeLedButton(surface, midiInput, midiOutput, 24 + channelControl.instance, fader_x + 1, fader_y + 4, 1, 1) + channelControl.mute_button = makeLedButton(surface, midiInput, midiOutput, 16 + channelControl.instance, fader_x + 1, fader_y + 5, 1, 1) + channelControl.solo_button = makeLedButton(surface, midiInput, midiOutput, 8 + channelControl.instance, fader_x + 1, fader_y + 6, 1, 1) + channelControl.rec_button = makeLedButton(surface, midiInput, midiOutput, 0 + channelControl.instance, fader_x + 1, fader_y + 7, 1, 1) + + return channelControl } @@ -108,71 +131,49 @@ function channelControl(surface, midiInput, midiOutput, x, y, instance) { * @param {Number} h - height of the push encoder. * @param {Number} instance - instance of the push encoder. */ -function masterControl(surface, midiInput, midiOutput, x, y, instance) { - // Position on GUI - this.surface = surface; - this.midiInput = midiInput; - this.midiOutput = midiOutput; - this.x = x + 2 * instance; - this.y = y; - this.instance = instance; // 9 - Master - - this.ident = function () { +function makeMasterControl(surface, midiInput, midiOutput, x, y, instance) { + var masterControl = {} + masterControl.surface = surface; + masterControl.midiInput = midiInput; + masterControl.midiOutput = midiOutput; + masterControl.x = x + 2 * instance; + masterControl.y = y; + masterControl.instance = instance; // 9 - Master + + masterControl.ident = function () { return ("Class masterControl"); } // Fader + Fader Touch - var fader_x = this.x + var fader_x = masterControl.x var fader_y = y + 3 var tf = makeTouchFader(surface, midiInput, midiOutput, instance, fader_x, fader_y, 1, 8) - this.fader = tf[0] - this.fader_touch = tf[1] + masterControl.fader = tf[0] + masterControl.fader_touch = tf[1] // Channel Buttons - // this.mixer_button = makeLedButton(surface, midiInput, midiOutput, 84, fader_x + 1, fader_y + 4, 1, 1) + // masterControl.mixer_button = makeLedButton(surface, midiInput, midiOutput, 84, fader_x + 1, fader_y + 4, 1, 1) var mixer_button = surface.makeButton(fader_x + 1, fader_y + 4, 1, 1) - this.mixer_button = mixer_button + masterControl.mixer_button = mixer_button mixer_button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, 84) - this.read_button = makeLedButton(surface, midiInput, midiOutput, 74, fader_x + 1, fader_y + 5, 1, 1) - this.write_button = makeLedButton(surface, midiInput, midiOutput, 75, fader_x + 1, fader_y + 6, 1, 1) - -} + masterControl.read_button = makeLedButton(surface, midiInput, midiOutput, 74, fader_x + 1, fader_y + 5, 1, 1) + masterControl.write_button = makeLedButton(surface, midiInput, midiOutput, 75, fader_x + 1, fader_y + 6, 1, 1) -function repeatCommand(activeDevice, command, repeats) { - for (var i = 0; i < repeats; i++) { - command.setProcessValue(activeDevice, 1) - } -} -/** - * @param {MR_SurfaceElementValue} pushEncoder - * @param {MR_SurfaceCustomValueVariable} commandIncrease - * @param {MR_SurfaceCustomValueVariable} commandDecrease - */ -function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { - // console.log('from script: createCommandKnob') - pushEncoder.mOnProcessValueChange = function (activeDevice, value) { - console.log('value changed: ' + value) - if (value < 0.5) { - var jump_rate = Math.floor(value * 127) - repeatCommand(activeDevice, commandIncrease, jump_rate) - } else if (value > 0.5) { - var jump_rate = Math.floor((value - 0.5) * 127) - repeatCommand(activeDevice, commandDecrease, jump_rate) - } - } + return masterControl } -function Transport(surface, midiInput, midiOutput, x, y) { - this.surface = surface; - this.midiInput = midiInput; - this.midiOutput = midiOutput; - this.x = x; - this.y = y; +function makeTransport(surface, midiInput, midiOutput, x, y) { + var transport = {} + transport.surface = surface; + transport.midiInput = midiInput; + transport.midiOutput = midiOutput; + transport.x = x; + transport.y = y; var w = 1 var h = 1 - this.ident = function () { + transport.ident = function () { return ("Class Transport"); } @@ -180,36 +181,36 @@ function Transport(surface, midiInput, midiOutput, x, y) { button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(chn, num) } - this.prevChn = makeLedButton(surface, midiInput, midiOutput, 48, x, y, w, h) - this.nextChn = makeLedButton(surface, midiInput, midiOutput, 49, x + 1, y, w, h) + transport.prevChn = makeLedButton(surface, midiInput, midiOutput, 48, x, y, w, h) + transport.nextChn = makeLedButton(surface, midiInput, midiOutput, 49, x + 1, y, w, h) // TODO Not implemented yet - not sure what to use them for // TODO Perhaps Change the Page in the midi remote?? - this.prevBnk = makeLedButton(surface, midiInput, midiOutput, 46, x, y + 1, w, h) + transport.prevBnk = makeLedButton(surface, midiInput, midiOutput, 46, x, y + 1, w, h) // TODO Not implemented yet - not sure what to use them for - this.nextBnk = makeLedButton(surface, midiInput, midiOutput, 47, x + 1, y + 1, w, h) + transport.nextBnk = makeLedButton(surface, midiInput, midiOutput, 47, x + 1, y + 1, w, h) - this.btnRewind = makeLedButton(surface, midiInput, midiOutput, 91, x, y + 2, w, h) - this.btnForward = makeLedButton(surface, midiInput, midiOutput, 92, x + 1, y + 2, w, h) + transport.btnRewind = makeLedButton(surface, midiInput, midiOutput, 91, x, y + 2, w, h) + transport.btnForward = makeLedButton(surface, midiInput, midiOutput, 92, x + 1, y + 2, w, h) - this.btnStart = makeLedButton(surface, midiInput, midiOutput, 94, x, y + 3, w, h) - this.btnStop = makeLedButton(surface, midiInput, midiOutput, 93, x + 1, y + 3, w, h) + transport.btnStart = makeLedButton(surface, midiInput, midiOutput, 94, x, y + 3, w, h) + transport.btnStop = makeLedButton(surface, midiInput, midiOutput, 93, x + 1, y + 3, w, h) - this.btnRecord = makeLedButton(surface, midiInput, midiOutput, 95, x, y + 4, w, h) - this.btnCycle = makeLedButton(surface, midiInput, midiOutput, 86, x + 1, y + 4, w, h) + transport.btnRecord = makeLedButton(surface, midiInput, midiOutput, 95, x, y + 4, w, h) + transport.btnCycle = makeLedButton(surface, midiInput, midiOutput, 86, x + 1, y + 4, w, h) // The Note on/off events for the special functioans are timestamped at the same time // cubase midi remote doesn't show anything on screen though a note is sent // Flip - Simultaneous press of Pre Chn+Pre Bank - this.btnFlip = surface.makeButton(x + 3, y + 4, 1, 1) - bindMidiNote(this.btnFlip, 0, 50) + transport.btnFlip = surface.makeButton(x + 3, y + 4, 1, 1) + bindMidiNote(transport.btnFlip, 0, 50) // Pressing the Zoom keys simultaneously will toggle on and off a note event. If on // either zoom button will send a Note 100 when zoom is activated or deactivated by either button // If zoom is active and you simply press then other button the event will not be sent // - this.btnZoomOnOff = surface.makeButton(x + 4, y + 4, 1, 1) - bindMidiNote(this.btnZoomOnOff, 0, 100) + transport.btnZoomOnOff = surface.makeButton(x + 4, y + 4, 1, 1) + bindMidiNote(transport.btnZoomOnOff, 0, 100) // The Jog wheel will change CC/Note based on which of thte Zoom buttons have been activated // None - CC 60 @@ -223,38 +224,40 @@ function Transport(surface, midiInput, midiOutput, x, y) { // ? One weird side effect of this is the Knob displayed in Cubase will show its "value" in a weird way. // todo I wonder if there is a way to change that behaviour? - this.jog_wheel = surface.makePushEncoder(x, y + 6, 2, 2) - this.jog_wheel.mEncoderValue.mMidiBinding + transport.jog_wheel = surface.makePushEncoder(x, y + 6, 2, 2) + transport.jog_wheel.mEncoderValue.mMidiBinding .setInputPort(midiInput) .bindToControlChange(0, 60) .setTypeAbsolute() - this.jog_wheel.mPushValue.mMidiBinding + transport.jog_wheel.mPushValue.mMidiBinding .setInputPort(midiInput) .bindToNote(0, 101) // ? This is still passing midi events through. It's unclear how to stop the midi CC messages passing through other then removing the MIDI port from All In - this.jogLeftVariable = surface.makeCustomValueVariable('jogLeft') - this.jogRightVariable = surface.makeCustomValueVariable('jogRight') + transport.jogLeftVariable = surface.makeCustomValueVariable('jogLeft') + transport.jogRightVariable = surface.makeCustomValueVariable('jogRight') - bindCommandKnob(this.jog_wheel.mEncoderValue, this.jogRightVariable, this.jogLeftVariable); + bindCommandKnob(transport.jog_wheel.mEncoderValue, transport.jogRightVariable, transport.jogLeftVariable); //Zoom Vertical - this.zoomVertOut = surface.makeButton(x + 3, y + 6, 1, 1).setShapeCircle() - bindMidiNote(this.zoomVertOut, 0, 96) - this.zoomVertIn = surface.makeButton(x + 4, y + 6, 1, 1).setShapeCircle() - bindMidiNote(this.zoomVertIn, 0, 97) + transport.zoomVertOut = surface.makeButton(x + 3, y + 6, 1, 1).setShapeCircle() + bindMidiNote(transport.zoomVertOut, 0, 96) + transport.zoomVertIn = surface.makeButton(x + 4, y + 6, 1, 1).setShapeCircle() + bindMidiNote(transport.zoomVertIn, 0, 97) //Zoom Horizontal - this.zoomHorizOut = surface.makeButton(x + 3, y + 7, 1, 1).setShapeCircle() - bindMidiNote(this.zoomHorizOut, 0, 98) - this.zoomHorizIn = surface.makeButton(x + 4, y + 7, 1, 1).setShapeCircle() - bindMidiNote(this.zoomHorizIn, 0, 99) + transport.zoomHorizOut = surface.makeButton(x + 3, y + 7, 1, 1).setShapeCircle() + bindMidiNote(transport.zoomHorizOut, 0, 98) + transport.zoomHorizIn = surface.makeButton(x + 4, y + 7, 1, 1).setShapeCircle() + bindMidiNote(transport.zoomHorizIn, 0, 99) + + return transport } module.exports = { - channelControl, - masterControl, + makeChannelControl, + makeMasterControl, + makeTransport, makeLedButton, makeTouchFader, - Transport, bindCommandKnob } diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index ebdf327..5d0eb17 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -5,9 +5,9 @@ // - Mackie C4 by Ron Garrison https://github.com/rwgarrison/midiremote-userscripts var iconElements = require('./icon_elements.js') -var channelControl = iconElements.channelControl -var masterControl = iconElements.masterControl -var Transport = iconElements.Transport +var makeChannelControl = iconElements.makeChannelControl +var makeMasterControl = iconElements.makeMasterControl +var makeTransport = iconElements.makeTransport //----------------------------------------------------------------------------- // 1. DRIVER SETUP - create driver object, midi ports and detection information @@ -54,11 +54,11 @@ function makeSurfaceElements() { var yKnobStrip = 0 for (var i = 0; i < surfaceElements.numStrips; ++i) { - surfaceElements.channelControls[i] = new channelControl(surface, midiInput, midiOutput, xKnobStrip, yKnobStrip, i) + surfaceElements.channelControls[i] = makeChannelControl(surface, midiInput, midiOutput, xKnobStrip, yKnobStrip, i) } - surfaceElements.faderMaster = new masterControl(surface, midiInput, midiOutput, xKnobStrip + 1, yKnobStrip, surfaceElements.numStrips) - surfaceElements.transport = new Transport(surface, midiInput, midiOutput, xKnobStrip + 20, yKnobStrip + 3) + surfaceElements.faderMaster = makeMasterControl(surface, midiInput, midiOutput, xKnobStrip + 1, yKnobStrip, surfaceElements.numStrips) + surfaceElements.transport = makeTransport(surface, midiInput, midiOutput, xKnobStrip + 20, yKnobStrip + 3) return surfaceElements } @@ -181,10 +181,9 @@ function makePageMixer() { // FaderKnobs - Volume, Pan, Editor Open page.makeValueBinding(knobSurfaceValue, hostMixerBankChannel.mValue.mPan).setSubPage(subPageFaderVolume) - page.makeValueBinding(knobPushValue, hostMixerBankChannel.mValue.mEditorOpen).setTypeToggle().setSubPage(subPageFaderVolume) + page.makeValueBinding(knobPushValue, hostMixerBankChannel.mValue.mMonitorEnable).setTypeToggle().setSubPage(subPageFaderVolume) page.makeValueBinding(faderSurfaceValue, hostMixerBankChannel.mValue.mVolume).setValueTakeOverModeJump().setSubPage(subPageFaderVolume) - page.makeValueBinding(faderTouchSurfaceValue, hostMixerBankChannel.mValue.mSelected).setValueTakeOverModeJump().setSubPage(subPageFaderVolume) - page.makeValueBinding(sel_buttonSurfaceValue, hostMixerBankChannel.mValue.mMonitorEnable).setTypeToggle().setTypeToggle().setSubPage(subPageButtonDefaultSet) + // page.makeValueBinding(sel_buttonSurfaceValue, hostMixerBankChannel.mValue.mSelected).setTypeToggle().setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(mute_buttonSurfaceValue, hostMixerBankChannel.mValue.mMute).setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(solo_buttonSurfaceValue, hostMixerBankChannel.mValue.mSolo).setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(rec_buttonSurfaceValue, hostMixerBankChannel.mValue.mRecordEnable).setTypeToggle().setSubPage(subPageButtonDefaultSet) @@ -198,7 +197,6 @@ function makePageSelectedTrack() { var selectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel - for (var idx = 0; idx < surfaceElements.numStrips; ++idx) { var knobSurfaceValue = surfaceElements.channelControls[idx].pushEncoder.mEncoderValue; var knobPushValue = surfaceElements.channelControls[idx].pushEncoder.mPushValue; From d065764460c84d440154ce9ba65056dc0aaef3bc Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Mon, 30 May 2022 17:29:01 +1000 Subject: [PATCH 19/65] Humph, still debugging selected track --- icon/platformmplus/icon_elements.js | 15 ++++----------- icon/platformmplus/icon_platformmplus.js | 4 ++-- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index c497c86..c9fc4db 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -73,7 +73,6 @@ function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { } /** - * @constructor * @param {MR_DeviceSurface} surface * @param {MR_DeviceMidiInput} midiInput * @param {MR_DeviceMidiOutput} midiOutput @@ -96,12 +95,12 @@ function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { channelControl.pushEncoder = channelControl.surface.makePushEncoder(channelControl.x, y, 2, 2) channelControl.pushEncoder.mEncoderValue.mMidiBinding - .setInputPort(midiInput) + .setInputPort(midiInput).setOutputPort(midiOutput) .bindToControlChange(0, 16 + channelControl.instance) - .setTypeRelativeSignedBit(); + .setTypeRelativeSignedBit() channelControl.pushEncoder.mPushValue.mMidiBinding - .setInputPort(midiInput) + .setInputPort(midiInput).setOutputPort(midiOutput) .bindToNote(0, 32 + channelControl.instance); // Fader + Fader Touch @@ -152,10 +151,7 @@ function makeMasterControl(surface, midiInput, midiOutput, x, y, instance) { masterControl.fader_touch = tf[1] // Channel Buttons - // masterControl.mixer_button = makeLedButton(surface, midiInput, midiOutput, 84, fader_x + 1, fader_y + 4, 1, 1) - var mixer_button = surface.makeButton(fader_x + 1, fader_y + 4, 1, 1) - masterControl.mixer_button = mixer_button - mixer_button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, 84) + masterControl.mixer_button = makeLedButton(surface, midiInput, midiOutput, 84, fader_x + 1, fader_y + 4, 1, 1) masterControl.read_button = makeLedButton(surface, midiInput, midiOutput, 74, fader_x + 1, fader_y + 5, 1, 1) masterControl.write_button = makeLedButton(surface, midiInput, midiOutput, 75, fader_x + 1, fader_y + 6, 1, 1) @@ -184,10 +180,7 @@ function makeTransport(surface, midiInput, midiOutput, x, y) { transport.prevChn = makeLedButton(surface, midiInput, midiOutput, 48, x, y, w, h) transport.nextChn = makeLedButton(surface, midiInput, midiOutput, 49, x + 1, y, w, h) - // TODO Not implemented yet - not sure what to use them for - // TODO Perhaps Change the Page in the midi remote?? transport.prevBnk = makeLedButton(surface, midiInput, midiOutput, 46, x, y + 1, w, h) - // TODO Not implemented yet - not sure what to use them for transport.nextBnk = makeLedButton(surface, midiInput, midiOutput, 47, x + 1, y + 1, w, h) transport.btnRewind = makeLedButton(surface, midiInput, midiOutput, 91, x, y + 2, w, h) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 5d0eb17..bab8c87 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -183,7 +183,7 @@ function makePageMixer() { page.makeValueBinding(knobSurfaceValue, hostMixerBankChannel.mValue.mPan).setSubPage(subPageFaderVolume) page.makeValueBinding(knobPushValue, hostMixerBankChannel.mValue.mMonitorEnable).setTypeToggle().setSubPage(subPageFaderVolume) page.makeValueBinding(faderSurfaceValue, hostMixerBankChannel.mValue.mVolume).setValueTakeOverModeJump().setSubPage(subPageFaderVolume) - // page.makeValueBinding(sel_buttonSurfaceValue, hostMixerBankChannel.mValue.mSelected).setTypeToggle().setTypeToggle().setSubPage(subPageButtonDefaultSet) + page.makeValueBinding(sel_buttonSurfaceValue, hostMixerBankChannel.mValue.mSelected).setTypeToggle().setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(mute_buttonSurfaceValue, hostMixerBankChannel.mValue.mMute).setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(solo_buttonSurfaceValue, hostMixerBankChannel.mValue.mSolo).setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(rec_buttonSurfaceValue, hostMixerBankChannel.mValue.mRecordEnable).setTypeToggle().setSubPage(subPageButtonDefaultSet) @@ -193,7 +193,7 @@ function makePageMixer() { } function makePageSelectedTrack() { - var page = makePageWithDefaults('Selected Track') + var page = makePageWithDefaults('Selected Channel') var selectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel From 88cc956cfc902cb24417b18348ed057d5a1261eb Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Tue, 31 May 2022 19:15:49 +1000 Subject: [PATCH 20/65] Add isConsuming to jog wheel - even though it makes no difference --- icon/platformmplus/icon_elements.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index c9fc4db..9c5fadc 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -95,12 +95,12 @@ function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { channelControl.pushEncoder = channelControl.surface.makePushEncoder(channelControl.x, y, 2, 2) channelControl.pushEncoder.mEncoderValue.mMidiBinding - .setInputPort(midiInput).setOutputPort(midiOutput) + .setInputPort(midiInput) .bindToControlChange(0, 16 + channelControl.instance) .setTypeRelativeSignedBit() channelControl.pushEncoder.mPushValue.mMidiBinding - .setInputPort(midiInput).setOutputPort(midiOutput) + .setInputPort(midiInput) .bindToNote(0, 32 + channelControl.instance); // Fader + Fader Touch @@ -186,8 +186,8 @@ function makeTransport(surface, midiInput, midiOutput, x, y) { transport.btnRewind = makeLedButton(surface, midiInput, midiOutput, 91, x, y + 2, w, h) transport.btnForward = makeLedButton(surface, midiInput, midiOutput, 92, x + 1, y + 2, w, h) - transport.btnStart = makeLedButton(surface, midiInput, midiOutput, 94, x, y + 3, w, h) transport.btnStop = makeLedButton(surface, midiInput, midiOutput, 93, x + 1, y + 3, w, h) + transport.btnStart = makeLedButton(surface, midiInput, midiOutput, 94, x, y + 3, w, h) transport.btnRecord = makeLedButton(surface, midiInput, midiOutput, 95, x, y + 4, w, h) transport.btnCycle = makeLedButton(surface, midiInput, midiOutput, 86, x + 1, y + 4, w, h) @@ -220,6 +220,7 @@ function makeTransport(surface, midiInput, midiOutput, x, y) { transport.jog_wheel = surface.makePushEncoder(x, y + 6, 2, 2) transport.jog_wheel.mEncoderValue.mMidiBinding .setInputPort(midiInput) + .setIsConsuming(true) .bindToControlChange(0, 60) .setTypeAbsolute() transport.jog_wheel.mPushValue.mMidiBinding From f54c9d2a44eee017fedb11d6a00e2365b5730fb3 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Tue, 31 May 2022 19:52:15 +1000 Subject: [PATCH 21/65] Cosmetic tweaks - rec button is round --- icon/platformmplus/icon_elements.js | 41 ++++++++++++++++------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 9c5fadc..dabb569 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -7,11 +7,14 @@ * @param {number} y * @param {number} w * @param {number} h - * + * @param {boolean} circle */ -function makeLedButton(surface, midiInput, midiOutput, note, x, y, w, h) { +function makeLedButton(surface, midiInput, midiOutput, note, x, y, w, h, circle) { var button = surface.makeButton(x, y, w, h) button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, note) + if (circle) { + button.setShapeCircle() + } button.mSurfaceValue.mOnProcessValueChange = function (activeDevice) { if (button.mSurfaceValue.getProcessValue(activeDevice) > 0) midiOutput.sendMidi(activeDevice, [0x90, note, 127]) @@ -111,10 +114,10 @@ function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { channelControl.fader_touch = tf[1] // Channel Buttons - channelControl.sel_button = makeLedButton(surface, midiInput, midiOutput, 24 + channelControl.instance, fader_x + 1, fader_y + 4, 1, 1) - channelControl.mute_button = makeLedButton(surface, midiInput, midiOutput, 16 + channelControl.instance, fader_x + 1, fader_y + 5, 1, 1) - channelControl.solo_button = makeLedButton(surface, midiInput, midiOutput, 8 + channelControl.instance, fader_x + 1, fader_y + 6, 1, 1) - channelControl.rec_button = makeLedButton(surface, midiInput, midiOutput, 0 + channelControl.instance, fader_x + 1, fader_y + 7, 1, 1) + channelControl.sel_button = makeLedButton(surface, midiInput, midiOutput, 24 + channelControl.instance, fader_x + 1, fader_y + 4, 1, 1, false) + channelControl.mute_button = makeLedButton(surface, midiInput, midiOutput, 16 + channelControl.instance, fader_x + 1, fader_y + 5, 1, 1, false) + channelControl.solo_button = makeLedButton(surface, midiInput, midiOutput, 8 + channelControl.instance, fader_x + 1, fader_y + 6, 1, 1, false) + channelControl.rec_button = makeLedButton(surface, midiInput, midiOutput, 0 + channelControl.instance, fader_x + 1, fader_y + 7, 1, 1, true) return channelControl @@ -151,9 +154,9 @@ function makeMasterControl(surface, midiInput, midiOutput, x, y, instance) { masterControl.fader_touch = tf[1] // Channel Buttons - masterControl.mixer_button = makeLedButton(surface, midiInput, midiOutput, 84, fader_x + 1, fader_y + 4, 1, 1) - masterControl.read_button = makeLedButton(surface, midiInput, midiOutput, 74, fader_x + 1, fader_y + 5, 1, 1) - masterControl.write_button = makeLedButton(surface, midiInput, midiOutput, 75, fader_x + 1, fader_y + 6, 1, 1) + masterControl.mixer_button = makeLedButton(surface, midiInput, midiOutput, 84, fader_x + 1, fader_y + 4, 1, 1, false) + masterControl.read_button = makeLedButton(surface, midiInput, midiOutput, 74, fader_x + 1, fader_y + 5, 1, 1, false) + masterControl.write_button = makeLedButton(surface, midiInput, midiOutput, 75, fader_x + 1, fader_y + 6, 1, 1, false) return masterControl } @@ -177,20 +180,20 @@ function makeTransport(surface, midiInput, midiOutput, x, y) { button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(chn, num) } - transport.prevChn = makeLedButton(surface, midiInput, midiOutput, 48, x, y, w, h) - transport.nextChn = makeLedButton(surface, midiInput, midiOutput, 49, x + 1, y, w, h) + transport.prevChn = makeLedButton(surface, midiInput, midiOutput, 48, x, y, w, h, false) + transport.nextChn = makeLedButton(surface, midiInput, midiOutput, 49, x + 1, y, w, h, false) - transport.prevBnk = makeLedButton(surface, midiInput, midiOutput, 46, x, y + 1, w, h) - transport.nextBnk = makeLedButton(surface, midiInput, midiOutput, 47, x + 1, y + 1, w, h) + transport.prevBnk = makeLedButton(surface, midiInput, midiOutput, 46, x, y + 1, w, h, false) + transport.nextBnk = makeLedButton(surface, midiInput, midiOutput, 47, x + 1, y + 1, w, h, false) - transport.btnRewind = makeLedButton(surface, midiInput, midiOutput, 91, x, y + 2, w, h) - transport.btnForward = makeLedButton(surface, midiInput, midiOutput, 92, x + 1, y + 2, w, h) + transport.btnRewind = makeLedButton(surface, midiInput, midiOutput, 91, x, y + 2, w, h, false) + transport.btnForward = makeLedButton(surface, midiInput, midiOutput, 92, x + 1, y + 2, w, h, false) - transport.btnStop = makeLedButton(surface, midiInput, midiOutput, 93, x + 1, y + 3, w, h) - transport.btnStart = makeLedButton(surface, midiInput, midiOutput, 94, x, y + 3, w, h) + transport.btnStop = makeLedButton(surface, midiInput, midiOutput, 93, x + 1, y + 3, w, h, false) + transport.btnStart = makeLedButton(surface, midiInput, midiOutput, 94, x, y + 3, w, h, false) - transport.btnRecord = makeLedButton(surface, midiInput, midiOutput, 95, x, y + 4, w, h) - transport.btnCycle = makeLedButton(surface, midiInput, midiOutput, 86, x + 1, y + 4, w, h) + transport.btnRecord = makeLedButton(surface, midiInput, midiOutput, 95, x, y + 4, w, h, false) + transport.btnCycle = makeLedButton(surface, midiInput, midiOutput, 86, x + 1, y + 4, w, h, false) // The Note on/off events for the special functioans are timestamped at the same time // cubase midi remote doesn't show anything on screen though a note is sent From 54da386ca6d363689cf27189fed87a7f238a3b55 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Tue, 31 May 2022 19:54:33 +1000 Subject: [PATCH 22/65] Now the selection issue is seemingly a bug in the midi remote api change the button usage: - touch a fader is select track - Sel button is now Monitor Enable - Push a Pan encoder and it will open Channel Settings Window - and it might even be programmed to shift to a suitable page to edit it but I don't know yet. --- icon/platformmplus/icon_platformmplus.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index bab8c87..ae736dc 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -181,9 +181,10 @@ function makePageMixer() { // FaderKnobs - Volume, Pan, Editor Open page.makeValueBinding(knobSurfaceValue, hostMixerBankChannel.mValue.mPan).setSubPage(subPageFaderVolume) - page.makeValueBinding(knobPushValue, hostMixerBankChannel.mValue.mMonitorEnable).setTypeToggle().setSubPage(subPageFaderVolume) + page.makeValueBinding(knobPushValue, hostMixerBankChannel.mValue.mEditorOpen).setTypeToggle().setSubPage(subPageFaderVolume) page.makeValueBinding(faderSurfaceValue, hostMixerBankChannel.mValue.mVolume).setValueTakeOverModeJump().setSubPage(subPageFaderVolume) - page.makeValueBinding(sel_buttonSurfaceValue, hostMixerBankChannel.mValue.mSelected).setTypeToggle().setTypeToggle().setSubPage(subPageButtonDefaultSet) + page.makeValueBinding(faderTouchSurfaceValue, hostMixerBankChannel.mValue.mSelected).setTypeToggle().setSubPage(subPageFaderVolume) + page.makeValueBinding(sel_buttonSurfaceValue, hostMixerBankChannel.mValue.mMonitorEnable).setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(mute_buttonSurfaceValue, hostMixerBankChannel.mValue.mMute).setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(solo_buttonSurfaceValue, hostMixerBankChannel.mValue.mSolo).setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(rec_buttonSurfaceValue, hostMixerBankChannel.mValue.mRecordEnable).setTypeToggle().setSubPage(subPageButtonDefaultSet) From 9153d18328524c1b113abb00e64ec214ca64092f Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Tue, 31 May 2022 20:21:56 +1000 Subject: [PATCH 23/65] Clear all Leds when activating pages so that no lit leds linger if they are not bound on a page --- icon/platformmplus/icon_elements.js | 30 +++++++++++++++++++++++- icon/platformmplus/icon_platformmplus.js | 6 ++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index dabb569..20ade6a 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -25,6 +25,33 @@ function makeLedButton(surface, midiInput, midiOutput, note, x, y, w, h, circle) return button } +function clearAllLeds(activeDevice, midiOutput) { + console.log('Clear All Leds') + // Mixer buttons + for (var i = 0; i < 8; ++i) { + midiOutput.sendMidi(activeDevice, [0x90, 24 + i, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 16 + i, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 8 + i, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 0 + i, 0]) + } + // Master Fader buttons + midiOutput.sendMidi(activeDevice, [0x90, 84, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 74, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 75, 0]) + + // Transport Buttons + midiOutput.sendMidi(activeDevice, [0x90, 48, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 49, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 46, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 47, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 91, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 92, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 93, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 94, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 95, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 86, 0]) +} + /** * @param {MR_DeviceSurface} surface * @param {MR_DeviceMidiInput} midiInput @@ -256,5 +283,6 @@ module.exports = { makeTransport, makeLedButton, makeTouchFader, - bindCommandKnob + bindCommandKnob, + clearAllLeds } diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index ae736dc..e50aa3c 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -8,6 +8,7 @@ var iconElements = require('./icon_elements.js') var makeChannelControl = iconElements.makeChannelControl var makeMasterControl = iconElements.makeMasterControl var makeTransport = iconElements.makeTransport +var clearAllLeds = iconElements.clearAllLeds //----------------------------------------------------------------------------- // 1. DRIVER SETUP - create driver object, midi ports and detection information @@ -24,7 +25,8 @@ var midiInput = deviceDriver.mPorts.makeMidiInput() var midiOutput = deviceDriver.mPorts.makeMidiOutput() deviceDriver.mOnActivate = function (activeDevice) { - console.log('Icon Platform M+ Initialized'); + console.log('Icon Platform M+ Activated'); + clearAllLeds(activeDevice, midiOutput) }; // define all possible namings the devices MIDI ports could have @@ -227,8 +229,10 @@ var selectedTrackPage = makePageSelectedTrack() mixerPage.mOnActivate = function (device) { console.log('from script: Platform M+ page "Mixer" activated') + clearAllLeds(device, midiOutput) } selectedTrackPage.mOnActivate = function (device) { console.log('from script: Platform M+ page "Selected Track" activated') + clearAllLeds(device, midiOutput) } From d2ee038173ec902ebefdb41963d07169def7a8c8 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Tue, 31 May 2022 20:49:21 +1000 Subject: [PATCH 24/65] Selected Channel updates - still not sure on design of this. So far have Send and Focus QC. and EQ1-4 on/off. plus basic channel controls for mute solo etc. --- icon/platformmplus/icon_platformmplus.js | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index e50aa3c..46315d8 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -208,16 +208,26 @@ function makePageSelectedTrack() { page.makeValueBinding(knobSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mLevel) page.makeValueBinding(knobPushValue, selectedTrackChannel.mSends.getByIndex(idx).mOn).setTypeToggle() page.makeValueBinding(faderSurfaceValue, page.mHostAccess.mFocusedQuickControls.getByIndex(idx)).setValueTakeOverModeJump() + + //page.makeValueBinding(surfaceElements.channelControls[idx].sel_button.mSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mOn).setTypeToggle() + page.makeValueBinding(surfaceElements.channelControls[idx].mute_button.mSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mPrePost).setTypeToggle() + //page.makeValueBinding(surfaceElements.channelControls[idx].solo_button.mSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mOn).setTypeToggle() } - page.makeValueBinding(surfaceElements.channelControls[6].sel_button.mSurfaceValue, selectedTrackChannel.mValue.mEditorOpen).setTypeToggle() - page.makeValueBinding(surfaceElements.channelControls[6].mute_button.mSurfaceValue, selectedTrackChannel.mValue.mInstrumentOpen).setTypeToggle() - page.makeCommandBinding(surfaceElements.channelControls[6].solo_button.mSurfaceValue, 'Automation', 'Show Used Automation (Selected Tracks)') - page.makeCommandBinding(surfaceElements.channelControls[6].rec_button.mSurfaceValue, 'Automation', 'Hide Automation') + page.makeValueBinding(surfaceElements.channelControls[0].solo_button.mSurfaceValue, selectedTrackChannel.mChannelEQ.mBand1.mOn).setTypeToggle() + page.makeValueBinding(surfaceElements.channelControls[1].solo_button.mSurfaceValue, selectedTrackChannel.mChannelEQ.mBand2.mOn).setTypeToggle() + page.makeValueBinding(surfaceElements.channelControls[2].solo_button.mSurfaceValue, selectedTrackChannel.mChannelEQ.mBand3.mOn).setTypeToggle() + page.makeValueBinding(surfaceElements.channelControls[3].solo_button.mSurfaceValue, selectedTrackChannel.mChannelEQ.mBand4.mOn).setTypeToggle() + + + page.makeCommandBinding(surfaceElements.channelControls[4].solo_button.mSurfaceValue, 'Automation', 'Show Used Automation (Selected Tracks)') + page.makeCommandBinding(surfaceElements.channelControls[5].solo_button.mSurfaceValue, 'Automation', 'Hide Automation') + page.makeValueBinding(surfaceElements.channelControls[6].solo_button.mSurfaceValue, selectedTrackChannel.mValue.mEditorOpen).setTypeToggle() + page.makeValueBinding(surfaceElements.channelControls[7].solo_button.mSurfaceValue, selectedTrackChannel.mValue.mInstrumentOpen).setTypeToggle() - page.makeValueBinding(surfaceElements.channelControls[7].sel_button.mSurfaceValue, selectedTrackChannel.mValue.mMonitorEnable).setTypeToggle() - page.makeValueBinding(surfaceElements.channelControls[7].mute_button.mSurfaceValue, selectedTrackChannel.mValue.mMute).setTypeToggle() - page.makeValueBinding(surfaceElements.channelControls[7].solo_button.mSurfaceValue, selectedTrackChannel.mValue.mSolo).setTypeToggle() + page.makeValueBinding(surfaceElements.channelControls[4].rec_button.mSurfaceValue, selectedTrackChannel.mValue.mMonitorEnable).setTypeToggle() + page.makeValueBinding(surfaceElements.channelControls[5].rec_button.mSurfaceValue, selectedTrackChannel.mValue.mMute).setTypeToggle() + page.makeValueBinding(surfaceElements.channelControls[6].rec_button.mSurfaceValue, selectedTrackChannel.mValue.mSolo).setTypeToggle() page.makeValueBinding(surfaceElements.channelControls[7].rec_button.mSurfaceValue, selectedTrackChannel.mValue.mRecordEnable).setTypeToggle() return page From e7f0e6b03a1a8c48742ef23bb8ef97341d7ca6a0 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sat, 4 Jun 2022 12:35:33 +1000 Subject: [PATCH 25/65] Selected track sub pages areas for sends/Qc, PreFilter, EQ, CureSends --- icon/platformmplus/icon_platformmplus.js | 121 +++++++++++++++++++---- 1 file changed, 101 insertions(+), 20 deletions(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 46315d8..eb5fafa 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -89,7 +89,7 @@ function makePageWithDefaults(name) { var jogSubPageArea = page.makeSubPageArea('Jog') var zoomSubPageArea = page.makeSubPageArea('Zoom') var subPageJogNudge = makeSubPage(jogSubPageArea, 'Nudge') - var subPageJogScrub = makeSubPage(jogSubPageArea, 'Srcub') + var subPageJogScrub = makeSubPage(jogSubPageArea, 'Scrub') var subPageJogZoom = makeSubPage(zoomSubPageArea, 'Zoom') var subPageJobNav = makeSubPage(zoomSubPageArea, 'Nav') @@ -119,7 +119,7 @@ function makePageWithDefaults(name) { page.makeActionBinding(surfaceElements.transport.btnZoomOnOff.mSurfaceValue, zoomSubPageArea.mAction.mNext) // Jog Pages - when Zoom lights are off - // Nuge + // Nudge page.makeCommandBinding(surfaceElements.transport.jogLeftVariable, 'Transport', 'Nudge Cursor Left').setSubPage(subPageJogNudge) page.makeCommandBinding(surfaceElements.transport.jogRightVariable, 'Transport', 'Nudge Cursor Right').setSubPage(subPageJogNudge) // Scrub (Jog in Cubase) @@ -198,37 +198,118 @@ function makePageMixer() { function makePageSelectedTrack() { var page = makePageWithDefaults('Selected Channel') + var faderSubPageArea = page.makeSubPageArea('Faders') + var subPageSendsQC = makeSubPage(faderSubPageArea, 'SendsQC') + var subPageEQ = makeSubPage(faderSubPageArea, 'EQ') + var subPageCueSends = makeSubPage(faderSubPageArea, 'CueSends') + var subPagePreFilter = makeSubPage(faderSubPageArea, 'PreFilter') + var selectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel + /// SendsQC subPage + // Sends on PushEncodes and mute button for pre/post + // Focus QC on Faders + // Fader for (var idx = 0; idx < surfaceElements.numStrips; ++idx) { var knobSurfaceValue = surfaceElements.channelControls[idx].pushEncoder.mEncoderValue; var knobPushValue = surfaceElements.channelControls[idx].pushEncoder.mPushValue; var faderSurfaceValue = surfaceElements.channelControls[idx].fader.mSurfaceValue; - page.makeValueBinding(knobSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mLevel) - page.makeValueBinding(knobPushValue, selectedTrackChannel.mSends.getByIndex(idx).mOn).setTypeToggle() - page.makeValueBinding(faderSurfaceValue, page.mHostAccess.mFocusedQuickControls.getByIndex(idx)).setValueTakeOverModeJump() + page.makeValueBinding(knobSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mLevel).setSubPage(subPageSendsQC) + page.makeValueBinding(knobPushValue, selectedTrackChannel.mSends.getByIndex(idx).mOn).setTypeToggle().setSubPage(subPageSendsQC) + page.makeValueBinding(faderSurfaceValue, page.mHostAccess.mFocusedQuickControls.getByIndex(idx)).setValueTakeOverModeJump().setSubPage(subPageSendsQC) + + page.makeValueBinding(surfaceElements.channelControls[idx].sel_button.mSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mOn).setTypeToggle().setSubPage(subPageSendsQC) + page.makeValueBinding(surfaceElements.channelControls[idx].mute_button.mSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mPrePost).setTypeToggle().setSubPage(subPageSendsQC) + } + + // Handy controls for easy access + page.makeCommandBinding(surfaceElements.channelControls[4].solo_button.mSurfaceValue, 'Automation', 'Show Used Automation (Selected Tracks)').setSubPage(subPageSendsQC) + page.makeCommandBinding(surfaceElements.channelControls[5].solo_button.mSurfaceValue, 'Automation', 'Hide Automation').setSubPage(subPageSendsQC) + page.makeValueBinding(surfaceElements.channelControls[6].solo_button.mSurfaceValue, selectedTrackChannel.mValue.mEditorOpen).setTypeToggle().setSubPage(subPageSendsQC) + page.makeValueBinding(surfaceElements.channelControls[7].solo_button.mSurfaceValue, selectedTrackChannel.mValue.mInstrumentOpen).setTypeToggle().setSubPage(subPageSendsQC) + + page.makeValueBinding(surfaceElements.channelControls[4].rec_button.mSurfaceValue, selectedTrackChannel.mValue.mMonitorEnable).setTypeToggle().setSubPage(subPageSendsQC) + page.makeValueBinding(surfaceElements.channelControls[5].rec_button.mSurfaceValue, selectedTrackChannel.mValue.mMute).setTypeToggle().setSubPage(subPageSendsQC) + page.makeValueBinding(surfaceElements.channelControls[6].rec_button.mSurfaceValue, selectedTrackChannel.mValue.mSolo).setTypeToggle().setSubPage(subPageSendsQC) + page.makeValueBinding(surfaceElements.channelControls[7].rec_button.mSurfaceValue, selectedTrackChannel.mValue.mRecordEnable).setTypeToggle().setSubPage(subPageSendsQC) + + // EQ Related but on Sends page so you know have EQ activated...not sure the best option but hey, more buttons and lights is cool! + page.makeValueBinding(surfaceElements.channelControls[0].solo_button.mSurfaceValue, selectedTrackChannel.mChannelEQ.mBand1.mOn).setTypeToggle().setSubPage(subPageSendsQC) + page.makeValueBinding(surfaceElements.channelControls[1].solo_button.mSurfaceValue, selectedTrackChannel.mChannelEQ.mBand2.mOn).setTypeToggle().setSubPage(subPageSendsQC) + page.makeValueBinding(surfaceElements.channelControls[2].solo_button.mSurfaceValue, selectedTrackChannel.mChannelEQ.mBand3.mOn).setTypeToggle().setSubPage(subPageSendsQC) + page.makeValueBinding(surfaceElements.channelControls[3].solo_button.mSurfaceValue, selectedTrackChannel.mChannelEQ.mBand4.mOn).setTypeToggle().setSubPage(subPageSendsQC) + + page.makeActionBinding(surfaceElements.channelControls[0].rec_button.mSurfaceValue, subPageSendsQC.mAction.mActivate).setSubPage(subPageSendsQC) + page.makeActionBinding(surfaceElements.channelControls[1].rec_button.mSurfaceValue, subPageEQ.mAction.mActivate).setSubPage(subPageSendsQC) + page.makeActionBinding(surfaceElements.channelControls[2].rec_button.mSurfaceValue, subPagePreFilter.mAction.mActivate).setSubPage(subPageSendsQC) + page.makeActionBinding(surfaceElements.channelControls[3].rec_button.mSurfaceValue, subPageCueSends.mAction.mActivate).setSubPage(subPageSendsQC) + + // EQ Subpage + const eqBand = [] + eqBand[0] = selectedTrackChannel.mChannelEQ.mBand1 + eqBand[1] = selectedTrackChannel.mChannelEQ.mBand2 + eqBand[2] = selectedTrackChannel.mChannelEQ.mBand3 + eqBand[3] = selectedTrackChannel.mChannelEQ.mBand4 + for (var idx = 0; idx < 4; ++idx) { + var knobSurfaceValue = surfaceElements.channelControls[idx].pushEncoder.mEncoderValue; + var knob2SurfaceValue = surfaceElements.channelControls[idx+4].pushEncoder.mEncoderValue; + var knobPushValue = surfaceElements.channelControls[idx].pushEncoder.mPushValue; + var knob2PushValue = surfaceElements.channelControls[idx+4].pushEncoder.mPushValue; + var faderSurfaceValue = surfaceElements.channelControls[idx].fader.mSurfaceValue; + var fader2SurfaceValue = surfaceElements.channelControls[idx + 4].fader.mSurfaceValue; + + page.makeValueBinding(knobSurfaceValue, eqBand[idx].mFilterType).setSubPage(subPageEQ) + page.makeValueBinding(knob2SurfaceValue, eqBand[idx].mQ).setSubPage(subPageEQ) + page.makeValueBinding(knobPushValue, eqBand[idx].mOn).setTypeToggle().setSubPage(subPageEQ) + page.makeValueBinding(knob2PushValue, eqBand[idx].mOn).setTypeToggle().setSubPage(subPageEQ) + page.makeValueBinding(faderSurfaceValue, eqBand[idx].mGain).setSubPage(subPageEQ) + page.makeValueBinding(fader2SurfaceValue, eqBand[idx].mFreq).setSubPage(subPageEQ) + } + + /// CueSends subPage + for (var idx = 0; idx < selectedTrackChannel.mCueSends.getSize(); ++idx) { + var knobSurfaceValue = surfaceElements.channelControls[idx].pushEncoder.mEncoderValue; + var knobPushValue = surfaceElements.channelControls[idx].pushEncoder.mPushValue; + var faderSurfaceValue = surfaceElements.channelControls[idx].fader.mSurfaceValue; + + page.makeValueBinding(knobSurfaceValue, selectedTrackChannel.mCueSends.getByIndex(idx).mPan).setSubPage(subPageCueSends) + page.makeValueBinding(knobPushValue, selectedTrackChannel.mCueSends.getByIndex(idx).mOn).setTypeToggle().setSubPage(subPageCueSends) + page.makeValueBinding(faderSurfaceValue, selectedTrackChannel.mCueSends.getByIndex(idx).mLevel).setSubPage(subPageCueSends) - //page.makeValueBinding(surfaceElements.channelControls[idx].sel_button.mSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mOn).setTypeToggle() - page.makeValueBinding(surfaceElements.channelControls[idx].mute_button.mSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mPrePost).setTypeToggle() - //page.makeValueBinding(surfaceElements.channelControls[idx].solo_button.mSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mOn).setTypeToggle() + page.makeValueBinding(surfaceElements.channelControls[idx].sel_button.mSurfaceValue, selectedTrackChannel.mCueSends.getByIndex(idx).mOn).setTypeToggle().setSubPage(subPageCueSends) + page.makeValueBinding(surfaceElements.channelControls[idx].mute_button.mSurfaceValue, selectedTrackChannel.mCueSends.getByIndex(idx).mPrePost).setTypeToggle().setSubPage(subPageCueSends) } - page.makeValueBinding(surfaceElements.channelControls[0].solo_button.mSurfaceValue, selectedTrackChannel.mChannelEQ.mBand1.mOn).setTypeToggle() - page.makeValueBinding(surfaceElements.channelControls[1].solo_button.mSurfaceValue, selectedTrackChannel.mChannelEQ.mBand2.mOn).setTypeToggle() - page.makeValueBinding(surfaceElements.channelControls[2].solo_button.mSurfaceValue, selectedTrackChannel.mChannelEQ.mBand3.mOn).setTypeToggle() - page.makeValueBinding(surfaceElements.channelControls[3].solo_button.mSurfaceValue, selectedTrackChannel.mChannelEQ.mBand4.mOn).setTypeToggle() + // PreFilter subPage + var knobSurfaceValue = surfaceElements.channelControls[0].pushEncoder.mEncoderValue; + var knob2SurfaceValue = surfaceElements.channelControls[1].pushEncoder.mEncoderValue; + var knob3SurfaceValue = surfaceElements.channelControls[2].pushEncoder.mEncoderValue; + + var knobPushValue = surfaceElements.channelControls[0].pushEncoder.mPushValue; + var knob2PushValue = surfaceElements.channelControls[1].pushEncoder.mPushValue; + var knob3PushValue = surfaceElements.channelControls[2].pushEncoder.mPushValue; + + var faderSurfaceValue = surfaceElements.channelControls[0].fader.mSurfaceValue; + var fader2SurfaceValue = surfaceElements.channelControls[1].fader.mSurfaceValue; + var fader3SurfaceValue = surfaceElements.channelControls[2].fader.mSurfaceValue; + + var preFilter = selectedTrackChannel.mPreFilter + page.makeValueBinding(surfaceElements.channelControls[0].sel_button.mSurfaceValue, preFilter.mBypass).setTypeToggle().setSubPage(subPagePreFilter) + page.makeValueBinding(surfaceElements.channelControls[0].mute_button.mSurfaceValue, preFilter.mPhaseSwitch).setTypeToggle().setSubPage(subPagePreFilter) - page.makeCommandBinding(surfaceElements.channelControls[4].solo_button.mSurfaceValue, 'Automation', 'Show Used Automation (Selected Tracks)') - page.makeCommandBinding(surfaceElements.channelControls[5].solo_button.mSurfaceValue, 'Automation', 'Hide Automation') - page.makeValueBinding(surfaceElements.channelControls[6].solo_button.mSurfaceValue, selectedTrackChannel.mValue.mEditorOpen).setTypeToggle() - page.makeValueBinding(surfaceElements.channelControls[7].solo_button.mSurfaceValue, selectedTrackChannel.mValue.mInstrumentOpen).setTypeToggle() + page.makeValueBinding(surfaceElements.channelControls[1].sel_button.mSurfaceValue, preFilter.mHighCutOn).setTypeToggle().setSubPage(subPagePreFilter) + page.makeValueBinding(surfaceElements.channelControls[2].sel_button.mSurfaceValue, preFilter.mLowCutOn).setTypeToggle().setSubPage(subPagePreFilter) - page.makeValueBinding(surfaceElements.channelControls[4].rec_button.mSurfaceValue, selectedTrackChannel.mValue.mMonitorEnable).setTypeToggle() - page.makeValueBinding(surfaceElements.channelControls[5].rec_button.mSurfaceValue, selectedTrackChannel.mValue.mMute).setTypeToggle() - page.makeValueBinding(surfaceElements.channelControls[6].rec_button.mSurfaceValue, selectedTrackChannel.mValue.mSolo).setTypeToggle() - page.makeValueBinding(surfaceElements.channelControls[7].rec_button.mSurfaceValue, selectedTrackChannel.mValue.mRecordEnable).setTypeToggle() + page.makeValueBinding(knob2SurfaceValue, preFilter.mHighCutSlope ).setSubPage(subPagePreFilter) + page.makeValueBinding(knob3SurfaceValue, preFilter.mLowCutSlope ).setSubPage(subPagePreFilter) + page.makeValueBinding(knobPushValue, preFilter.mBypass ).setTypeToggle().setSubPage(subPagePreFilter) + page.makeValueBinding(knob2PushValue, preFilter.mHighCutOn ).setTypeToggle().setSubPage(subPagePreFilter) + page.makeValueBinding(knob3PushValue, preFilter.mLowCutOn ).setTypeToggle().setSubPage(subPagePreFilter) + page.makeValueBinding(faderSurfaceValue, preFilter.mGain).setSubPage(subPagePreFilter) + page.makeValueBinding(fader2SurfaceValue, preFilter.mHighCutFreq ).setSubPage(subPagePreFilter) + page.makeValueBinding(fader3SurfaceValue, preFilter.mLowCutFreq ).setSubPage(subPagePreFilter) return page } From cc997d77b6f636be328b922b57fb2554ea49d650 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sat, 12 Nov 2022 10:08:12 +1100 Subject: [PATCH 26/65] WIP to display information on the D2 display - initial example code added by "Jesper" --- icon/platformmplus/helper.js | 58 ++++++++++++++++++++++++ icon/platformmplus/icon_elements.js | 25 ++++++++++ icon/platformmplus/icon_platformmplus.js | 47 +++++++++++++++++-- 3 files changed, 125 insertions(+), 5 deletions(-) create mode 100644 icon/platformmplus/helper.js diff --git a/icon/platformmplus/helper.js b/icon/platformmplus/helper.js new file mode 100644 index 0000000..0e326be --- /dev/null +++ b/icon/platformmplus/helper.js @@ -0,0 +1,58 @@ + +function make_Sysex_displayActivateLayoutByIndex(layoutIndex) { + return [0xf0, 0x00, 0x20, 0x29, 0x02, 0x0a, 0x01, + 0x01, layoutIndex, + 0xf7] +} + +function make_Sysex_displayActivateLayoutKnob() { + return make_Sysex_displayActivateLayoutByIndex(0x01) +} + +function make_Sysex_displaySetTextOfColumn(columnIndex, textFieldIndex, textString) { + var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, + columnIndex * 7 + textFieldIndex * 56] + //0xF0 0x00 0x00 0x66 0x14 0x12 ' + pos + ' ' + text.normalize('NFD').replace(/[\u0300-\u036f]/g, '').replace(/[^\x00-\x7F]/g, "?").split('').map(x => x.charCodeAt(0)).join(' ') + ' 0xF7 + + var text = (textString + ' ').slice(0, 7) // ensure to always clear a column + for (var i = 0; i < 7; ++i) + data.push(text.charCodeAt(i)) + + + //data.push(0) + data.push(0xf7) + + return data +} + +function make_Sysex_setDisplayValueOfColumn(columnIndex, objectIndex, value) { + // return [0xf0, 0x00, 0x20, 0x29, 0x02, 0x0a, 0x01, + // 0x02, columnIndex, 0x03, objectIndex, value, 0xf7] + return [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, + columnIndex * 7 + objectIndex * 56, value] +} + +/** + * @param {MR_ActiveDevice} activeDevice + * @param {MR_DeviceMidiOutput} outPort + */ +function resetDisplay(activeDevice, outPort) { + outPort.sendMidi(activeDevice, make_Sysex_displayActivateLayoutKnob()) + for (var i = 0; i < 8; ++i) { + for (var k = 0; k < 2; ++k) { + outPort.sendMidi(activeDevice, make_Sysex_displaySetTextOfColumn(i, k, " ")) + } + } +} + +module.exports = { + sysex: { + displayActivateLayoutByIndex: make_Sysex_displayActivateLayoutByIndex, + displayActivateLayoutKnob: make_Sysex_displayActivateLayoutKnob, + displaySetTextOfColumn: make_Sysex_displaySetTextOfColumn, + setDisplayValueOfColumn: make_Sysex_setDisplayValueOfColumn, + }, + display: { + reset: resetDisplay + } +} diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 20ade6a..55c529e 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -1,3 +1,4 @@ +var helper = require('./helper') /** * @param {MR_DeviceSurface} surface * @param {String} name @@ -50,6 +51,8 @@ function clearAllLeds(activeDevice, midiOutput) { midiOutput.sendMidi(activeDevice, [0x90, 94, 0]) midiOutput.sendMidi(activeDevice, [0x90, 95, 0]) midiOutput.sendMidi(activeDevice, [0x90, 86, 0]) + + helper.display.reset(activeDevice, midiOutput) } /** @@ -146,6 +149,28 @@ function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { channelControl.solo_button = makeLedButton(surface, midiInput, midiOutput, 8 + channelControl.instance, fader_x + 1, fader_y + 6, 1, 1, false) channelControl.rec_button = makeLedButton(surface, midiInput, midiOutput, 0 + channelControl.instance, fader_x + 1, fader_y + 7, 1, 1, true) + // ADDED BY JESPER START + var channelIndex = channelControl.instance + + //0xF0 0x00 0x00 0x66 0x14 0x12 ' + pos + ' ' + text.normalize('NFD').replace(/[\u0300-\u036f]/g, '').replace(/[^\x00-\x7F]/g, "?").split('').map(x => x.charCodeAt(0)).join(' ') + ' 0xF7 + + + // TITLE OF VALUE + channelControl.fader.mSurfaceValue.mOnTitleChange = function (context, objectTitle, valueTitle) { + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeStringMax6CharectersAndRemoveSpace(valueTitle))) + } + + channelControl.fader.mSurfaceValue.mOnDisplayValueChange = function (context, value, units) { + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeStringMax6CharectersAndRemoveSpace(value))) + } + + + function makeStringMax6CharectersAndRemoveSpace(value) { + //return value.length > 6 ? value.replace(/\s/g, '').slice(0, 6) : value + return value.replace(/\s/g, '').slice(0, 6) + } + // ADDED BY JESPER ENDS + return channelControl } diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index eb5fafa..b76b2a9 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -31,12 +31,12 @@ deviceDriver.mOnActivate = function (activeDevice) { // define all possible namings the devices MIDI ports could have // NOTE: Windows and MacOS handle port naming differently -// deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput) -// .expectInputNameEquals('Platform M+ V2.15') // Platform M+ v2.15 -// .expectOutputNameEquals('Platform M+ V2.15') // Platform M+ v2.15 deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput) - .expectInputNameContains('Platform M+') - .expectOutputNameContains('Platform M+') + .expectInputNameEquals('Platform M+ V2.15') // Platform M+ v2.15 + .expectOutputNameEquals('Platform M+ V2.15') // Platform M+ v2.15 +// deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput) +// .expectInputNameContains('Platform M+') +// .expectOutputNameContains('Platform M+') // ? I wonder if this can be figured out? // .expectSysexIdentityResponse(/*vendor id (1 or 3 bytes, here: 3 bytes)*/'00n1n2', /*device family*/'n1n2', /*model number*/'n1n2') @@ -67,6 +67,43 @@ function makeSurfaceElements() { var surfaceElements = makeSurfaceElements() + +function faderDisplayFeedback() { + surfaceElements.channelControls[0].fader.mSurfaceValue.mOnDisplayValueChange = function (context, value, units) { + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(0, 0, makeStringMax6CharectersAndRemoveSpace(value))) + } + + surfaceElements.channelControls[1].fader.mSurfaceValue.mOnDisplayValueChange = function (context, value, units) { + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(1, 0, makeStringMax6CharectersAndRemoveSpace(value))) + } + + surfaceElements.channelControls[2].fader.mSurfaceValue.mOnDisplayValueChange = function (context, value, units) { + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(2, 0, makeStringMax6CharectersAndRemoveSpace(value))) + } + + surfaceElements.channelControls[3].fader.mSurfaceValue.mOnDisplayValueChange = function (context, value, units) { + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(3, 0, makeStringMax6CharectersAndRemoveSpace(value))) + } + + surfaceElements.channelControls[4].fader.mSurfaceValue.mOnDisplayValueChange = function (context, value, units) { + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(4, 0, makeStringMax6CharectersAndRemoveSpace(value))) + } + surfaceElements.channelControls[5].fader.mSurfaceValue.mOnDisplayValueChange = function (context, value, units) { + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(5, 0, makeStringMax6CharectersAndRemoveSpace(value))) + } + surfaceElements.channelControls[6].fader.mSurfaceValue.mOnDisplayValueChange = function (context, value, units) { + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(6, 0, makeStringMax6CharectersAndRemoveSpace(value))) + } + surfaceElements.channelControls[7].fader.mSurfaceValue.mOnDisplayValueChange = function (context, value, units) { + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(7, 0, makeStringMax6CharectersAndRemoveSpace(value))) + } + + function makeStringMax6CharectersAndRemoveSpace(value) { + //return value.length > 6 ? value.replace(/\s/g, '').slice(0, 6) : value + return value.replace(/\s/g, '').slice(0, 6) + } +} + //----------------------------------------------------------------------------- // 3. HOST MAPPING - create mapping mixerPages and host bindings //----------------------------------------------------------------------------- From facbe8826e59fc19124bf874c6181d828a874226 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sat, 12 Nov 2022 10:51:06 +1100 Subject: [PATCH 27/65] Remove WIP code --- icon/platformmplus/icon_platformmplus.js | 36 ------------------------ 1 file changed, 36 deletions(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index b76b2a9..ce6000a 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -68,42 +68,6 @@ function makeSurfaceElements() { var surfaceElements = makeSurfaceElements() -function faderDisplayFeedback() { - surfaceElements.channelControls[0].fader.mSurfaceValue.mOnDisplayValueChange = function (context, value, units) { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(0, 0, makeStringMax6CharectersAndRemoveSpace(value))) - } - - surfaceElements.channelControls[1].fader.mSurfaceValue.mOnDisplayValueChange = function (context, value, units) { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(1, 0, makeStringMax6CharectersAndRemoveSpace(value))) - } - - surfaceElements.channelControls[2].fader.mSurfaceValue.mOnDisplayValueChange = function (context, value, units) { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(2, 0, makeStringMax6CharectersAndRemoveSpace(value))) - } - - surfaceElements.channelControls[3].fader.mSurfaceValue.mOnDisplayValueChange = function (context, value, units) { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(3, 0, makeStringMax6CharectersAndRemoveSpace(value))) - } - - surfaceElements.channelControls[4].fader.mSurfaceValue.mOnDisplayValueChange = function (context, value, units) { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(4, 0, makeStringMax6CharectersAndRemoveSpace(value))) - } - surfaceElements.channelControls[5].fader.mSurfaceValue.mOnDisplayValueChange = function (context, value, units) { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(5, 0, makeStringMax6CharectersAndRemoveSpace(value))) - } - surfaceElements.channelControls[6].fader.mSurfaceValue.mOnDisplayValueChange = function (context, value, units) { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(6, 0, makeStringMax6CharectersAndRemoveSpace(value))) - } - surfaceElements.channelControls[7].fader.mSurfaceValue.mOnDisplayValueChange = function (context, value, units) { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(7, 0, makeStringMax6CharectersAndRemoveSpace(value))) - } - - function makeStringMax6CharectersAndRemoveSpace(value) { - //return value.length > 6 ? value.replace(/\s/g, '').slice(0, 6) : value - return value.replace(/\s/g, '').slice(0, 6) - } -} - //----------------------------------------------------------------------------- // 3. HOST MAPPING - create mapping mixerPages and host bindings //----------------------------------------------------------------------------- From 84311eefbccb405d3a3e79826c15fa7dd5479844 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sat, 12 Nov 2022 10:51:36 +1100 Subject: [PATCH 28/65] Update label encoding to make Camel Case and Strip vowels to improve identification --- icon/platformmplus/icon_elements.js | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 55c529e..ff5abc7 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -157,19 +157,32 @@ function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { // TITLE OF VALUE channelControl.fader.mSurfaceValue.mOnTitleChange = function (context, objectTitle, valueTitle) { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeStringMax6CharectersAndRemoveSpace(valueTitle))) + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(valueTitle))) } channelControl.fader.mSurfaceValue.mOnDisplayValueChange = function (context, value, units) { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeStringMax6CharectersAndRemoveSpace(value))) + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value))) } + function makeLabel(value) { - function makeStringMax6CharectersAndRemoveSpace(value) { - //return value.length > 6 ? value.replace(/\s/g, '').slice(0, 6) : value - return value.replace(/\s/g, '').slice(0, 6) + var words = value.split(" "); + var label = ""; + + for(var i = 0 , len = words.length; i < len; i++) { + + var currentStr = words[i]; + + var tempStr = currentStr + + // convert first letter to upper case and remove all vowels after first letter + tempStr = tempStr.substr(0, 1).toUpperCase() + tempStr.substr(1).replace(/[aeiou]/gi, ''); + + label +=tempStr; + + } + return label.slice(0, 6); // Remove vowels and shorten to 6 char label } - // ADDED BY JESPER ENDS return channelControl From ff2f9a4588c793cc96d16b08c46ad2a6689a30ff Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sat, 19 Nov 2022 11:38:34 +1100 Subject: [PATCH 29/65] Scale layout to make room for d2 panel --- icon/platformmplus/icon_elements.js | 100 ++++++++++++----------- icon/platformmplus/icon_platformmplus.js | 86 ++++++++++++++++--- 2 files changed, 129 insertions(+), 57 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index ff5abc7..01d58bb 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -120,12 +120,12 @@ function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { channelControl.surface = surface; channelControl.midiInput = midiInput; channelControl.midiOutput = midiOutput; - channelControl.x = x + 2 * instance; + channelControl.x = x + 7 * instance; channelControl.y = y; channelControl.instance = instance; // Channel number, 1-8 // Pot encoder - channelControl.pushEncoder = channelControl.surface.makePushEncoder(channelControl.x, y, 2, 2) + channelControl.pushEncoder = channelControl.surface.makePushEncoder(channelControl.x, y+2, 4, 4) channelControl.pushEncoder.mEncoderValue.mMidiBinding .setInputPort(midiInput) @@ -138,50 +138,56 @@ function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { // Fader + Fader Touch var fader_x = channelControl.x - var fader_y = y + 3 - var tf = makeTouchFader(surface, midiInput, channelControl.midiOutput, instance, fader_x, fader_y, 1, 8) + var fader_y = y + 7 + var tf = makeTouchFader(surface, midiInput, channelControl.midiOutput, instance, fader_x, fader_y, 3, 18) channelControl.fader = tf[0] channelControl.fader_touch = tf[1] // Channel Buttons - channelControl.sel_button = makeLedButton(surface, midiInput, midiOutput, 24 + channelControl.instance, fader_x + 1, fader_y + 4, 1, 1, false) - channelControl.mute_button = makeLedButton(surface, midiInput, midiOutput, 16 + channelControl.instance, fader_x + 1, fader_y + 5, 1, 1, false) - channelControl.solo_button = makeLedButton(surface, midiInput, midiOutput, 8 + channelControl.instance, fader_x + 1, fader_y + 6, 1, 1, false) - channelControl.rec_button = makeLedButton(surface, midiInput, midiOutput, 0 + channelControl.instance, fader_x + 1, fader_y + 7, 1, 1, true) + channelControl.sel_button = makeLedButton(surface, midiInput, midiOutput, 24 + channelControl.instance, fader_x + 4, fader_y + 6, 3, 3, false) + channelControl.mute_button = makeLedButton(surface, midiInput, midiOutput, 16 + channelControl.instance, fader_x + 4, fader_y + 9, 3, 3, false) + channelControl.solo_button = makeLedButton(surface, midiInput, midiOutput, 8 + channelControl.instance, fader_x + 4, fader_y + 12, 3, 3, false) + channelControl.rec_button = makeLedButton(surface, midiInput, midiOutput, 0 + channelControl.instance, fader_x + 4, fader_y + 15, 3, 3, true) - // ADDED BY JESPER START var channelIndex = channelControl.instance - //0xF0 0x00 0x00 0x66 0x14 0x12 ' + pos + ' ' + text.normalize('NFD').replace(/[\u0300-\u036f]/g, '').replace(/[^\x00-\x7F]/g, "?").split('').map(x => x.charCodeAt(0)).join(' ') + ' 0xF7 - - - // TITLE OF VALUE channelControl.fader.mSurfaceValue.mOnTitleChange = function (context, objectTitle, valueTitle) { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(valueTitle))) + console.log(objectTitle) + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(objectTitle))) + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(valueTitle))) } channelControl.fader.mSurfaceValue.mOnDisplayValueChange = function (context, value, units) { midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value))) } + // channelControl.fader.mSurfaceValue.mOnProcessValueChange = function (context, newValue, oldValue) { + // // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, newValue)) + // } + function makeLabel(value) { + // Do nothing if the label is already short enough + if (value.length <= 6) { + return value + } - var words = value.split(" "); - var label = ""; + // If to long shorten it by removing vowels and making it CamelCase to remove spaces + var words = value.split(" "); + var label = ""; - for(var i = 0 , len = words.length; i < len; i++) { + for(var i = 0 , len = words.length; i < len; i++) { - var currentStr = words[i]; + var currentStr = words[i]; - var tempStr = currentStr + var tempStr = currentStr - // convert first letter to upper case and remove all vowels after first letter - tempStr = tempStr.substr(0, 1).toUpperCase() + tempStr.substr(1).replace(/[aeiou]/gi, ''); + // convert first letter to upper case and remove all vowels after first letter + tempStr = tempStr.substr(0, 1).toUpperCase() + tempStr.substr(1).replace(/[aeiou]/gi, ''); - label +=tempStr; + label +=tempStr; - } - return label.slice(0, 6); // Remove vowels and shorten to 6 char label + } + return label.slice(0, 6); // Remove vowels and shorten to 6 char label } return channelControl @@ -203,7 +209,7 @@ function makeMasterControl(surface, midiInput, midiOutput, x, y, instance) { masterControl.surface = surface; masterControl.midiInput = midiInput; masterControl.midiOutput = midiOutput; - masterControl.x = x + 2 * instance; + masterControl.x = x + 7 * instance; masterControl.y = y; masterControl.instance = instance; // 9 - Master @@ -214,14 +220,14 @@ function makeMasterControl(surface, midiInput, midiOutput, x, y, instance) { // Fader + Fader Touch var fader_x = masterControl.x var fader_y = y + 3 - var tf = makeTouchFader(surface, midiInput, midiOutput, instance, fader_x, fader_y, 1, 8) + var tf = makeTouchFader(surface, midiInput, midiOutput, instance, fader_x, fader_y, 3, 18) masterControl.fader = tf[0] masterControl.fader_touch = tf[1] // Channel Buttons - masterControl.mixer_button = makeLedButton(surface, midiInput, midiOutput, 84, fader_x + 1, fader_y + 4, 1, 1, false) - masterControl.read_button = makeLedButton(surface, midiInput, midiOutput, 74, fader_x + 1, fader_y + 5, 1, 1, false) - masterControl.write_button = makeLedButton(surface, midiInput, midiOutput, 75, fader_x + 1, fader_y + 6, 1, 1, false) + masterControl.mixer_button = makeLedButton(surface, midiInput, midiOutput, 84, fader_x + 3, fader_y + 6, 3, 3, false) + masterControl.read_button = makeLedButton(surface, midiInput, midiOutput, 74, fader_x + 3, fader_y + 9, 3, 3, false) + masterControl.write_button = makeLedButton(surface, midiInput, midiOutput, 75, fader_x + 3, fader_y + 12, 3, 3, false) return masterControl } @@ -234,8 +240,8 @@ function makeTransport(surface, midiInput, midiOutput, x, y) { transport.x = x; transport.y = y; - var w = 1 - var h = 1 + var w = 3 + var h = 3 transport.ident = function () { return ("Class Transport"); @@ -246,31 +252,31 @@ function makeTransport(surface, midiInput, midiOutput, x, y) { } transport.prevChn = makeLedButton(surface, midiInput, midiOutput, 48, x, y, w, h, false) - transport.nextChn = makeLedButton(surface, midiInput, midiOutput, 49, x + 1, y, w, h, false) + transport.nextChn = makeLedButton(surface, midiInput, midiOutput, 49, x + 3, y, w, h, false) - transport.prevBnk = makeLedButton(surface, midiInput, midiOutput, 46, x, y + 1, w, h, false) - transport.nextBnk = makeLedButton(surface, midiInput, midiOutput, 47, x + 1, y + 1, w, h, false) + transport.prevBnk = makeLedButton(surface, midiInput, midiOutput, 46, x, y + 3, w, h, false) + transport.nextBnk = makeLedButton(surface, midiInput, midiOutput, 47, x + 3, y + 3, w, h, false) - transport.btnRewind = makeLedButton(surface, midiInput, midiOutput, 91, x, y + 2, w, h, false) - transport.btnForward = makeLedButton(surface, midiInput, midiOutput, 92, x + 1, y + 2, w, h, false) + transport.btnRewind = makeLedButton(surface, midiInput, midiOutput, 91, x, y + 6, w, h, false) + transport.btnForward = makeLedButton(surface, midiInput, midiOutput, 92, x + 3, y + 6, w, h, false) - transport.btnStop = makeLedButton(surface, midiInput, midiOutput, 93, x + 1, y + 3, w, h, false) - transport.btnStart = makeLedButton(surface, midiInput, midiOutput, 94, x, y + 3, w, h, false) + transport.btnStop = makeLedButton(surface, midiInput, midiOutput, 93, x + 3, y + 9, w, h, false) + transport.btnStart = makeLedButton(surface, midiInput, midiOutput, 94, x, y + 9, w, h, false) - transport.btnRecord = makeLedButton(surface, midiInput, midiOutput, 95, x, y + 4, w, h, false) - transport.btnCycle = makeLedButton(surface, midiInput, midiOutput, 86, x + 1, y + 4, w, h, false) + transport.btnRecord = makeLedButton(surface, midiInput, midiOutput, 95, x, y + 12, w, h, false) + transport.btnCycle = makeLedButton(surface, midiInput, midiOutput, 86, x + 3, y + 12, w, h, false) // The Note on/off events for the special functioans are timestamped at the same time // cubase midi remote doesn't show anything on screen though a note is sent // Flip - Simultaneous press of Pre Chn+Pre Bank - transport.btnFlip = surface.makeButton(x + 3, y + 4, 1, 1) + transport.btnFlip = surface.makeButton(x+0.5, y + 15, 2, 2).setShapeCircle() bindMidiNote(transport.btnFlip, 0, 50) // Pressing the Zoom keys simultaneously will toggle on and off a note event. If on // either zoom button will send a Note 100 when zoom is activated or deactivated by either button // If zoom is active and you simply press then other button the event will not be sent // - transport.btnZoomOnOff = surface.makeButton(x + 4, y + 4, 1, 1) + transport.btnZoomOnOff = surface.makeButton(x + 3.5, y + 15, 2, 2).setShapeCircle() bindMidiNote(transport.btnZoomOnOff, 0, 100) // The Jog wheel will change CC/Note based on which of thte Zoom buttons have been activated @@ -285,7 +291,7 @@ function makeTransport(surface, midiInput, midiOutput, x, y) { // ? One weird side effect of this is the Knob displayed in Cubase will show its "value" in a weird way. // todo I wonder if there is a way to change that behaviour? - transport.jog_wheel = surface.makePushEncoder(x, y + 6, 2, 2) + transport.jog_wheel = surface.makePushEncoder(x, y + 17, 6, 6) transport.jog_wheel.mEncoderValue.mMidiBinding .setInputPort(midiInput) .setIsConsuming(true) @@ -301,15 +307,15 @@ function makeTransport(surface, midiInput, midiOutput, x, y) { bindCommandKnob(transport.jog_wheel.mEncoderValue, transport.jogRightVariable, transport.jogLeftVariable); //Zoom Vertical - transport.zoomVertOut = surface.makeButton(x + 3, y + 6, 1, 1).setShapeCircle() + transport.zoomVertOut = surface.makeButton(x + 9, y + 8, 2, 2).setShapeCircle() bindMidiNote(transport.zoomVertOut, 0, 96) - transport.zoomVertIn = surface.makeButton(x + 4, y + 6, 1, 1).setShapeCircle() + transport.zoomVertIn = surface.makeButton(x + 11, y + 8, 2, 2).setShapeCircle() bindMidiNote(transport.zoomVertIn, 0, 97) //Zoom Horizontal - transport.zoomHorizOut = surface.makeButton(x + 3, y + 7, 1, 1).setShapeCircle() + transport.zoomHorizOut = surface.makeButton(x + 9, y + 10, 2, 2).setShapeCircle() bindMidiNote(transport.zoomHorizOut, 0, 98) - transport.zoomHorizIn = surface.makeButton(x + 4, y + 7, 1, 1).setShapeCircle() + transport.zoomHorizIn = surface.makeButton(x + 11, y + 10, 2, 2).setShapeCircle() bindMidiNote(transport.zoomHorizIn, 0, 99) return transport diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index ce6000a..a153877 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -31,14 +31,13 @@ deviceDriver.mOnActivate = function (activeDevice) { // define all possible namings the devices MIDI ports could have // NOTE: Windows and MacOS handle port naming differently -deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput) - .expectInputNameEquals('Platform M+ V2.15') // Platform M+ v2.15 - .expectOutputNameEquals('Platform M+ V2.15') // Platform M+ v2.15 // deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput) -// .expectInputNameContains('Platform M+') -// .expectOutputNameContains('Platform M+') -// ? I wonder if this can be figured out? -// .expectSysexIdentityResponse(/*vendor id (1 or 3 bytes, here: 3 bytes)*/'00n1n2', /*device family*/'n1n2', /*model number*/'n1n2') +// .expectInputNameEquals('Platform M+ V2.15') // Platform M+ v2.15 +// .expectOutputNameEquals('Platform M+ V2.15') // Platform M+ v2.15 +deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput) + .expectInputNameContains('Platform M+') + .expectOutputNameContains('Platform M+') + var surface = deviceDriver.mSurface @@ -48,19 +47,24 @@ var surface = deviceDriver.mSurface function makeSurfaceElements() { var surfaceElements = {} + // Display - 2lines + surfaceElements.d2Display = surface.makeBlindPanel(0,0,56,6) + surfaceElements.displayTop = surface.makeLabelField(0,1,56,2) + surfaceElements.displayBottom = surface.makeLabelField(0,3,56,2) + surfaceElements.numStrips = 8 surfaceElements.channelControls = {} var xKnobStrip = 0 - var yKnobStrip = 0 + var yKnobStrip = 5 for (var i = 0; i < surfaceElements.numStrips; ++i) { surfaceElements.channelControls[i] = makeChannelControl(surface, midiInput, midiOutput, xKnobStrip, yKnobStrip, i) } - surfaceElements.faderMaster = makeMasterControl(surface, midiInput, midiOutput, xKnobStrip + 1, yKnobStrip, surfaceElements.numStrips) - surfaceElements.transport = makeTransport(surface, midiInput, midiOutput, xKnobStrip + 20, yKnobStrip + 3) + surfaceElements.faderMaster = makeMasterControl(surface, midiInput, midiOutput, xKnobStrip + 1, yKnobStrip+4, surfaceElements.numStrips) + surfaceElements.transport = makeTransport(surface, midiInput, midiOutput, xKnobStrip + 63, yKnobStrip + 4) return surfaceElements } @@ -315,8 +319,65 @@ function makePageSelectedTrack() { return page } +function makePageChannelStrip() { + var page = makePageWithDefaults('Channelstrip') + + var strip = page.makeSubPageArea('strip') + var gatePage = makeSubPage(strip, 'Gate') + var compressorPage = makeSubPage(strip, 'Compressor') + var toolsPage = makeSubPage(strip, 'Tools') + var saturatorPage = makeSubPage(strip, 'Saturator') + var limiterPage = makeSubPage(strip, 'Limiter') + + + var selectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel + var stripEffects = selectedTrackChannel.mInsertAndStripEffects.mStripEffects + + for (var idx = 0; idx < surfaceElements.numStrips; ++idx) { + var knobSurfaceValue = surfaceElements.channelControls[idx].pushEncoder.mEncoderValue; + var knobPushValue = surfaceElements.channelControls[idx].pushEncoder.mPushValue; + var faderSurfaceValue = surfaceElements.channelControls[idx].fader.mSurfaceValue; + + page.makeValueBinding(faderSurfaceValue, stripEffects.mGate.mParameterBankZone.makeParameterValue()).setSubPage(gatePage) + page.makeValueBinding(faderSurfaceValue, stripEffects.mCompressor.mParameterBankZone.makeParameterValue()).setSubPage(compressorPage) + page.makeValueBinding(faderSurfaceValue, stripEffects.mTools.mParameterBankZone.makeParameterValue()).setSubPage(toolsPage) + page.makeValueBinding(faderSurfaceValue, stripEffects.mSaturator.mParameterBankZone.makeParameterValue()).setSubPage(saturatorPage) + page.makeValueBinding(faderSurfaceValue, stripEffects.mLimiter.mParameterBankZone.makeParameterValue()).setSubPage(limiterPage) + } + + for (var idx = 0; idx < 5; ++idx) { + var faderStrip = surfaceElements.channelControls[idx] + var type = ['mGate', 'mCompressor', 'mTools', 'mSaturator', 'mLimiter'][idx] + page.makeValueBinding(faderStrip.rec_button.mSurfaceValue, stripEffects[type].mOn).setTypeToggle() + page.makeValueBinding(faderStrip.mute_button.mSurfaceValue, stripEffects[type].mBypass).setTypeToggle() + } + + page.makeActionBinding(surfaceElements.channelControls[0].sel_button.mSurfaceValue, gatePage.mAction.mActivate) + page.makeActionBinding(surfaceElements.channelControls[1].sel_button.mSurfaceValue, compressorPage.mAction.mActivate) + page.makeActionBinding(surfaceElements.channelControls[2].sel_button.mSurfaceValue, toolsPage.mAction.mActivate) + page.makeActionBinding(surfaceElements.channelControls[3].sel_button.mSurfaceValue, saturatorPage.mAction.mActivate) + page.makeActionBinding(surfaceElements.channelControls[4].sel_button.mSurfaceValue, limiterPage.mAction.mActivate) + + gatePage.mOnActivate = function (device) { setLeds(device, 24, 'Gate') } + compressorPage.mOnActivate = function (device) { setLeds(device, 25, 'Compressor') } + toolsPage.mOnActivate = function (device) { setLeds(device, 26, 'Tools') } + saturatorPage.mOnActivate = function (device) { setLeds(device, 27, 'Saturator') } + limiterPage.mOnActivate = function (device) { setLeds(device, 28, 'Limiter') } + + function setLeds(device, value, text) { + console.log('from script: Platform M+ subpage "' + text + '" activated') + for (var i = 0; i < 5; ++i) { + midiOutput.sendMidi(device, [0x90, 24 + i, 0]) + } + midiOutput.sendMidi(device, [0x90, value, 127]) + } + + return page +} + var mixerPage = makePageMixer() var selectedTrackPage = makePageSelectedTrack() +var channelStripPage = makePageChannelStrip() // var quadPage = makePageQuad() mixerPage.mOnActivate = function (device) { @@ -328,3 +389,8 @@ selectedTrackPage.mOnActivate = function (device) { console.log('from script: Platform M+ page "Selected Track" activated') clearAllLeds(device, midiOutput) } + +channelStripPage.mOnActivate = function (device) { + console.log('from script: Platform M+ page "Channel Strip" activated') + clearAllLeds(device, midiOutput) +} From c6c3066f0ded408f2d0349823f80daee0699344a Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sat, 19 Nov 2022 16:43:36 +1100 Subject: [PATCH 30/65] Fooling around with different display options and feedback whilst learning the midiremote capabilities --- icon/platformmplus/icon_elements.js | 27 ++++++++++++++++++------ icon/platformmplus/icon_platformmplus.js | 14 +++++++++--- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 01d58bb..fa9453f 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -124,6 +124,13 @@ function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { channelControl.y = y; channelControl.instance = instance; // Channel number, 1-8 + // Channel Displays + channelControl.displayTop = channelControl.surface.makeLabelField(channelControl.x,1,7,2) + channelControl.displayBottom = channelControl.surface.makeLabelField(channelControl.x,3,7,2) + + channelControl.faderValueDisplay = channelControl.surface.makeCustomValueVariable('faderValueDisplay'); + channelControl.panValueDisplay = channelControl.surface.makeCustomValueVariable('panValueDisplay'); + // Pot encoder channelControl.pushEncoder = channelControl.surface.makePushEncoder(channelControl.x, y+2, 4, 4) @@ -151,18 +158,26 @@ function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { var channelIndex = channelControl.instance - channelControl.fader.mSurfaceValue.mOnTitleChange = function (context, objectTitle, valueTitle) { - console.log(objectTitle) + // channelControl.fader.mSurfaceValue.mOnTitleChange = function (context, objectTitle, valueTitle) { + // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(objectTitle))) + // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(valueTitle))) + // } + + channelControl.faderValueDisplay.mOnTitleChange = function (context, objectTitle, valueTitle) { midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(objectTitle))) midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(valueTitle))) } - channelControl.fader.mSurfaceValue.mOnDisplayValueChange = function (context, value, units) { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value))) + channelControl.faderValueDisplay.mOnDisplayValueChange = function (context, value, units) { + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, "|"+makeLabel(value))) } + // channelControl.panValueDisplay.mOnTitleChange = function (context, objectTitle, valueTitle) { + // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(objectTitle))) + // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(valueTitle))) + // } - // channelControl.fader.mSurfaceValue.mOnProcessValueChange = function (context, newValue, oldValue) { - // // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, newValue)) + // channelControl.panValueDisplay.mOnDisplayValueChange = function (context, value, units) { + // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, "_"+makeLabel(value))) // } function makeLabel(value) { diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index a153877..13e80d8 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -49,8 +49,6 @@ function makeSurfaceElements() { // Display - 2lines surfaceElements.d2Display = surface.makeBlindPanel(0,0,56,6) - surfaceElements.displayTop = surface.makeLabelField(0,1,56,2) - surfaceElements.displayBottom = surface.makeLabelField(0,3,56,2) surfaceElements.numStrips = 8 @@ -186,6 +184,11 @@ function makePageMixer() { var solo_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].solo_button.mSurfaceValue; var rec_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].rec_button.mSurfaceValue; + // Displays + page.setLabelFieldHostObject(surfaceElements.channelControls[channelIndex].displayTop, hostMixerBankChannel) // For PC display, Platfomr M+ D2 display coded in icon_elements.js + page.makeValueBinding(surfaceElements.channelControls[channelIndex].faderValueDisplay, hostMixerBankChannel.mValue.mVolume) // for Platform M+ D2 Display + page.makeValueBinding(surfaceElements.channelControls[channelIndex].panValueDisplay, hostMixerBankChannel.mValue.mPan) // for Platform M+ D2 Display + // FaderKnobs - Volume, Pan, Editor Open page.makeValueBinding(knobSurfaceValue, hostMixerBankChannel.mValue.mPan).setSubPage(subPageFaderVolume) page.makeValueBinding(knobPushValue, hostMixerBankChannel.mValue.mEditorOpen).setTypeToggle().setSubPage(subPageFaderVolume) @@ -220,6 +223,11 @@ function makePageSelectedTrack() { var knobPushValue = surfaceElements.channelControls[idx].pushEncoder.mPushValue; var faderSurfaceValue = surfaceElements.channelControls[idx].fader.mSurfaceValue; + // Displays + page.setLabelFieldHostObject(surfaceElements.channelControls[idx].displayTop, page.mHostAccess.mFocusedQuickControls) // For PC display, Platfomr M+ D2 display coded in icon_elements.js + page.makeValueBinding(surfaceElements.channelControls[idx].faderValueDisplay, page.mHostAccess.mFocusedQuickControls.getByIndex(idx)) // for Platform M+ D2 Display + page.makeValueBinding(surfaceElements.channelControls[idx].panValueDisplay, selectedTrackChannel.mSends.getByIndex(idx).mLevel) // for Platform M+ D2 Display + page.makeValueBinding(knobSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mLevel).setSubPage(subPageSendsQC) page.makeValueBinding(knobPushValue, selectedTrackChannel.mSends.getByIndex(idx).mOn).setTypeToggle().setSubPage(subPageSendsQC) page.makeValueBinding(faderSurfaceValue, page.mHostAccess.mFocusedQuickControls.getByIndex(idx)).setValueTakeOverModeJump().setSubPage(subPageSendsQC) @@ -378,10 +386,10 @@ function makePageChannelStrip() { var mixerPage = makePageMixer() var selectedTrackPage = makePageSelectedTrack() var channelStripPage = makePageChannelStrip() -// var quadPage = makePageQuad() mixerPage.mOnActivate = function (device) { console.log('from script: Platform M+ page "Mixer" activated') + clearAllLeds(device, midiOutput) } From 8c35ecf0ec6694597ed04b22ceefdacd5043e647 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 20 Nov 2022 07:35:58 +1100 Subject: [PATCH 31/65] Now with touch fader change to/from values --- icon/platformmplus/helper.js | 44 +++++++++------------- icon/platformmplus/icon_elements.js | 48 +++++++++++++++++------- icon/platformmplus/icon_platformmplus.js | 7 +++- 3 files changed, 56 insertions(+), 43 deletions(-) diff --git a/icon/platformmplus/helper.js b/icon/platformmplus/helper.js index 0e326be..7a8e0de 100644 --- a/icon/platformmplus/helper.js +++ b/icon/platformmplus/helper.js @@ -1,35 +1,28 @@ -function make_Sysex_displayActivateLayoutByIndex(layoutIndex) { - return [0xf0, 0x00, 0x20, 0x29, 0x02, 0x0a, 0x01, - 0x01, layoutIndex, - 0xf7] -} - -function make_Sysex_displayActivateLayoutKnob() { - return make_Sysex_displayActivateLayoutByIndex(0x01) -} - -function make_Sysex_displaySetTextOfColumn(columnIndex, textFieldIndex, textString) { +function displaySetTextOfColumn(columnIndex, rowIndex, textString) { var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, - columnIndex * 7 + textFieldIndex * 56] - //0xF0 0x00 0x00 0x66 0x14 0x12 ' + pos + ' ' + text.normalize('NFD').replace(/[\u0300-\u036f]/g, '').replace(/[^\x00-\x7F]/g, "?").split('').map(x => x.charCodeAt(0)).join(' ') + ' 0xF7 + columnIndex * 7 + rowIndex * 56] var text = (textString + ' ').slice(0, 7) // ensure to always clear a column + console.log("display:"+text) for (var i = 0; i < 7; ++i) data.push(text.charCodeAt(i)) - - - //data.push(0) data.push(0xf7) return data } -function make_Sysex_setDisplayValueOfColumn(columnIndex, objectIndex, value) { - // return [0xf0, 0x00, 0x20, 0x29, 0x02, 0x0a, 0x01, - // 0x02, columnIndex, 0x03, objectIndex, value, 0xf7] - return [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, - columnIndex * 7 + objectIndex * 56, value] +function displaySetTextOfLine(rowIndex, textString) { + var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, + rowIndex * 56] + var blank = Array(56).join(" ") + var text = (textString + blank).slice(0, 50) // ensure to always clear the entire row + console.log("display:"+text) + for (var i = 0; i < 50; ++i) + data.push(text.charCodeAt(i)) + data.push(0xf7) + + return data } /** @@ -37,20 +30,17 @@ function make_Sysex_setDisplayValueOfColumn(columnIndex, objectIndex, value) { * @param {MR_DeviceMidiOutput} outPort */ function resetDisplay(activeDevice, outPort) { - outPort.sendMidi(activeDevice, make_Sysex_displayActivateLayoutKnob()) for (var i = 0; i < 8; ++i) { for (var k = 0; k < 2; ++k) { - outPort.sendMidi(activeDevice, make_Sysex_displaySetTextOfColumn(i, k, " ")) + outPort.sendMidi(activeDevice, displaySetTextOfColumn(i, k, " ")) } } } module.exports = { sysex: { - displayActivateLayoutByIndex: make_Sysex_displayActivateLayoutByIndex, - displayActivateLayoutKnob: make_Sysex_displayActivateLayoutKnob, - displaySetTextOfColumn: make_Sysex_displaySetTextOfColumn, - setDisplayValueOfColumn: make_Sysex_setDisplayValueOfColumn, + displaySetTextOfColumn: displaySetTextOfColumn, + displaySetTextOfLine: displaySetTextOfLine }, display: { reset: resetDisplay diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index fa9453f..c2f90df 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -72,7 +72,7 @@ function makeTouchFader(surface, midiInput, midiOutput, channel, x, y, w, h) { .setOutputPort(midiOutput) .bindToPitchBend(channel) - var fader_touch = surface.makeButton(x + 1, y, 1, 1) + var fader_touch = surface.makeButton(x + 1, y -1, 1, 1) fader_touch.mSurfaceValue.mMidiBinding .setInputPort(midiInput) .bindToNote(0, 104 + channel) @@ -130,6 +130,11 @@ function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { channelControl.faderValueDisplay = channelControl.surface.makeCustomValueVariable('faderValueDisplay'); channelControl.panValueDisplay = channelControl.surface.makeCustomValueVariable('panValueDisplay'); + channelControl.faderObjectTitle = "" + channelControl.faderValuteTitle = "" + channelControl.faderTouched = 0 // 0 - not touched, 1 - touched + channelControl.panObjectTitle = "" + channelControl.panValueTitle = "" // Pot encoder channelControl.pushEncoder = channelControl.surface.makePushEncoder(channelControl.x, y+2, 4, 4) @@ -158,31 +163,46 @@ function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { var channelIndex = channelControl.instance - // channelControl.fader.mSurfaceValue.mOnTitleChange = function (context, objectTitle, valueTitle) { - // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(objectTitle))) - // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(valueTitle))) - // } + channelControl.fader_touch.mSurfaceValue.mOnProcessValueChange = function (context, touched, value2) { + channelControl.faderTouched = touched + if(touched) { + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderValueTitle,6))) + } + else { + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderObjectTitle, 6))) + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(channelControl.faderValueTitle, 6))) + } + } channelControl.faderValueDisplay.mOnTitleChange = function (context, objectTitle, valueTitle) { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(objectTitle))) - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(valueTitle))) + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(objectTitle, 6))) + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(valueTitle, 6))) + channelControl.faderObjectTitle = objectTitle + channelControl.faderValueTitle = valueTitle } channelControl.faderValueDisplay.mOnDisplayValueChange = function (context, value, units) { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, "|"+makeLabel(value))) + // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderValueTitle))) + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value, 6))) } + + // ! Can't currently find a way to stop the pan mOnTitleChange being triggered when initialised rather than just when its being changed. This stuffs up the display. // channelControl.panValueDisplay.mOnTitleChange = function (context, objectTitle, valueTitle) { - // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(objectTitle))) - // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(valueTitle))) + // // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(objectTitle))) + // // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(valueTitle))) + // channelControl.panObjectTitle = "objectTitle" + // channelControl.panValueTitle = "valueTitle" // } // channelControl.panValueDisplay.mOnDisplayValueChange = function (context, value, units) { - // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, "_"+makeLabel(value))) + // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel("Pan",6))) + // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value,6))) // } - function makeLabel(value) { + function makeLabel(value, length) { + console.log("makeLabel:"+value) // Do nothing if the label is already short enough - if (value.length <= 6) { + if (value.length <= length) { return value } @@ -202,7 +222,7 @@ function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { label +=tempStr; } - return label.slice(0, 6); // Remove vowels and shorten to 6 char label + return label.slice(0, length); // Remove vowels and shorten to 6 char label } return channelControl diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 13e80d8..ff3d4c5 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -185,7 +185,11 @@ function makePageMixer() { var rec_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].rec_button.mSurfaceValue; // Displays + // PC + // ? There doesn't appear to be a way via relateTo to connect the label surface elements to valueTitle or arbitrarily change them around + // ! Ignoring PC side of display for the moment in favour of the D2 displaying what is required page.setLabelFieldHostObject(surfaceElements.channelControls[channelIndex].displayTop, hostMixerBankChannel) // For PC display, Platfomr M+ D2 display coded in icon_elements.js + // D2 page.makeValueBinding(surfaceElements.channelControls[channelIndex].faderValueDisplay, hostMixerBankChannel.mValue.mVolume) // for Platform M+ D2 Display page.makeValueBinding(surfaceElements.channelControls[channelIndex].panValueDisplay, hostMixerBankChannel.mValue.mPan) // for Platform M+ D2 Display @@ -193,8 +197,7 @@ function makePageMixer() { page.makeValueBinding(knobSurfaceValue, hostMixerBankChannel.mValue.mPan).setSubPage(subPageFaderVolume) page.makeValueBinding(knobPushValue, hostMixerBankChannel.mValue.mEditorOpen).setTypeToggle().setSubPage(subPageFaderVolume) page.makeValueBinding(faderSurfaceValue, hostMixerBankChannel.mValue.mVolume).setValueTakeOverModeJump().setSubPage(subPageFaderVolume) - page.makeValueBinding(faderTouchSurfaceValue, hostMixerBankChannel.mValue.mSelected).setTypeToggle().setSubPage(subPageFaderVolume) - page.makeValueBinding(sel_buttonSurfaceValue, hostMixerBankChannel.mValue.mMonitorEnable).setTypeToggle().setSubPage(subPageButtonDefaultSet) + page.makeValueBinding(sel_buttonSurfaceValue, hostMixerBankChannel.mValue.mSelected).setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(mute_buttonSurfaceValue, hostMixerBankChannel.mValue.mMute).setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(solo_buttonSurfaceValue, hostMixerBankChannel.mValue.mSolo).setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(rec_buttonSurfaceValue, hostMixerBankChannel.mValue.mRecordEnable).setTypeToggle().setSubPage(subPageButtonDefaultSet) From 6146c4b029d9bcc76d66c3bd979f74076084702c Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 20 Nov 2022 08:49:05 +1100 Subject: [PATCH 32/65] WIP for Selected Track - starting to get a handle on how to do the display via customvariables and page switching --- icon/platformmplus/helper.js | 33 +++++- icon/platformmplus/icon_elements.js | 130 +++++++++++++++-------- icon/platformmplus/icon_platformmplus.js | 7 +- 3 files changed, 120 insertions(+), 50 deletions(-) diff --git a/icon/platformmplus/helper.js b/icon/platformmplus/helper.js index 7a8e0de..ba45e32 100644 --- a/icon/platformmplus/helper.js +++ b/icon/platformmplus/helper.js @@ -4,7 +4,7 @@ function displaySetTextOfColumn(columnIndex, rowIndex, textString) { columnIndex * 7 + rowIndex * 56] var text = (textString + ' ').slice(0, 7) // ensure to always clear a column - console.log("display:"+text) + // console.log("display:" + text) for (var i = 0; i < 7; ++i) data.push(text.charCodeAt(i)) data.push(0xf7) @@ -17,7 +17,7 @@ function displaySetTextOfLine(rowIndex, textString) { rowIndex * 56] var blank = Array(56).join(" ") var text = (textString + blank).slice(0, 50) // ensure to always clear the entire row - console.log("display:"+text) + // console.log("display:" + text) for (var i = 0; i < 50; ++i) data.push(text.charCodeAt(i)) data.push(0xf7) @@ -37,12 +37,39 @@ function resetDisplay(activeDevice, outPort) { } } +function makeLabel(value, length) { + // console.log("makeLabel:" + value) + // Do nothing if the label is already short enough + if (value.length <= length) { + return value + } + + // If to long shorten it by removing vowels and making it CamelCase to remove spaces + var words = value.split(" "); + var label = ""; + + for (var i = 0, len = words.length; i < len; i++) { + + var currentStr = words[i]; + + var tempStr = currentStr + + // convert first letter to upper case and remove all vowels after first letter + tempStr = tempStr.substr(0, 1).toUpperCase() + tempStr.substr(1).replace(/[aeiou]/gi, ''); + + label += tempStr; + + } + return label.slice(0, length); // Remove vowels and shorten to 6 char label +} + module.exports = { sysex: { displaySetTextOfColumn: displaySetTextOfColumn, displaySetTextOfLine: displaySetTextOfLine }, display: { - reset: resetDisplay + reset: resetDisplay, + makeLabel: makeLabel } } diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index c2f90df..4cade46 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -1,4 +1,5 @@ var helper = require('./helper') +var makeLabel = helper.display.makeLabel /** * @param {MR_DeviceSurface} surface * @param {String} name @@ -72,7 +73,7 @@ function makeTouchFader(surface, midiInput, midiOutput, channel, x, y, w, h) { .setOutputPort(midiOutput) .bindToPitchBend(channel) - var fader_touch = surface.makeButton(x + 1, y -1, 1, 1) + var fader_touch = surface.makeButton(x + 1, y - 1, 1, 1) fader_touch.mSurfaceValue.mMidiBinding .setInputPort(midiInput) .bindToNote(0, 104 + channel) @@ -115,7 +116,7 @@ function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { * @param {Number} h - height of the push encoder. * @param {Number} instance - instance of the push encoder. */ - function makeChannelControl(surface, midiInput, midiOutput, x, y, instance) { +function makeChannelControl(surface, midiInput, midiOutput, x, y, instance) { var channelControl = {} channelControl.surface = surface; channelControl.midiInput = midiInput; @@ -125,19 +126,22 @@ function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { channelControl.instance = instance; // Channel number, 1-8 // Channel Displays - channelControl.displayTop = channelControl.surface.makeLabelField(channelControl.x,1,7,2) - channelControl.displayBottom = channelControl.surface.makeLabelField(channelControl.x,3,7,2) - - channelControl.faderValueDisplay = channelControl.surface.makeCustomValueVariable('faderValueDisplay'); - channelControl.panValueDisplay = channelControl.surface.makeCustomValueVariable('panValueDisplay'); + channelControl.displayTop = channelControl.surface.makeLabelField(channelControl.x, 1, 7, 2) + channelControl.displayBottom = channelControl.surface.makeLabelField(channelControl.x, 3, 7, 2) + + channelControl.trackNameDisplay = channelControl.surface.makeCustomValueVariable('trackNameDisplay'); + channelControl.trackObjectTitle = "" + channelControl.trackValueTitle = "" + channelControl.faderValueDisplay = channelControl.surface.makeCustomValueVariable('faderValueDisplay'); + channelControl.panValueDisplay = channelControl.surface.makeCustomValueVariable('panValueDisplay'); channelControl.faderObjectTitle = "" - channelControl.faderValuteTitle = "" + channelControl.faderValueTitle = "" channelControl.faderTouched = 0 // 0 - not touched, 1 - touched channelControl.panObjectTitle = "" channelControl.panValueTitle = "" // Pot encoder - channelControl.pushEncoder = channelControl.surface.makePushEncoder(channelControl.x, y+2, 4, 4) + channelControl.pushEncoder = channelControl.surface.makePushEncoder(channelControl.x, y + 2, 4, 4) channelControl.pushEncoder.mEncoderValue.mMidiBinding .setInputPort(midiInput) @@ -164,26 +168,86 @@ function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { var channelIndex = channelControl.instance channelControl.fader_touch.mSurfaceValue.mOnProcessValueChange = function (context, touched, value2) { - channelControl.faderTouched = touched - if(touched) { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderValueTitle,6))) + switch (activePage) { + case "Mixer": + channelControl.faderTouched = touched + if (touched) { + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderValueTitle, 6))) + } + else { + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderObjectTitle, 6))) + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(channelControl.faderValueTitle, 6))) + } + break; + case "SelectedTrack": + channelControl.faderTouched = touched + if (touched) { + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderValueTitle, 6))) + } + else { + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.trackObjectTitle, 56))) + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(channelControl.faderValueTitle, 6))) + } + break; + default: + console.error("No page specific binding defined") + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel(activePage, 56))) + break; } - else { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderObjectTitle, 6))) - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(channelControl.faderValueTitle, 6))) + } + + channelControl.trackNameDisplay.mOnTitleChange = function (context, objectTitle, valueTitle) { + console.log("Track Title Changed:"+objectTitle) + channelControl.trackObjectTitle = objectTitle + channelControl.trackValueTitle = valueTitle + switch (activePage) { + case "Mixer": + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(objectTitle, 6))) + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(valueTitle, 6))) + break; + case "SelectedTrack": + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.trackObjectTitle, 56))) + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(channelControl.faderValueTitle, 6))) + break; + default: + console.error("No page specific binding defined") + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel(activePage, 56))) + break; } } channelControl.faderValueDisplay.mOnTitleChange = function (context, objectTitle, valueTitle) { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(objectTitle, 6))) - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(valueTitle, 6))) channelControl.faderObjectTitle = objectTitle channelControl.faderValueTitle = valueTitle + switch (activePage) { + case "Mixer": + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(objectTitle, 6))) + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(valueTitle, 6))) + break; + case "SelectedTrack": + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.trackObjectTitle, 56))) + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(channelControl.faderValueTitle, 6))) + break; + default: + console.error("No page specific binding defined") + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel(activePage, 56))) + break; + } } channelControl.faderValueDisplay.mOnDisplayValueChange = function (context, value, units) { - // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderValueTitle))) - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value, 6))) + switch (activePage) { + case "Mixer": + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value, 6))) + break; + case "SelectedTrack": + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value, 6))) + break; + default: + console.error("No page specific binding defined") + // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(0, makeLabel(activePage, 56))) + break; + } } // ! Can't currently find a way to stop the pan mOnTitleChange being triggered when initialised rather than just when its being changed. This stuffs up the display. @@ -199,32 +263,6 @@ function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value,6))) // } - function makeLabel(value, length) { - console.log("makeLabel:"+value) - // Do nothing if the label is already short enough - if (value.length <= length) { - return value - } - - // If to long shorten it by removing vowels and making it CamelCase to remove spaces - var words = value.split(" "); - var label = ""; - - for(var i = 0 , len = words.length; i < len; i++) { - - var currentStr = words[i]; - - var tempStr = currentStr - - // convert first letter to upper case and remove all vowels after first letter - tempStr = tempStr.substr(0, 1).toUpperCase() + tempStr.substr(1).replace(/[aeiou]/gi, ''); - - label +=tempStr; - - } - return label.slice(0, length); // Remove vowels and shorten to 6 char label - } - return channelControl } @@ -304,7 +342,7 @@ function makeTransport(surface, midiInput, midiOutput, x, y) { // The Note on/off events for the special functioans are timestamped at the same time // cubase midi remote doesn't show anything on screen though a note is sent // Flip - Simultaneous press of Pre Chn+Pre Bank - transport.btnFlip = surface.makeButton(x+0.5, y + 15, 2, 2).setShapeCircle() + transport.btnFlip = surface.makeButton(x + 0.5, y + 15, 2, 2).setShapeCircle() bindMidiNote(transport.btnFlip, 0, 50) // Pressing the Zoom keys simultaneously will toggle on and off a note event. If on diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index ff3d4c5..98abf16 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -190,6 +190,7 @@ function makePageMixer() { // ! Ignoring PC side of display for the moment in favour of the D2 displaying what is required page.setLabelFieldHostObject(surfaceElements.channelControls[channelIndex].displayTop, hostMixerBankChannel) // For PC display, Platfomr M+ D2 display coded in icon_elements.js // D2 + page.makeValueBinding(surfaceElements.channelControls[channelIndex].trackNameDisplay, hostMixerBankChannel.mValue.mVolume) page.makeValueBinding(surfaceElements.channelControls[channelIndex].faderValueDisplay, hostMixerBankChannel.mValue.mVolume) // for Platform M+ D2 Display page.makeValueBinding(surfaceElements.channelControls[channelIndex].panValueDisplay, hostMixerBankChannel.mValue.mPan) // for Platform M+ D2 Display @@ -228,6 +229,7 @@ function makePageSelectedTrack() { // Displays page.setLabelFieldHostObject(surfaceElements.channelControls[idx].displayTop, page.mHostAccess.mFocusedQuickControls) // For PC display, Platfomr M+ D2 display coded in icon_elements.js + page.makeValueBinding(surfaceElements.channelControls[idx].trackNameDisplay, selectedTrackChannel.mValue.mVolume) page.makeValueBinding(surfaceElements.channelControls[idx].faderValueDisplay, page.mHostAccess.mFocusedQuickControls.getByIndex(idx)) // for Platform M+ D2 Display page.makeValueBinding(surfaceElements.channelControls[idx].panValueDisplay, selectedTrackChannel.mSends.getByIndex(idx).mLevel) // for Platform M+ D2 Display @@ -389,19 +391,22 @@ function makePageChannelStrip() { var mixerPage = makePageMixer() var selectedTrackPage = makePageSelectedTrack() var channelStripPage = makePageChannelStrip() +var activePage = "Mixer" mixerPage.mOnActivate = function (device) { console.log('from script: Platform M+ page "Mixer" activated') - + activePage="Mixer" clearAllLeds(device, midiOutput) } selectedTrackPage.mOnActivate = function (device) { console.log('from script: Platform M+ page "Selected Track" activated') + activePage="SelectedTrack" clearAllLeds(device, midiOutput) } channelStripPage.mOnActivate = function (device) { console.log('from script: Platform M+ page "Channel Strip" activated') + activePage="ChannelStrip" clearAllLeds(device, midiOutput) } From a15cb833bd45c159b8b25edebe6b6efa22a17391 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 20 Nov 2022 12:20:53 +1100 Subject: [PATCH 33/65] Mixer and Selected Track pages now have reasonable display response - still can't get Pan to play nice as I can't reset the display --- icon/platformmplus/helper.js | 4 ++-- icon/platformmplus/icon_elements.js | 17 ++++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/icon/platformmplus/helper.js b/icon/platformmplus/helper.js index ba45e32..fa94c69 100644 --- a/icon/platformmplus/helper.js +++ b/icon/platformmplus/helper.js @@ -16,9 +16,9 @@ function displaySetTextOfLine(rowIndex, textString) { var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, rowIndex * 56] var blank = Array(56).join(" ") - var text = (textString + blank).slice(0, 50) // ensure to always clear the entire row + var text = (textString + blank).slice(0, 56) // ensure to always clear the entire row // console.log("display:" + text) - for (var i = 0; i < 50; ++i) + for (var i = 0; i < 56; ++i) data.push(text.charCodeAt(i)) data.push(0xf7) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 4cade46..63b7873 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -168,9 +168,9 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance) { var channelIndex = channelControl.instance channelControl.fader_touch.mSurfaceValue.mOnProcessValueChange = function (context, touched, value2) { + channelControl.faderTouched = touched switch (activePage) { case "Mixer": - channelControl.faderTouched = touched if (touched) { midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderValueTitle, 6))) } @@ -180,9 +180,8 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance) { } break; case "SelectedTrack": - channelControl.faderTouched = touched if (touched) { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderValueTitle, 6))) + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.faderValueTitle, 56))) } else { midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.trackObjectTitle, 56))) @@ -191,13 +190,13 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance) { break; default: console.error("No page specific binding defined") - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel(activePage, 56))) + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel("No "+activePage+" specific binding defined", 56))) break; } } channelControl.trackNameDisplay.mOnTitleChange = function (context, objectTitle, valueTitle) { - console.log("Track Title Changed:"+objectTitle) + // console.log("Track Title Changed:"+objectTitle) channelControl.trackObjectTitle = objectTitle channelControl.trackValueTitle = valueTitle switch (activePage) { @@ -211,7 +210,7 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance) { break; default: console.error("No page specific binding defined") - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel(activePage, 56))) + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel("No "+activePage+" specific binding defined", 56))) break; } } @@ -230,7 +229,7 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance) { break; default: console.error("No page specific binding defined") - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel(activePage, 56))) + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel("No "+activePage+" specific binding defined", 56))) break; } } @@ -245,7 +244,7 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance) { break; default: console.error("No page specific binding defined") - // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(0, makeLabel(activePage, 56))) + midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel("No "+activePage+" specific binding defined", 56))) break; } } @@ -339,7 +338,7 @@ function makeTransport(surface, midiInput, midiOutput, x, y) { transport.btnRecord = makeLedButton(surface, midiInput, midiOutput, 95, x, y + 12, w, h, false) transport.btnCycle = makeLedButton(surface, midiInput, midiOutput, 86, x + 3, y + 12, w, h, false) - // The Note on/off events for the special functioans are timestamped at the same time + // The Note on/off events for the special functions are timestamped at the same time // cubase midi remote doesn't show anything on screen though a note is sent // Flip - Simultaneous press of Pre Chn+Pre Bank transport.btnFlip = surface.makeButton(x + 0.5, y + 15, 2, 2).setShapeCircle() From dfe0132b9351aa48365f765dae858e2bf77b562b Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 20 Nov 2022 12:39:01 +1100 Subject: [PATCH 34/65] minor fixes --- icon/platformmplus/icon_platformmplus.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 98abf16..e9cc35d 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -140,7 +140,7 @@ function makePageWithDefaults(name) { // Master Fader // If there is only One output it will be Main // If there is more than one out then this will be the first one - there doesn't appear to be a way to verify this - var outputMixerBanks = page.mHostAccess.mMixConsole.makeMixerBankZone().includeOutputChannels() + var outputMixerBanks = page.mHostAccess.mMixConsole.makeMixerBankZone("OutputBanks").includeOutputChannels() var outputMixerBankChannels = outputMixerBanks.makeMixerBankChannel() page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, outputMixerBankChannels.mValue.mVolume).setValueTakeOverModeJump().setSubPage(subPageMasterFaderMain) page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, page.mHostAccess.mMouseCursor.mValueUnderMouse).setValueTakeOverModeJump().setSubPage(subPageMasterFaderValue) @@ -168,7 +168,7 @@ function makePageMixer() { var ButtonSubPageArea = page.makeSubPageArea('Buttons') var subPageButtonDefaultSet = makeSubPage(ButtonSubPageArea, 'DefaultSet') - var hostMixerBankZone = page.mHostAccess.mMixConsole.makeMixerBankZone() + var hostMixerBankZone = page.mHostAccess.mMixConsole.makeMixerBankZone("AudioInstrBanks") .includeAudioChannels() .includeInstrumentChannels() From b54d37dafe966cea899bc21ab7edabca1546057d Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 20 Nov 2022 13:30:52 +1100 Subject: [PATCH 35/65] stashing minor adjustments --- icon/platformmplus/icon_platformmplus.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index e9cc35d..25358ef 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -38,7 +38,6 @@ deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput) .expectInputNameContains('Platform M+') .expectOutputNameContains('Platform M+') - var surface = deviceDriver.mSurface //----------------------------------------------------------------------------- @@ -171,6 +170,7 @@ function makePageMixer() { var hostMixerBankZone = page.mHostAccess.mMixConsole.makeMixerBankZone("AudioInstrBanks") .includeAudioChannels() .includeInstrumentChannels() + .setFollowVisibility(true) for (var channelIndex = 0; channelIndex < surfaceElements.numStrips; ++channelIndex) { var hostMixerBankChannel = hostMixerBankZone.makeMixerBankChannel() @@ -228,7 +228,7 @@ function makePageSelectedTrack() { var faderSurfaceValue = surfaceElements.channelControls[idx].fader.mSurfaceValue; // Displays - page.setLabelFieldHostObject(surfaceElements.channelControls[idx].displayTop, page.mHostAccess.mFocusedQuickControls) // For PC display, Platfomr M+ D2 display coded in icon_elements.js + // page.setLabelFieldHostObject(surfaceElements.channelControls[idx].displayTop, page.mHostAccess.mFocusedQuickControls) // For PC display, Platfomr M+ D2 display coded in icon_elements.js page.makeValueBinding(surfaceElements.channelControls[idx].trackNameDisplay, selectedTrackChannel.mValue.mVolume) page.makeValueBinding(surfaceElements.channelControls[idx].faderValueDisplay, page.mHostAccess.mFocusedQuickControls.getByIndex(idx)) // for Platform M+ D2 Display page.makeValueBinding(surfaceElements.channelControls[idx].panValueDisplay, selectedTrackChannel.mSends.getByIndex(idx).mLevel) // for Platform M+ D2 Display From 9ee4d7e7b596e8ee9fc2d1c39a8b5512c9f01308 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sat, 26 Nov 2022 16:28:57 +1100 Subject: [PATCH 36/65] Merge branch 'mucking-flip-n-zoom-wip' --- icon/platformmplus/icon_elements.js | 201 +++++++++++++++++------ icon/platformmplus/icon_platformmplus.js | 55 +++++-- 2 files changed, 186 insertions(+), 70 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 63b7873..0def595 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -1,5 +1,53 @@ var helper = require('./helper') var makeLabel = helper.display.makeLabel +var flip = false + +function updateDisplay(activeDevice) { + switch (activePage) { + case "Mixer": + for (var i = 0; i < surfaceElements.numStrips; ++i) { + var element = surfaceElements.channelControls[i] + if (!flip) { + midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 1, makeLabel(element.faderObjectTitle, 6))) + midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel(element.faderValueTitle, 6))) + } + else { + midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 1, makeLabel(element.panObjectTitle, 6))) + midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel(element.panValueTitle, 6))) + } + } + break; + case "SelectedTrack": + var msg = surfaceElements.channelControls[0].trackObjectTitle + if (!flip) { + // For selected track all the trackObjectTitle are set to the same value + // So send it once to the display and use the entire top line for the title + + midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel('QC-' + msg, 56))) + for (var i = 0; i < surfaceElements.numStrips; ++i) { + var element = surfaceElements.channelControls[i] + midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel(element.faderValueTitle, 6))) + } + } + else { + midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("Sends-" + msg, 56))) + for (var i = 0; i < surfaceElements.numStrips; ++i) { + var element = surfaceElements.channelControls[i] + if (element.panPushValue == "On") { + midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel(element.panObjectTitle, 6))) + } else { + midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel("Off", 6))) + } + } + } + break; + default: + console.error("No page specific binding defined") + midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("No " + activePage + " specific binding defined", 56))) + break; + } +} + /** * @param {MR_DeviceSurface} surface * @param {String} name @@ -18,6 +66,7 @@ function makeLedButton(surface, midiInput, midiOutput, note, x, y, w, h, circle) button.setShapeCircle() } button.mSurfaceValue.mOnProcessValueChange = function (activeDevice) { + // console.log("LedButton ProcessValue Change:"+button.mSurfaceValue.getProcessValue(activeDevice)) if (button.mSurfaceValue.getProcessValue(activeDevice) > 0) midiOutput.sendMidi(activeDevice, [0x90, note, 127]) else { @@ -126,19 +175,19 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance) { channelControl.instance = instance; // Channel number, 1-8 // Channel Displays - channelControl.displayTop = channelControl.surface.makeLabelField(channelControl.x, 1, 7, 2) - channelControl.displayBottom = channelControl.surface.makeLabelField(channelControl.x, 3, 7, 2) - channelControl.trackNameDisplay = channelControl.surface.makeCustomValueVariable('trackNameDisplay'); channelControl.trackObjectTitle = "" channelControl.trackValueTitle = "" - channelControl.faderValueDisplay = channelControl.surface.makeCustomValueVariable('faderValueDisplay'); - channelControl.panValueDisplay = channelControl.surface.makeCustomValueVariable('panValueDisplay'); + channelControl.faderTitlesDisplay = channelControl.surface.makeCustomValueVariable('faderTitlesDisplay'); + channelControl.panTitlesDisplay = channelControl.surface.makeCustomValueVariable('panTitlesDisplay'); channelControl.faderObjectTitle = "" channelControl.faderValueTitle = "" + channelControl.faderValue = "" channelControl.faderTouched = 0 // 0 - not touched, 1 - touched channelControl.panObjectTitle = "" channelControl.panValueTitle = "" + channelControl.panValue = "" + channelControl.panPushValue = "" // Pot encoder channelControl.pushEncoder = channelControl.surface.makePushEncoder(channelControl.x, y + 2, 4, 4) @@ -167,100 +216,105 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance) { var channelIndex = channelControl.instance - channelControl.fader_touch.mSurfaceValue.mOnProcessValueChange = function (context, touched, value2) { + channelControl.trackNameDisplay.mOnTitleChange = function (activeDevice, objectTitle, valueTitle) { + channelControl.trackObjectTitle = objectTitle + channelControl.trackValueTitle = valueTitle + // console.log("Track Title Changed:"+objectTitle+":"+valueTitle) + updateDisplay(activeDevice) + } + + channelControl.faderTitlesDisplay.mOnTitleChange = function (activeDevice, objectTitle, valueTitle) { + channelControl.faderObjectTitle = objectTitle + channelControl.faderValueTitle = valueTitle + console.log("Fader Title Changed:" + objectTitle + ":" + valueTitle) + updateDisplay(activeDevice) + } + + channelControl.fader_touch.mSurfaceValue.mOnProcessValueChange = function (activeDevice, touched, value2) { channelControl.faderTouched = touched switch (activePage) { case "Mixer": if (touched) { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderValueTitle, 6))) + midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderValueTitle, 6))) } else { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderObjectTitle, 6))) - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(channelControl.faderValueTitle, 6))) + updateDisplay(activeDevice) } break; case "SelectedTrack": if (touched) { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.faderValueTitle, 56))) + midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.faderValueTitle, 56))) } else { - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.trackObjectTitle, 56))) - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(channelControl.faderValueTitle, 6))) + updateDisplay(activeDevice) } break; default: - console.error("No page specific binding defined") - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel("No "+activePage+" specific binding defined", 56))) + console.log("No page specific binding defined") + midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("No " + activePage + " specific binding defined", 56))) break; } } - channelControl.trackNameDisplay.mOnTitleChange = function (context, objectTitle, valueTitle) { - // console.log("Track Title Changed:"+objectTitle) - channelControl.trackObjectTitle = objectTitle - channelControl.trackValueTitle = valueTitle + channelControl.faderTitlesDisplay.mOnDisplayValueChange = function (activeDevice, value, units) { + console.log("Fader Value Change: " + value + ":" + units) + channelControl.faderValue = value switch (activePage) { case "Mixer": - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(objectTitle, 6))) - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(valueTitle, 6))) + midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value, 6))) break; case "SelectedTrack": - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.trackObjectTitle, 56))) - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(channelControl.faderValueTitle, 6))) + midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value, 6))) break; default: - console.error("No page specific binding defined") - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel("No "+activePage+" specific binding defined", 56))) + console.log("No page specific binding defined") + midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("No " + activePage + " specific binding defined", 56))) break; } } - channelControl.faderValueDisplay.mOnTitleChange = function (context, objectTitle, valueTitle) { - channelControl.faderObjectTitle = objectTitle - channelControl.faderValueTitle = valueTitle + channelControl.panTitlesDisplay.mOnTitleChange = function (activeDevice, objectTitle, valueTitle) { + channelControl.panObjectTitle = objectTitle + channelControl.panValueTitle = valueTitle + console.log("Pan Title Changed:" + objectTitle + ":" + valueTitle) + switch (activePage) { - case "Mixer": - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(objectTitle, 6))) - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(valueTitle, 6))) - break; case "SelectedTrack": - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.trackObjectTitle, 56))) - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(channelControl.faderValueTitle, 6))) + // For selected track trime the send channel number since it's lined up with the Platform M+ numbering anyway + channelControl.panObjectTitle = channelControl.panObjectTitle.slice(3) break; default: - console.error("No page specific binding defined") - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel("No "+activePage+" specific binding defined", 56))) + console.log("No page specific binding defined") + // do nothing break; } + updateDisplay(activeDevice) } - channelControl.faderValueDisplay.mOnDisplayValueChange = function (context, value, units) { + channelControl.panTitlesDisplay.mOnDisplayValueChange = function (activeDevice, value, units) { + console.log("Pan Value Change: " + value + ":" + units) + channelControl.panValue = value switch (activePage) { case "Mixer": - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value, 6))) + midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value, 6))) break; case "SelectedTrack": - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value, 6))) + midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel('Sends-'+channelControl.trackObjectTitle +"-" +channelControl.panObjectTitle, 56))) + midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value, 6))) break; default: - console.error("No page specific binding defined") - midiOutput.sendMidi(context, helper.sysex.displaySetTextOfLine(1, makeLabel("No "+activePage+" specific binding defined", 56))) + console.log("No page specific binding defined") + midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("No " + activePage + " specific binding defined", 56))) break; } } - // ! Can't currently find a way to stop the pan mOnTitleChange being triggered when initialised rather than just when its being changed. This stuffs up the display. - // channelControl.panValueDisplay.mOnTitleChange = function (context, objectTitle, valueTitle) { - // // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(objectTitle))) - // // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(valueTitle))) - // channelControl.panObjectTitle = "objectTitle" - // channelControl.panValueTitle = "valueTitle" - // } - - // channelControl.panValueDisplay.mOnDisplayValueChange = function (context, value, units) { - // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel("Pan",6))) - // midiOutput.sendMidi(context, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value,6))) - // } + // ! Hmm, I wonder if my use of the *TitlesDisplay custom variables is unnecessary based on this one + channelControl.pushEncoder.mPushValue.mOnDisplayValueChange = function (activeDevice, value, units) { + console.log("Pan push Value Change: " + value + ":" + units) + channelControl.panPushValue = value + updateDisplay(activeDevice) + } return channelControl @@ -344,12 +398,50 @@ function makeTransport(surface, midiInput, midiOutput, x, y) { transport.btnFlip = surface.makeButton(x + 0.5, y + 15, 2, 2).setShapeCircle() bindMidiNote(transport.btnFlip, 0, 50) + transport.btnFlip.mSurfaceValue.mOnProcessValueChange = function (activeDevice, number1, number2) { + flip = !flip + updateDisplay(activeDevice) + console.log("transport flip: " + flip) + } + // Pressing the Zoom keys simultaneously will toggle on and off a note event. If on // either zoom button will send a Note 100 when zoom is activated or deactivated by either button // If zoom is active and you simply press then other button the event will not be sent // transport.btnZoomOnOff = surface.makeButton(x + 3.5, y + 15, 2, 2).setShapeCircle() - bindMidiNote(transport.btnZoomOnOff, 0, 100) + // bindMidiNote(transport.btnZoomOnOff, 0, 100) + transport.zoomState = surface.makeCustomValueVariable('ZoomState'); + transport.zoomState.mMidiBinding.setInputPort(midiInput).bindToNote(0, 100) + transport.zoomState.mOnProcessValueChange = function (activeDevice, number1, number2) { + + console.log("zoomState: " + number1 + ":" + number2) + // switch (activePage) { + // case "Mixer": + // if (touched) { + // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderValueTitle, 6))) + // } + // else { + // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderObjectTitle, 6))) + // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(channelControl.faderValueTitle, 6))) + // } + // break; + // case "SelectedTrack": + // if (touched) { + // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.faderValueTitle, 56))) + // } + // else { + // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.trackObjectTitle, 56))) + // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(channelControl.faderValueTitle, 6))) + // } + // break; + // default: + // console.error("No page specific binding defined") + // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("No "+activePage+" specific binding defined", 56))) + // break; + // } + + } + // The Jog wheel will change CC/Note based on which of thte Zoom buttons have been activated // None - CC 60 @@ -400,5 +492,6 @@ module.exports = { makeLedButton, makeTouchFader, bindCommandKnob, - clearAllLeds + clearAllLeds, + updateDisplay } diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 25358ef..0d89468 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -9,6 +9,7 @@ var makeChannelControl = iconElements.makeChannelControl var makeMasterControl = iconElements.makeMasterControl var makeTransport = iconElements.makeTransport var clearAllLeds = iconElements.clearAllLeds +var updateDisplay = iconElements.updateDisplay //----------------------------------------------------------------------------- // 1. DRIVER SETUP - create driver object, midi ports and detection information @@ -79,6 +80,14 @@ function makeSubPage(subPageArea, name) { var msgText = 'sub page ' + name + ' activated' subPage.mOnActivate = function (activeDevice) { console.log(msgText) + switch (name) { + case "MF_MainOut": + midiOutput.sendMidi(activeDevice, [0x90, 84, 127]) + break; + case "MF_ValueUnderCursor": + midiOutput.sendMidi(activeDevice, [0x90, 84, 0]) + break; + } } return subPage } @@ -119,6 +128,7 @@ function makePageWithDefaults(name) { page.makeCommandBinding(surfaceElements.transport.zoomHorizOut.mSurfaceValue, 'Transport', 'Locate Previous Event').setSubPage(subPageJobNav) // Switch Zoom and Nav via simultaneous press of Zoom buttons page.makeActionBinding(surfaceElements.transport.btnZoomOnOff.mSurfaceValue, zoomSubPageArea.mAction.mNext) + // page.makeActionBinding(surfaceElements.transport.zoomState.mSurfaceValue, zoomSubPageArea.mAction.mNext) // Jog Pages - when Zoom lights are off // Nudge @@ -131,21 +141,19 @@ function makePageWithDefaults(name) { page.makeActionBinding(surfaceElements.transport.jog_wheel.mPushValue, jogSubPageArea.mAction.mNext) var MasterFaderSubPageArea = page.makeSubPageArea('MasterFader') - var subPageMasterFaderMain = makeSubPage(MasterFaderSubPageArea, 'MF_MainOut') - var subPageMasterFaderHeadphone = makeSubPage(MasterFaderSubPageArea, 'MF_HeadphoneOut') - var subPageMasterCMain = makeSubPage(MasterFaderSubPageArea, 'MF_CMain') var subPageMasterFaderValue = makeSubPage(MasterFaderSubPageArea, 'MF_ValueUnderCursor') + var subPageMasterFaderMain = makeSubPage(MasterFaderSubPageArea, 'MF_MainOut') + // Master Fader // If there is only One output it will be Main // If there is more than one out then this will be the first one - there doesn't appear to be a way to verify this var outputMixerBanks = page.mHostAccess.mMixConsole.makeMixerBankZone("OutputBanks").includeOutputChannels() var outputMixerBankChannels = outputMixerBanks.makeMixerBankChannel() - page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, outputMixerBankChannels.mValue.mVolume).setValueTakeOverModeJump().setSubPage(subPageMasterFaderMain) page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, page.mHostAccess.mMouseCursor.mValueUnderMouse).setValueTakeOverModeJump().setSubPage(subPageMasterFaderValue) - page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, page.mHostAccess.mControlRoom.getPhonesChannelByIndex(0).mLevelValue).setValueTakeOverModeJump().setSubPage(subPageMasterFaderHeadphone) - page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, page.mHostAccess.mControlRoom.mMainChannel.mLevelValue).setValueTakeOverModeJump().setSubPage(subPageMasterCMain) - // Switch Master Fader to Main Out->Headphone->Value Under Cursor (AI) + page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, outputMixerBankChannels.mValue.mVolume).setValueTakeOverModeJump().setSubPage(subPageMasterFaderMain) + + // Switch Master Fader to Main Out<->Value Under Cursor (AI) page.makeActionBinding(surfaceElements.faderMaster.mixer_button.mSurfaceValue, MasterFaderSubPageArea.mAction.mNext) // Automation for selected tracks @@ -185,14 +193,10 @@ function makePageMixer() { var rec_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].rec_button.mSurfaceValue; // Displays - // PC - // ? There doesn't appear to be a way via relateTo to connect the label surface elements to valueTitle or arbitrarily change them around - // ! Ignoring PC side of display for the moment in favour of the D2 displaying what is required - page.setLabelFieldHostObject(surfaceElements.channelControls[channelIndex].displayTop, hostMixerBankChannel) // For PC display, Platfomr M+ D2 display coded in icon_elements.js // D2 page.makeValueBinding(surfaceElements.channelControls[channelIndex].trackNameDisplay, hostMixerBankChannel.mValue.mVolume) - page.makeValueBinding(surfaceElements.channelControls[channelIndex].faderValueDisplay, hostMixerBankChannel.mValue.mVolume) // for Platform M+ D2 Display - page.makeValueBinding(surfaceElements.channelControls[channelIndex].panValueDisplay, hostMixerBankChannel.mValue.mPan) // for Platform M+ D2 Display + page.makeValueBinding(surfaceElements.channelControls[channelIndex].faderTitlesDisplay, hostMixerBankChannel.mValue.mVolume) // for Platform M+ D2 Display + page.makeValueBinding(surfaceElements.channelControls[channelIndex].panTitlesDisplay, hostMixerBankChannel.mValue.mPan) // for Platform M+ D2 Display // FaderKnobs - Volume, Pan, Editor Open page.makeValueBinding(knobSurfaceValue, hostMixerBankChannel.mValue.mPan).setSubPage(subPageFaderVolume) @@ -228,10 +232,9 @@ function makePageSelectedTrack() { var faderSurfaceValue = surfaceElements.channelControls[idx].fader.mSurfaceValue; // Displays - // page.setLabelFieldHostObject(surfaceElements.channelControls[idx].displayTop, page.mHostAccess.mFocusedQuickControls) // For PC display, Platfomr M+ D2 display coded in icon_elements.js page.makeValueBinding(surfaceElements.channelControls[idx].trackNameDisplay, selectedTrackChannel.mValue.mVolume) - page.makeValueBinding(surfaceElements.channelControls[idx].faderValueDisplay, page.mHostAccess.mFocusedQuickControls.getByIndex(idx)) // for Platform M+ D2 Display - page.makeValueBinding(surfaceElements.channelControls[idx].panValueDisplay, selectedTrackChannel.mSends.getByIndex(idx).mLevel) // for Platform M+ D2 Display + page.makeValueBinding(surfaceElements.channelControls[idx].faderTitlesDisplay, page.mHostAccess.mFocusedQuickControls.getByIndex(idx)) // for Platform M+ D2 Display + page.makeValueBinding(surfaceElements.channelControls[idx].panTitlesDisplay, selectedTrackChannel.mSends.getByIndex(idx).mLevel) // for Platform M+ D2 Display page.makeValueBinding(knobSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mLevel).setSubPage(subPageSendsQC) page.makeValueBinding(knobPushValue, selectedTrackChannel.mSends.getByIndex(idx).mOn).setTypeToggle().setSubPage(subPageSendsQC) @@ -392,21 +395,41 @@ var mixerPage = makePageMixer() var selectedTrackPage = makePageSelectedTrack() var channelStripPage = makePageChannelStrip() var activePage = "Mixer" +var activeSubPage = "Nudge" +// Function to clear out the Channel State for the display titles/values +// the OnDisplayChange callback is not called if the Channel doesn't have an updated +// Title. So swtiching to QC would leave the old Mixer Page "Volume" title kicking around +// in the state. By clearing state on the page activation it will update all that are changing. +function clearChannelState() { + for (var i = 0; i < surfaceElements.numStrips; ++i) { + surfaceElements.channelControls[i].faderObjectTitle = "" + surfaceElements.channelControls[i].faderValueTitle = "" + surfaceElements.channelControls[i].faderValue = "" + surfaceElements.channelControls[i].panObjectTitle = "" + surfaceElements.channelControls[i].panValueTitle = "" + surfaceElements.channelControls[i].panValue = "" + surfaceElements.channelControls[i].panPushValue = "" + } +} mixerPage.mOnActivate = function (device) { console.log('from script: Platform M+ page "Mixer" activated') activePage="Mixer" clearAllLeds(device, midiOutput) + clearChannelState() } selectedTrackPage.mOnActivate = function (device) { console.log('from script: Platform M+ page "Selected Track" activated') activePage="SelectedTrack" clearAllLeds(device, midiOutput) + clearChannelState() } channelStripPage.mOnActivate = function (device) { console.log('from script: Platform M+ page "Channel Strip" activated') activePage="ChannelStrip" clearAllLeds(device, midiOutput) + clearChannelState() } + From 0e82004651c0f7bfdaff370583d0c31ec97add8f Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 27 Nov 2022 10:20:46 +1100 Subject: [PATCH 37/65] fix formatting --- icon/platformmplus/icon_elements.js | 2 +- icon/platformmplus/icon_platformmplus.js | 30 ++++++++++++------------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 0def595..5f5bfdd 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -299,7 +299,7 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance) { midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value, 6))) break; case "SelectedTrack": - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel('Sends-'+channelControl.trackObjectTitle +"-" +channelControl.panObjectTitle, 56))) + midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel('Sends-' + channelControl.trackObjectTitle + "-" + channelControl.panObjectTitle, 56))) midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value, 6))) break; default: diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 0d89468..ac724cb 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -48,7 +48,7 @@ function makeSurfaceElements() { var surfaceElements = {} // Display - 2lines - surfaceElements.d2Display = surface.makeBlindPanel(0,0,56,6) + surfaceElements.d2Display = surface.makeBlindPanel(0, 0, 56, 6) surfaceElements.numStrips = 8 @@ -61,7 +61,7 @@ function makeSurfaceElements() { surfaceElements.channelControls[i] = makeChannelControl(surface, midiInput, midiOutput, xKnobStrip, yKnobStrip, i) } - surfaceElements.faderMaster = makeMasterControl(surface, midiInput, midiOutput, xKnobStrip + 1, yKnobStrip+4, surfaceElements.numStrips) + surfaceElements.faderMaster = makeMasterControl(surface, midiInput, midiOutput, xKnobStrip + 1, yKnobStrip + 4, surfaceElements.numStrips) surfaceElements.transport = makeTransport(surface, midiInput, midiOutput, xKnobStrip + 63, yKnobStrip + 4) return surfaceElements @@ -274,9 +274,9 @@ function makePageSelectedTrack() { eqBand[3] = selectedTrackChannel.mChannelEQ.mBand4 for (var idx = 0; idx < 4; ++idx) { var knobSurfaceValue = surfaceElements.channelControls[idx].pushEncoder.mEncoderValue; - var knob2SurfaceValue = surfaceElements.channelControls[idx+4].pushEncoder.mEncoderValue; + var knob2SurfaceValue = surfaceElements.channelControls[idx + 4].pushEncoder.mEncoderValue; var knobPushValue = surfaceElements.channelControls[idx].pushEncoder.mPushValue; - var knob2PushValue = surfaceElements.channelControls[idx+4].pushEncoder.mPushValue; + var knob2PushValue = surfaceElements.channelControls[idx + 4].pushEncoder.mPushValue; var faderSurfaceValue = surfaceElements.channelControls[idx].fader.mSurfaceValue; var fader2SurfaceValue = surfaceElements.channelControls[idx + 4].fader.mSurfaceValue; @@ -323,14 +323,14 @@ function makePageSelectedTrack() { page.makeValueBinding(surfaceElements.channelControls[1].sel_button.mSurfaceValue, preFilter.mHighCutOn).setTypeToggle().setSubPage(subPagePreFilter) page.makeValueBinding(surfaceElements.channelControls[2].sel_button.mSurfaceValue, preFilter.mLowCutOn).setTypeToggle().setSubPage(subPagePreFilter) - page.makeValueBinding(knob2SurfaceValue, preFilter.mHighCutSlope ).setSubPage(subPagePreFilter) - page.makeValueBinding(knob3SurfaceValue, preFilter.mLowCutSlope ).setSubPage(subPagePreFilter) - page.makeValueBinding(knobPushValue, preFilter.mBypass ).setTypeToggle().setSubPage(subPagePreFilter) - page.makeValueBinding(knob2PushValue, preFilter.mHighCutOn ).setTypeToggle().setSubPage(subPagePreFilter) - page.makeValueBinding(knob3PushValue, preFilter.mLowCutOn ).setTypeToggle().setSubPage(subPagePreFilter) + page.makeValueBinding(knob2SurfaceValue, preFilter.mHighCutSlope).setSubPage(subPagePreFilter) + page.makeValueBinding(knob3SurfaceValue, preFilter.mLowCutSlope).setSubPage(subPagePreFilter) + page.makeValueBinding(knobPushValue, preFilter.mBypass).setTypeToggle().setSubPage(subPagePreFilter) + page.makeValueBinding(knob2PushValue, preFilter.mHighCutOn).setTypeToggle().setSubPage(subPagePreFilter) + page.makeValueBinding(knob3PushValue, preFilter.mLowCutOn).setTypeToggle().setSubPage(subPagePreFilter) page.makeValueBinding(faderSurfaceValue, preFilter.mGain).setSubPage(subPagePreFilter) - page.makeValueBinding(fader2SurfaceValue, preFilter.mHighCutFreq ).setSubPage(subPagePreFilter) - page.makeValueBinding(fader3SurfaceValue, preFilter.mLowCutFreq ).setSubPage(subPagePreFilter) + page.makeValueBinding(fader2SurfaceValue, preFilter.mHighCutFreq).setSubPage(subPagePreFilter) + page.makeValueBinding(fader3SurfaceValue, preFilter.mLowCutFreq).setSubPage(subPagePreFilter) return page } @@ -361,7 +361,7 @@ function makePageChannelStrip() { page.makeValueBinding(faderSurfaceValue, stripEffects.mLimiter.mParameterBankZone.makeParameterValue()).setSubPage(limiterPage) } - for (var idx = 0; idx < 5; ++idx) { + for (var idx = 0; idx < 5; ++idx) { var faderStrip = surfaceElements.channelControls[idx] var type = ['mGate', 'mCompressor', 'mTools', 'mSaturator', 'mLimiter'][idx] page.makeValueBinding(faderStrip.rec_button.mSurfaceValue, stripEffects[type].mOn).setTypeToggle() @@ -414,21 +414,21 @@ function clearChannelState() { } mixerPage.mOnActivate = function (device) { console.log('from script: Platform M+ page "Mixer" activated') - activePage="Mixer" + activePage = "Mixer" clearAllLeds(device, midiOutput) clearChannelState() } selectedTrackPage.mOnActivate = function (device) { console.log('from script: Platform M+ page "Selected Track" activated') - activePage="SelectedTrack" + activePage = "SelectedTrack" clearAllLeds(device, midiOutput) clearChannelState() } channelStripPage.mOnActivate = function (device) { console.log('from script: Platform M+ page "Channel Strip" activated') - activePage="ChannelStrip" + activePage = "ChannelStrip" clearAllLeds(device, midiOutput) clearChannelState() } From f36ac4406fbc115b7e2b83b86cfda56b10754d13 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 27 Nov 2022 10:59:44 +1100 Subject: [PATCH 38/65] Mixer button now changes display from knobs to faders - the Flip button was to unreliable for my taste As a result the Master Fader is now ALWAYS the AI control --- icon/platformmplus/icon_elements.js | 21 ++++++++++++++++++--- icon/platformmplus/icon_platformmplus.js | 10 +++++----- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 5f5bfdd..3886723 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -3,6 +3,11 @@ var makeLabel = helper.display.makeLabel var flip = false function updateDisplay(activeDevice) { + if(flip) { + midiOutput.sendMidi(activeDevice, [0x90, 84, 127]) // Mixer + } else { + midiOutput.sendMidi(activeDevice, [0x90, 84, 0]) // Mixer + } switch (activePage) { case "Mixer": for (var i = 0; i < surfaceElements.numStrips; ++i) { @@ -86,7 +91,7 @@ function clearAllLeds(activeDevice, midiOutput) { midiOutput.sendMidi(activeDevice, [0x90, 0 + i, 0]) } // Master Fader buttons - midiOutput.sendMidi(activeDevice, [0x90, 84, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 84, 0]) // Mixer midiOutput.sendMidi(activeDevice, [0x90, 74, 0]) midiOutput.sendMidi(activeDevice, [0x90, 75, 0]) @@ -338,7 +343,6 @@ function makeMasterControl(surface, midiInput, midiOutput, x, y, instance) { masterControl.x = x + 7 * instance; masterControl.y = y; masterControl.instance = instance; // 9 - Master - masterControl.ident = function () { return ("Class masterControl"); } @@ -354,7 +358,18 @@ function makeMasterControl(surface, midiInput, midiOutput, x, y, instance) { masterControl.mixer_button = makeLedButton(surface, midiInput, midiOutput, 84, fader_x + 3, fader_y + 6, 3, 3, false) masterControl.read_button = makeLedButton(surface, midiInput, midiOutput, 74, fader_x + 3, fader_y + 9, 3, 3, false) masterControl.write_button = makeLedButton(surface, midiInput, midiOutput, 75, fader_x + 3, fader_y + 12, 3, 3, false) - + masterControl.mixer_button.mSurfaceValue.mOnProcessValueChange = function (activeDevice) { + var value = masterControl.mixer_button.mSurfaceValue.getProcessValue(activeDevice) + if (value == 1) { + flip = !flip + if (flip) + midiOutput.sendMidi(activeDevice, [0x90, 84, 127]) + else { + midiOutput.sendMidi(activeDevice, [0x90, 84, 0]) + } + updateDisplay(activeDevice) + } + } return masterControl } diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index ac724cb..dc19a37 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -142,19 +142,19 @@ function makePageWithDefaults(name) { var MasterFaderSubPageArea = page.makeSubPageArea('MasterFader') var subPageMasterFaderValue = makeSubPage(MasterFaderSubPageArea, 'MF_ValueUnderCursor') - var subPageMasterFaderMain = makeSubPage(MasterFaderSubPageArea, 'MF_MainOut') + // var subPageMasterFaderMain = makeSubPage(MasterFaderSubPageArea, 'MF_MainOut') // Master Fader // If there is only One output it will be Main // If there is more than one out then this will be the first one - there doesn't appear to be a way to verify this - var outputMixerBanks = page.mHostAccess.mMixConsole.makeMixerBankZone("OutputBanks").includeOutputChannels() - var outputMixerBankChannels = outputMixerBanks.makeMixerBankChannel() + // var outputMixerBanks = page.mHostAccess.mMixConsole.makeMixerBankZone("OutputBanks").includeOutputChannels() + // var outputMixerBankChannels = outputMixerBanks.makeMixerBankChannel() page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, page.mHostAccess.mMouseCursor.mValueUnderMouse).setValueTakeOverModeJump().setSubPage(subPageMasterFaderValue) - page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, outputMixerBankChannels.mValue.mVolume).setValueTakeOverModeJump().setSubPage(subPageMasterFaderMain) + // page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, outputMixerBankChannels.mValue.mVolume).setValueTakeOverModeJump().setSubPage(subPageMasterFaderMain) // Switch Master Fader to Main Out<->Value Under Cursor (AI) - page.makeActionBinding(surfaceElements.faderMaster.mixer_button.mSurfaceValue, MasterFaderSubPageArea.mAction.mNext) + // page.makeActionBinding(surfaceElements.faderMaster.mixer_button.mSurfaceValue, MasterFaderSubPageArea.mAction.mNext) // Automation for selected tracks var selectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel From 0ee8aba1231adbd838b0bc873351ada69f3790d8 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 27 Nov 2022 11:32:10 +1100 Subject: [PATCH 39/65] Minor change to update display --- icon/platformmplus/icon_elements.js | 10 ++++------ icon/platformmplus/icon_platformmplus.js | 10 +--------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 3886723..d3ec288 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -3,11 +3,6 @@ var makeLabel = helper.display.makeLabel var flip = false function updateDisplay(activeDevice) { - if(flip) { - midiOutput.sendMidi(activeDevice, [0x90, 84, 127]) // Mixer - } else { - midiOutput.sendMidi(activeDevice, [0x90, 84, 0]) // Mixer - } switch (activePage) { case "Mixer": for (var i = 0; i < surfaceElements.numStrips; ++i) { @@ -15,19 +10,21 @@ function updateDisplay(activeDevice) { if (!flip) { midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 1, makeLabel(element.faderObjectTitle, 6))) midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel(element.faderValueTitle, 6))) + midiOutput.sendMidi(activeDevice, [0x90, 84, 0]) // Mixer } else { midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 1, makeLabel(element.panObjectTitle, 6))) midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel(element.panValueTitle, 6))) + midiOutput.sendMidi(activeDevice, [0x90, 84, 127]) // Mixer } } break; case "SelectedTrack": var msg = surfaceElements.channelControls[0].trackObjectTitle if (!flip) { + midiOutput.sendMidi(activeDevice, [0x90, 84, 0]) // Mixer // For selected track all the trackObjectTitle are set to the same value // So send it once to the display and use the entire top line for the title - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel('QC-' + msg, 56))) for (var i = 0; i < surfaceElements.numStrips; ++i) { var element = surfaceElements.channelControls[i] @@ -35,6 +32,7 @@ function updateDisplay(activeDevice) { } } else { + midiOutput.sendMidi(activeDevice, [0x90, 84, 127]) // Mixer midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("Sends-" + msg, 56))) for (var i = 0; i < surfaceElements.numStrips; ++i) { var element = surfaceElements.channelControls[i] diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index dc19a37..90c1bf6 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -145,16 +145,8 @@ function makePageWithDefaults(name) { // var subPageMasterFaderMain = makeSubPage(MasterFaderSubPageArea, 'MF_MainOut') - // Master Fader - // If there is only One output it will be Main - // If there is more than one out then this will be the first one - there doesn't appear to be a way to verify this - // var outputMixerBanks = page.mHostAccess.mMixConsole.makeMixerBankZone("OutputBanks").includeOutputChannels() - // var outputMixerBankChannels = outputMixerBanks.makeMixerBankChannel() + // Master Fader changes display detail page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, page.mHostAccess.mMouseCursor.mValueUnderMouse).setValueTakeOverModeJump().setSubPage(subPageMasterFaderValue) - // page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, outputMixerBankChannels.mValue.mVolume).setValueTakeOverModeJump().setSubPage(subPageMasterFaderMain) - - // Switch Master Fader to Main Out<->Value Under Cursor (AI) - // page.makeActionBinding(surfaceElements.faderMaster.mixer_button.mSurfaceValue, MasterFaderSubPageArea.mAction.mNext) // Automation for selected tracks var selectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel From 77cae0b62b2646273f34ba488ecc96e5f319df57 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 27 Nov 2022 11:36:34 +1100 Subject: [PATCH 40/65] A non-specific binding is not an error --- icon/platformmplus/icon_elements.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index d3ec288..7fdaa59 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -45,7 +45,7 @@ function updateDisplay(activeDevice) { } break; default: - console.error("No page specific binding defined") + console.log("No page specific binding defined") midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("No " + activePage + " specific binding defined", 56))) break; } @@ -448,7 +448,7 @@ function makeTransport(surface, midiInput, midiOutput, x, y) { // } // break; // default: - // console.error("No page specific binding defined") + // console.log("No page specific binding defined") // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("No "+activePage+" specific binding defined", 56))) // break; // } From f6b7b5566273767d7c2cf0f910f3aa9760cc8f4f Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 27 Nov 2022 11:37:04 +1100 Subject: [PATCH 41/65] Remove left over code from mixer button - no longer switching this way --- icon/platformmplus/icon_platformmplus.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 90c1bf6..58a2110 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -80,14 +80,6 @@ function makeSubPage(subPageArea, name) { var msgText = 'sub page ' + name + ' activated' subPage.mOnActivate = function (activeDevice) { console.log(msgText) - switch (name) { - case "MF_MainOut": - midiOutput.sendMidi(activeDevice, [0x90, 84, 127]) - break; - case "MF_ValueUnderCursor": - midiOutput.sendMidi(activeDevice, [0x90, 84, 0]) - break; - } } return subPage } From bf454c103e165805df08c313a3d1fce5299eb5af Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 27 Nov 2022 12:08:19 +1100 Subject: [PATCH 42/65] A first cut at some display feedback for the Jog wheel - Last letter on first line will show the current Zoom function for the jog wheel - it will only be correct when either of the zoom buttons are first pressed. When the buttons are disabled it will return to Z (unfortunately). As soon as you activate again it will be Z - zoom, or N - Nav depending on what the actual underlying state is (which is flipped by pressing both Zoom buttons at the same time as shown on the Platform M+ display) The second line last letter will show S (Scrub) or J (Jog) when the Zoom lights are both off and the Jog wheel is pushed. Thus showing what mode you are in. WIP - trying to figure out if there is a way to do this more sanely. Unfortunately the MCU setting for zoom is only sent when zoom is first activated. This needs to be translated into some form of state machine in MIDI Remote script. --- icon/platformmplus/icon_elements.js | 64 ++++++++++++------------ icon/platformmplus/icon_platformmplus.js | 24 +++++++++ 2 files changed, 56 insertions(+), 32 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 7fdaa59..8a727f1 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -422,38 +422,38 @@ function makeTransport(surface, midiInput, midiOutput, x, y) { // If zoom is active and you simply press then other button the event will not be sent // transport.btnZoomOnOff = surface.makeButton(x + 3.5, y + 15, 2, 2).setShapeCircle() - // bindMidiNote(transport.btnZoomOnOff, 0, 100) - transport.zoomState = surface.makeCustomValueVariable('ZoomState'); - transport.zoomState.mMidiBinding.setInputPort(midiInput).bindToNote(0, 100) - transport.zoomState.mOnProcessValueChange = function (activeDevice, number1, number2) { - - console.log("zoomState: " + number1 + ":" + number2) - // switch (activePage) { - // case "Mixer": - // if (touched) { - // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderValueTitle, 6))) - // } - // else { - // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderObjectTitle, 6))) - // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(channelControl.faderValueTitle, 6))) - // } - // break; - // case "SelectedTrack": - // if (touched) { - // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.faderValueTitle, 56))) - // } - // else { - // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.trackObjectTitle, 56))) - // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(channelControl.faderValueTitle, 6))) - // } - // break; - // default: - // console.log("No page specific binding defined") - // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("No "+activePage+" specific binding defined", 56))) - // break; - // } - - } + bindMidiNote(transport.btnZoomOnOff, 0, 100) + // transport.zoomState = surface.makeCustomValueVariable('ZoomState'); + // transport.zoomState.mMidiBinding.setInputPort(midiInput).bindToNote(0, 100) + // transport.zoomState.mOnProcessValueChange = function (activeDevice, number1, number2) { + + // console.log("zoomState: " + number1 + ":" + number2) + // // switch (activePage) { + // // case "Mixer": + // // if (touched) { + // // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderValueTitle, 6))) + // // } + // // else { + // // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderObjectTitle, 6))) + // // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(channelControl.faderValueTitle, 6))) + // // } + // // break; + // // case "SelectedTrack": + // // if (touched) { + // // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.faderValueTitle, 56))) + // // } + // // else { + // // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.trackObjectTitle, 56))) + // // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(channelControl.faderValueTitle, 6))) + // // } + // // break; + // // default: + // // console.log("No page specific binding defined") + // // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("No "+activePage+" specific binding defined", 56))) + // // break; + // // } + + // } // The Jog wheel will change CC/Note based on which of thte Zoom buttons have been activated diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 58a2110..e28a972 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -80,6 +80,30 @@ function makeSubPage(subPageArea, name) { var msgText = 'sub page ' + name + ' activated' subPage.mOnActivate = function (activeDevice) { console.log(msgText) + var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, + ] + switch (name) { + case "Scrub": + var out = data.concat(55, "S".charCodeAt(0)) + out.push(0xf7) + midiOutput.sendMidi(activeDevice, out) + break; + case "Nudge": + var out = data.concat(55, "N".charCodeAt(0)) + out.push(0xf7) + midiOutput.sendMidi(activeDevice, out) + break; + case "Nav": + var out = data.concat(111, "N".charCodeAt(0)) + out.push(0xf7) + midiOutput.sendMidi(activeDevice, out) + break; + case "Zoom": + var out = data.concat(111, "Z".charCodeAt(0)) + out.push(0xf7) + midiOutput.sendMidi(activeDevice, out) + break; + } } return subPage } From cf8d400d1b06425290d2e3aed91c2cca68d6a899 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 27 Nov 2022 12:45:27 +1100 Subject: [PATCH 43/65] Add wip comments for later --- icon/platformmplus/icon_platformmplus.js | 1 + 1 file changed, 1 insertion(+) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index e28a972..4fab110 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -83,6 +83,7 @@ function makeSubPage(subPageArea, name) { var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, ] switch (name) { + // WIP This should probably be handled by state variables and made part of update display case "Scrub": var out = data.concat(55, "S".charCodeAt(0)) out.push(0xf7) From 224edc17f3b634770017607e78733aaee22be215 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 27 Nov 2022 12:52:19 +1100 Subject: [PATCH 44/65] WIP marker --- icon/platformmplus/icon_platformmplus.js | 1 + 1 file changed, 1 insertion(+) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 4fab110..b877016 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -275,6 +275,7 @@ function makePageSelectedTrack() { page.makeActionBinding(surfaceElements.channelControls[2].rec_button.mSurfaceValue, subPagePreFilter.mAction.mActivate).setSubPage(subPageSendsQC) page.makeActionBinding(surfaceElements.channelControls[3].rec_button.mSurfaceValue, subPageCueSends.mAction.mActivate).setSubPage(subPageSendsQC) + // WIP Add Subpage Displays to Selected channel // EQ Subpage const eqBand = [] eqBand[0] = selectedTrackChannel.mChannelEQ.mBand1 From 07f130da4b9571e891c18b522f24c2686c50ace2 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sat, 3 Dec 2022 12:16:02 +1100 Subject: [PATCH 45/65] Code tidy up based on examples --- icon/platformmplus/icon_elements.js | 97 ++++++++++++++---------- icon/platformmplus/icon_platformmplus.js | 32 ++++---- 2 files changed, 70 insertions(+), 59 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 8a727f1..01291cb 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -2,7 +2,8 @@ var helper = require('./helper') var makeLabel = helper.display.makeLabel var flip = false -function updateDisplay(activeDevice) { +function updateDisplay(/** @type {MR_ActiveDevice} */activeDevice, /** @type {MR_DeviceMidiOutput} */midiOutput, /** @type {Object} */surfaceElements) { + var activePage = activeDevice.getState("activePage") switch (activePage) { case "Mixer": for (var i = 0; i < surfaceElements.numStrips; ++i) { @@ -53,9 +54,9 @@ function updateDisplay(activeDevice) { /** * @param {MR_DeviceSurface} surface - * @param {String} name + * @param {MR_DeviceMidiInput} midiInput + * @param {MR_DeviceMidiOutput} midiOutput * @param {number} note - * @param {Boolean} toggle * @param {number} x * @param {number} y * @param {number} w @@ -68,18 +69,18 @@ function makeLedButton(surface, midiInput, midiOutput, note, x, y, w, h, circle) if (circle) { button.setShapeCircle() } - button.mSurfaceValue.mOnProcessValueChange = function (activeDevice) { + button.mSurfaceValue.mOnProcessValueChange = (function (/** @type {MR_ActiveDevice} */activeDevice) { // console.log("LedButton ProcessValue Change:"+button.mSurfaceValue.getProcessValue(activeDevice)) if (button.mSurfaceValue.getProcessValue(activeDevice) > 0) - midiOutput.sendMidi(activeDevice, [0x90, note, 127]) + this.midiOutput.sendMidi(activeDevice, [0x90, note, 127]) else { - midiOutput.sendMidi(activeDevice, [0x90, note, 0]) + this.midiOutput.sendMidi(activeDevice, [0x90, note, 0]) } - } + }).bind({ midiOutput }) return button } -function clearAllLeds(activeDevice, midiOutput) { +function clearAllLeds(/** @type {MR_ActiveDevice} */activeDevice, /** @type {MR_DeviceMidiOutput} */midiOutput) { console.log('Clear All Leds') // Mixer buttons for (var i = 0; i < 8; ++i) { @@ -163,12 +164,12 @@ function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { * @param {MR_DeviceMidiInput} midiInput * @param {MR_DeviceMidiOutput} midiOutput * @param {number} x - x location of the push encoder in the gui - * @param {Number} y - y location of the push encoder in the gui - * @param {Number} w - width of the push encoder. - * @param {Number} h - height of the push encoder. - * @param {Number} instance - instance of the push encoder. + * @param {number} y - y location of the push encoder in the gui + * @param {number} instance - instance of the push encoder. + * @param {Object} surfaceElements + * @returns {Object} */ -function makeChannelControl(surface, midiInput, midiOutput, x, y, instance) { +function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surfaceElements) { var channelControl = {} channelControl.surface = surface; channelControl.midiInput = midiInput; @@ -219,29 +220,30 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance) { var channelIndex = channelControl.instance - channelControl.trackNameDisplay.mOnTitleChange = function (activeDevice, objectTitle, valueTitle) { + channelControl.trackNameDisplay.mOnTitleChange = (function (activeDevice, objectTitle, valueTitle) { channelControl.trackObjectTitle = objectTitle channelControl.trackValueTitle = valueTitle // console.log("Track Title Changed:"+objectTitle+":"+valueTitle) - updateDisplay(activeDevice) - } + updateDisplay(activeDevice,midiOutput,surfaceElements) + }).bind({ midiOutput }) - channelControl.faderTitlesDisplay.mOnTitleChange = function (activeDevice, objectTitle, valueTitle) { + channelControl.faderTitlesDisplay.mOnTitleChange = (function (activeDevice, objectTitle, valueTitle) { channelControl.faderObjectTitle = objectTitle channelControl.faderValueTitle = valueTitle console.log("Fader Title Changed:" + objectTitle + ":" + valueTitle) - updateDisplay(activeDevice) - } + updateDisplay(activeDevice,midiOutput,surfaceElements) + }).bind({ midiOutput }) - channelControl.fader_touch.mSurfaceValue.mOnProcessValueChange = function (activeDevice, touched, value2) { + channelControl.fader_touch.mSurfaceValue.mOnProcessValueChange = (function (activeDevice, touched, value2) { channelControl.faderTouched = touched + var activePage = activeDevice.getState("activePage") switch (activePage) { case "Mixer": if (touched) { midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderValueTitle, 6))) } else { - updateDisplay(activeDevice) + updateDisplay(activeDevice,midiOutput,surfaceElements) } break; case "SelectedTrack": @@ -249,7 +251,7 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance) { midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.faderValueTitle, 56))) } else { - updateDisplay(activeDevice) + updateDisplay(activeDevice,midiOutput,surfaceElements) } break; default: @@ -257,11 +259,12 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance) { midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("No " + activePage + " specific binding defined", 56))) break; } - } + }).bind({ midiOutput }) - channelControl.faderTitlesDisplay.mOnDisplayValueChange = function (activeDevice, value, units) { + channelControl.faderTitlesDisplay.mOnDisplayValueChange = (function (activeDevice, value, units) { console.log("Fader Value Change: " + value + ":" + units) channelControl.faderValue = value + var activePage = activeDevice.getState("activePage") switch (activePage) { case "Mixer": midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value, 6))) @@ -274,13 +277,13 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance) { midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("No " + activePage + " specific binding defined", 56))) break; } - } + }).bind({ midiOutput }) - channelControl.panTitlesDisplay.mOnTitleChange = function (activeDevice, objectTitle, valueTitle) { + channelControl.panTitlesDisplay.mOnTitleChange = (function (activeDevice, objectTitle, valueTitle) { channelControl.panObjectTitle = objectTitle channelControl.panValueTitle = valueTitle console.log("Pan Title Changed:" + objectTitle + ":" + valueTitle) - + var activePage = activeDevice.getState("activePage") switch (activePage) { case "SelectedTrack": // For selected track trime the send channel number since it's lined up with the Platform M+ numbering anyway @@ -291,12 +294,13 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance) { // do nothing break; } - updateDisplay(activeDevice) - } + updateDisplay(activeDevice,midiOutput,surfaceElements) + }).bind({ midiOutput }) - channelControl.panTitlesDisplay.mOnDisplayValueChange = function (activeDevice, value, units) { + channelControl.panTitlesDisplay.mOnDisplayValueChange = (function (activeDevice, value, units) { console.log("Pan Value Change: " + value + ":" + units) channelControl.panValue = value + var activePage = activeDevice.getState("activePage") switch (activePage) { case "Mixer": midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value, 6))) @@ -310,14 +314,14 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance) { midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("No " + activePage + " specific binding defined", 56))) break; } - } + }).bind({ midiOutput }) // ! Hmm, I wonder if my use of the *TitlesDisplay custom variables is unnecessary based on this one - channelControl.pushEncoder.mPushValue.mOnDisplayValueChange = function (activeDevice, value, units) { + channelControl.pushEncoder.mPushValue.mOnDisplayValueChange = (function (activeDevice, value, units) { console.log("Pan push Value Change: " + value + ":" + units) channelControl.panPushValue = value - updateDisplay(activeDevice) - } + updateDisplay(activeDevice,midiOutput,surfaceElements) + }).bind({ midiOutput }) return channelControl @@ -328,12 +332,12 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance) { * @param {MR_DeviceMidiInput} midiInput * @param {MR_DeviceMidiOutput} midiOutput * @param {number} x - x location of the push encoder in the gui - * @param {Number} y - y location of the push encoder in the gui - * @param {Number} w - width of the push encoder. - * @param {Number} h - height of the push encoder. - * @param {Number} instance - instance of the push encoder. + * @param {number} y - y location of the push encoder in the gui + * @param {number} instance - instance of the push encoder. + * @param {Object} surfaceElements + * @returns {Object} */ -function makeMasterControl(surface, midiInput, midiOutput, x, y, instance) { +function makeMasterControl(surface, midiInput, midiOutput, x, y, instance, surfaceElements) { var masterControl = {} masterControl.surface = surface; masterControl.midiInput = midiInput; @@ -365,13 +369,22 @@ function makeMasterControl(surface, midiInput, midiOutput, x, y, instance) { else { midiOutput.sendMidi(activeDevice, [0x90, 84, 0]) } - updateDisplay(activeDevice) + updateDisplay(activeDevice,midiOutput,surfaceElements) } } return masterControl } -function makeTransport(surface, midiInput, midiOutput, x, y) { +/** + * @param {MR_DeviceSurface} surface + * @param {MR_DeviceMidiInput} midiInput + * @param {MR_DeviceMidiOutput} midiOutput + * @param {number} x + * @param {number} y + * @param {Object} surfaceElements + * @returns {Object} + */ +function makeTransport(surface, midiInput, midiOutput, x, y, surfaceElements) { var transport = {} transport.surface = surface; transport.midiInput = midiInput; @@ -413,7 +426,7 @@ function makeTransport(surface, midiInput, midiOutput, x, y) { transport.btnFlip.mSurfaceValue.mOnProcessValueChange = function (activeDevice, number1, number2) { flip = !flip - updateDisplay(activeDevice) + updateDisplay(activeDevice,midiOutput,surfaceElements) console.log("transport flip: " + flip) } diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index b877016..b0a3b65 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -58,11 +58,11 @@ function makeSurfaceElements() { var yKnobStrip = 5 for (var i = 0; i < surfaceElements.numStrips; ++i) { - surfaceElements.channelControls[i] = makeChannelControl(surface, midiInput, midiOutput, xKnobStrip, yKnobStrip, i) + surfaceElements.channelControls[i] = makeChannelControl(surface, midiInput, midiOutput, xKnobStrip, yKnobStrip, i, surfaceElements) } - surfaceElements.faderMaster = makeMasterControl(surface, midiInput, midiOutput, xKnobStrip + 1, yKnobStrip + 4, surfaceElements.numStrips) - surfaceElements.transport = makeTransport(surface, midiInput, midiOutput, xKnobStrip + 63, yKnobStrip + 4) + surfaceElements.faderMaster = makeMasterControl(surface, midiInput, midiOutput, xKnobStrip + 1, yKnobStrip + 4, surfaceElements.numStrips, surfaceElements) + surfaceElements.transport = makeTransport(surface, midiInput, midiOutput, xKnobStrip + 63, yKnobStrip + 4, surfaceElements) return surfaceElements } @@ -404,8 +404,6 @@ function makePageChannelStrip() { var mixerPage = makePageMixer() var selectedTrackPage = makePageSelectedTrack() var channelStripPage = makePageChannelStrip() -var activePage = "Mixer" -var activeSubPage = "Nudge" // Function to clear out the Channel State for the display titles/values // the OnDisplayChange callback is not called if the Channel doesn't have an updated @@ -422,24 +420,24 @@ function clearChannelState() { surfaceElements.channelControls[i].panPushValue = "" } } -mixerPage.mOnActivate = function (device) { +mixerPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDevice) { console.log('from script: Platform M+ page "Mixer" activated') - activePage = "Mixer" - clearAllLeds(device, midiOutput) + activeDevice.setState("activePage","Mixer") + clearAllLeds(activeDevice, midiOutput) clearChannelState() -} +}).bind({ midiOutput }) -selectedTrackPage.mOnActivate = function (device) { +selectedTrackPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDevice) { console.log('from script: Platform M+ page "Selected Track" activated') - activePage = "SelectedTrack" - clearAllLeds(device, midiOutput) + activeDevice.setState("activePage","SelectedTrack") + clearAllLeds(activeDevice, midiOutput) clearChannelState() -} +}).bind({ midiOutput }) -channelStripPage.mOnActivate = function (device) { +channelStripPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDevice) { console.log('from script: Platform M+ page "Channel Strip" activated') - activePage = "ChannelStrip" - clearAllLeds(device, midiOutput) + activeDevice.setState("activePage","ChannelStrip") + clearAllLeds(activeDevice, midiOutput) clearChannelState() -} +}).bind({ midiOutput }) From 8368d0cc045d990afdd4c50070e615d9a2f77125 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sat, 3 Dec 2022 16:54:52 +1100 Subject: [PATCH 46/65] More WIP --- icon/platformmplus/icon_elements.js | 38 +++++++++++++++++++----- icon/platformmplus/icon_platformmplus.js | 37 +++++++++-------------- 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 01291cb..1d2846a 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -4,6 +4,9 @@ var flip = false function updateDisplay(/** @type {MR_ActiveDevice} */activeDevice, /** @type {MR_DeviceMidiOutput} */midiOutput, /** @type {Object} */surfaceElements) { var activePage = activeDevice.getState("activePage") + var activeSubPage = activeDevice.getState("activeSubPage") + // WIP faderObjectTitle, faderValueTitle - need to be set in the respective OnDisplayUpdate etcs so they are not grabbed from the element + // WIP because the element changes with subPage etc. switch (activePage) { case "Mixer": for (var i = 0; i < surfaceElements.numStrips; ++i) { @@ -50,6 +53,24 @@ function updateDisplay(/** @type {MR_ActiveDevice} */activeDevice, /** @type {MR midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("No " + activePage + " specific binding defined", 56))) break; } + // Update indicator characters - last char of each row + function display_indicator(row, indicator) { + var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, + ] + if (row===0) { + data.push(55) + } else { + data.push(111) + } + data.push( indicator.charCodeAt(0)) + data.push(0xf7) + midiOutput.sendMidi(activeDevice, data) + } + var indicator1 = activeDevice.getState("indicator1") + var indicator2 = activeDevice.getState("indicator2") + display_indicator(1, indicator1) + display_indicator(0, indicator2) + } /** @@ -224,14 +245,14 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf channelControl.trackObjectTitle = objectTitle channelControl.trackValueTitle = valueTitle // console.log("Track Title Changed:"+objectTitle+":"+valueTitle) - updateDisplay(activeDevice,midiOutput,surfaceElements) + updateDisplay(activeDevice, midiOutput, surfaceElements) }).bind({ midiOutput }) channelControl.faderTitlesDisplay.mOnTitleChange = (function (activeDevice, objectTitle, valueTitle) { channelControl.faderObjectTitle = objectTitle channelControl.faderValueTitle = valueTitle console.log("Fader Title Changed:" + objectTitle + ":" + valueTitle) - updateDisplay(activeDevice,midiOutput,surfaceElements) + updateDisplay(activeDevice, midiOutput, surfaceElements) }).bind({ midiOutput }) channelControl.fader_touch.mSurfaceValue.mOnProcessValueChange = (function (activeDevice, touched, value2) { @@ -243,15 +264,16 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderValueTitle, 6))) } else { - updateDisplay(activeDevice,midiOutput,surfaceElements) + updateDisplay(activeDevice, midiOutput, surfaceElements) } break; case "SelectedTrack": + switch if (touched) { midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.faderValueTitle, 56))) } else { - updateDisplay(activeDevice,midiOutput,surfaceElements) + updateDisplay(activeDevice, midiOutput, surfaceElements) } break; default: @@ -294,7 +316,7 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf // do nothing break; } - updateDisplay(activeDevice,midiOutput,surfaceElements) + updateDisplay(activeDevice, midiOutput, surfaceElements) }).bind({ midiOutput }) channelControl.panTitlesDisplay.mOnDisplayValueChange = (function (activeDevice, value, units) { @@ -320,7 +342,7 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf channelControl.pushEncoder.mPushValue.mOnDisplayValueChange = (function (activeDevice, value, units) { console.log("Pan push Value Change: " + value + ":" + units) channelControl.panPushValue = value - updateDisplay(activeDevice,midiOutput,surfaceElements) + updateDisplay(activeDevice, midiOutput, surfaceElements) }).bind({ midiOutput }) return channelControl @@ -369,7 +391,7 @@ function makeMasterControl(surface, midiInput, midiOutput, x, y, instance, surfa else { midiOutput.sendMidi(activeDevice, [0x90, 84, 0]) } - updateDisplay(activeDevice,midiOutput,surfaceElements) + updateDisplay(activeDevice, midiOutput, surfaceElements) } } return masterControl @@ -426,7 +448,7 @@ function makeTransport(surface, midiInput, midiOutput, x, y, surfaceElements) { transport.btnFlip.mSurfaceValue.mOnProcessValueChange = function (activeDevice, number1, number2) { flip = !flip - updateDisplay(activeDevice,midiOutput,surfaceElements) + updateDisplay(activeDevice, midiOutput, surfaceElements) console.log("transport flip: " + flip) } diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index b0a3b65..3fe885a 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -19,7 +19,7 @@ var updateDisplay = iconElements.updateDisplay var midiremote_api = require('midiremote_api_v1') // create the device driver main object -var deviceDriver = midiremote_api.makeDeviceDriver('Icon', 'Platform Mplus', 'Big Fat Wombats') +var deviceDriver = midiremote_api.makeDeviceDriver('Icon', 'Platform Mplus', 'Big Fat Wombat') // create objects representing the hardware's MIDI ports var midiInput = deviceDriver.mPorts.makeMidiInput() @@ -28,7 +28,7 @@ var midiOutput = deviceDriver.mPorts.makeMidiOutput() deviceDriver.mOnActivate = function (activeDevice) { console.log('Icon Platform M+ Activated'); clearAllLeds(activeDevice, midiOutput) -}; +} // define all possible namings the devices MIDI ports could have // NOTE: Windows and MacOS handle port naming differently @@ -78,34 +78,27 @@ var surfaceElements = makeSurfaceElements() function makeSubPage(subPageArea, name) { var subPage = subPageArea.makeSubPage(name) var msgText = 'sub page ' + name + ' activated' - subPage.mOnActivate = function (activeDevice) { + subPage.mOnActivate = (function (activeDevice) { console.log(msgText) + activeDevice.setState("activeSubPage",name) var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, ] switch (name) { - // WIP This should probably be handled by state variables and made part of update display case "Scrub": - var out = data.concat(55, "S".charCodeAt(0)) - out.push(0xf7) - midiOutput.sendMidi(activeDevice, out) + activeDevice.setState("indicator2","S") break; case "Nudge": - var out = data.concat(55, "N".charCodeAt(0)) - out.push(0xf7) - midiOutput.sendMidi(activeDevice, out) + activeDevice.setState("indicator2","N") break; case "Nav": - var out = data.concat(111, "N".charCodeAt(0)) - out.push(0xf7) - midiOutput.sendMidi(activeDevice, out) + activeDevice.setState("indicator1","N") break; case "Zoom": - var out = data.concat(111, "Z".charCodeAt(0)) - out.push(0xf7) - midiOutput.sendMidi(activeDevice, out) + activeDevice.setState("indicator1","Z") break; } - } + updateDisplay(activeDevice, midiOutput, surfaceElements) + }).bind({ subPage, name }) return subPage } /** @@ -161,8 +154,6 @@ function makePageWithDefaults(name) { var subPageMasterFaderValue = makeSubPage(MasterFaderSubPageArea, 'MF_ValueUnderCursor') // var subPageMasterFaderMain = makeSubPage(MasterFaderSubPageArea, 'MF_MainOut') - - // Master Fader changes display detail page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, page.mHostAccess.mMouseCursor.mValueUnderMouse).setValueTakeOverModeJump().setSubPage(subPageMasterFaderValue) // Automation for selected tracks @@ -264,7 +255,7 @@ function makePageSelectedTrack() { page.makeValueBinding(surfaceElements.channelControls[6].rec_button.mSurfaceValue, selectedTrackChannel.mValue.mSolo).setTypeToggle().setSubPage(subPageSendsQC) page.makeValueBinding(surfaceElements.channelControls[7].rec_button.mSurfaceValue, selectedTrackChannel.mValue.mRecordEnable).setTypeToggle().setSubPage(subPageSendsQC) - // EQ Related but on Sends page so you know have EQ activated...not sure the best option but hey, more buttons and lights is cool! + // EQ Related but on Sends page so you know EQ activated...not sure the best option but hey, more buttons and lights is cool! page.makeValueBinding(surfaceElements.channelControls[0].solo_button.mSurfaceValue, selectedTrackChannel.mChannelEQ.mBand1.mOn).setTypeToggle().setSubPage(subPageSendsQC) page.makeValueBinding(surfaceElements.channelControls[1].solo_button.mSurfaceValue, selectedTrackChannel.mChannelEQ.mBand2.mOn).setTypeToggle().setSubPage(subPageSendsQC) page.makeValueBinding(surfaceElements.channelControls[2].solo_button.mSurfaceValue, selectedTrackChannel.mChannelEQ.mBand3.mOn).setTypeToggle().setSubPage(subPageSendsQC) @@ -422,21 +413,21 @@ function clearChannelState() { } mixerPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDevice) { console.log('from script: Platform M+ page "Mixer" activated') - activeDevice.setState("activePage","Mixer") + activeDevice.setState("activePage", "Mixer") clearAllLeds(activeDevice, midiOutput) clearChannelState() }).bind({ midiOutput }) selectedTrackPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDevice) { console.log('from script: Platform M+ page "Selected Track" activated') - activeDevice.setState("activePage","SelectedTrack") + activeDevice.setState("activePage", "SelectedTrack") clearAllLeds(activeDevice, midiOutput) clearChannelState() }).bind({ midiOutput }) channelStripPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDevice) { console.log('from script: Platform M+ page "Channel Strip" activated') - activeDevice.setState("activePage","ChannelStrip") + activeDevice.setState("activePage", "ChannelStrip") clearAllLeds(activeDevice, midiOutput) clearChannelState() }).bind({ midiOutput }) From 3c8353300e4394eaf9538a20d878c9fc8bbf3420 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 4 Dec 2022 14:48:31 +1100 Subject: [PATCH 47/65] Some progress on new display handling in Mixer track ondisplaychange. --- icon/platformmplus/helper.js | 21 +++++++- icon/platformmplus/icon_elements.js | 80 ++++++++++++++++++++++++----- 2 files changed, 87 insertions(+), 14 deletions(-) diff --git a/icon/platformmplus/helper.js b/icon/platformmplus/helper.js index fa94c69..e1afaab 100644 --- a/icon/platformmplus/helper.js +++ b/icon/platformmplus/helper.js @@ -12,6 +12,24 @@ function displaySetTextOfColumn(columnIndex, rowIndex, textString) { return data } + +function setTextOfColumn(columnIndex, col_text, original_text) { + var col = columnIndex * 7 + var text = (col_text + ' ').slice(0, 7) // ensure to always clear a column + + // original_text must be the full width of the display when setting a column + // so pad with spaces if it isn't + var new_text = original_text.slice(0, 56) + var length = new_text.length + while (length++ < 56) + new_text = new_text.concat(" ") + + new_text = new_text.substring(0, col) + text + new_text.substring(col + 7, new_text.length); + + return new_text +} + + function displaySetTextOfLine(rowIndex, textString) { var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, rowIndex * 56] @@ -70,6 +88,7 @@ module.exports = { }, display: { reset: resetDisplay, - makeLabel: makeLabel + makeLabel: makeLabel, + setTextOfColumn: setTextOfColumn } } diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 1d2846a..a9c53a1 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -1,6 +1,43 @@ var helper = require('./helper') var makeLabel = helper.display.makeLabel -var flip = false +var setTextOfColumn = helper.display.setTextOfColumn +var flip = false // WIP delete me... +var fader_view = true + +function Helper_updateDisplay(/** @type {string} */idRow1, /** @type {string} */idRow2, /** @type {MR_ActiveDevice} */activeDevice, /** @type {MR_DeviceMidiOutput} */midiOutput) { + // console.log("Helper Update Display") + var displayRow1 = activeDevice.getState(idRow1) + var displayRow2 = activeDevice.getState(idRow2) + + activeDevice.setState('Row1', displayRow1) + activeDevice.setState('Row2', displayRow2) + + var lenRow1 = displayRow1.length < 56 ? displayRow1.length : 56 + var lenRow2 = displayRow2.length < 56 ? displayRow2.length : 56 + + var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12] + + // Row 1 + var out = data.concat(56) // Row 1 offset + + for (var i = 0; i < lenRow1; ++i) + out.push(displayRow1.charCodeAt(i)) + while (lenRow1++ < 56) + out.push(0x20) // spaces for the rest + out.push(0xf7) + midiOutput.sendMidi(activeDevice, out) + + // Row 2 + out = data.concat(0) // Row 2 offset + + for (var i = 0; i < lenRow2; ++i) + out.push(displayRow2.charCodeAt(i)) + while (lenRow2++ < 56) + out.push(0x20) // spaces for the rest + out.push(0xf7) + midiOutput.sendMidi(activeDevice, out) +} + function updateDisplay(/** @type {MR_ActiveDevice} */activeDevice, /** @type {MR_DeviceMidiOutput} */midiOutput, /** @type {Object} */surfaceElements) { var activePage = activeDevice.getState("activePage") @@ -53,24 +90,26 @@ function updateDisplay(/** @type {MR_ActiveDevice} */activeDevice, /** @type {MR midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("No " + activePage + " specific binding defined", 56))) break; } + // Update indicator characters - last char of each row function display_indicator(row, indicator) { var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, ] - if (row===0) { + if (row === 0) { data.push(55) } else { data.push(111) } - data.push( indicator.charCodeAt(0)) + data.push(indicator.charCodeAt(0)) data.push(0xf7) midiOutput.sendMidi(activeDevice, data) } + var indicator1 = activeDevice.getState("indicator1") var indicator2 = activeDevice.getState("indicator2") + display_indicator(1, indicator1) display_indicator(0, indicator2) - } /** @@ -241,18 +280,33 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf var channelIndex = channelControl.instance + function _updateDisplay(activeDevice, midiOutput ) { + if (fader_view) { + Helper_updateDisplay('Mixer - Fader - Title','Mixer - Fader - Values', activeDevice, midiOutput ) + } else { + Helper_updateDisplay('Mixer - Pan - Title','Mixer - Pan - Values', activeDevice, midiOutput ) + } + } + channelControl.trackNameDisplay.mOnTitleChange = (function (activeDevice, objectTitle, valueTitle) { - channelControl.trackObjectTitle = objectTitle - channelControl.trackValueTitle = valueTitle - // console.log("Track Title Changed:"+objectTitle+":"+valueTitle) - updateDisplay(activeDevice, midiOutput, surfaceElements) + channelControl.trackObjectTitle = objectTitle // WIP Delete me + channelControl.trackValueTitle = valueTitle // WIP Delete me + var trackTitles= activeDevice.getState('Mixer - Track - Title') + var trackValues = activeDevice.getState('Mixer - Track - Values') + activeDevice.setState('Mixer - Track - Title', setTextOfColumn(channelIndex, makeLabel(objectTitle,6), trackTitles)) + activeDevice.setState('Mixer - Track - Values', setTextOfColumn(channelIndex, makeLabel(valueTitle,6), trackValues)) + _updateDisplay(activeDevice, midiOutput ) }).bind({ midiOutput }) channelControl.faderTitlesDisplay.mOnTitleChange = (function (activeDevice, objectTitle, valueTitle) { - channelControl.faderObjectTitle = objectTitle - channelControl.faderValueTitle = valueTitle - console.log("Fader Title Changed:" + objectTitle + ":" + valueTitle) - updateDisplay(activeDevice, midiOutput, surfaceElements) + channelControl.faderObjectTitle = objectTitle // WIP Delete me + channelControl.faderValueTitle = valueTitle // WIP Delete me + + var faderTitles= activeDevice.getState('Mixer - Fader - Title') + var faderValues = activeDevice.getState('Mixer - Fader - Values') + activeDevice.setState('Mixer - Fader - Title', setTextOfColumn(channelIndex, makeLabel(objectTitle,6), faderTitles)) + activeDevice.setState('Mixer - Fader - Values', setTextOfColumn(channelIndex, makeLabel(valueTitle,6), faderValues)) + _updateDisplay(activeDevice, midiOutput ) }).bind({ midiOutput }) channelControl.fader_touch.mSurfaceValue.mOnProcessValueChange = (function (activeDevice, touched, value2) { @@ -261,6 +315,7 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf switch (activePage) { case "Mixer": if (touched) { + setTextOfColumn(channelIndex, makeLabel(channelControl.faderValueTitle,6), "") midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderValueTitle, 6))) } else { @@ -268,7 +323,6 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf } break; case "SelectedTrack": - switch if (touched) { midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.faderValueTitle, 56))) } From afdf2e43dbe9ba4b84e5e0f941dfb82b470a3399 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 18 Dec 2022 11:45:37 +1100 Subject: [PATCH 48/65] More refactoring than I care to explain - much of it trial and error on midi remote scripting quirks. --- icon/platformmplus/helper.js | 71 +++-- icon/platformmplus/icon_elements.js | 366 +++++++++++------------ icon/platformmplus/icon_platformmplus.js | 188 ++++++------ 3 files changed, 305 insertions(+), 320 deletions(-) diff --git a/icon/platformmplus/helper.js b/icon/platformmplus/helper.js index e1afaab..1ed5086 100644 --- a/icon/platformmplus/helper.js +++ b/icon/platformmplus/helper.js @@ -1,16 +1,16 @@ -function displaySetTextOfColumn(columnIndex, rowIndex, textString) { - var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, - columnIndex * 7 + rowIndex * 56] +// function displaySetTextOfColumn(columnIndex, rowIndex, textString) { +// var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, +// columnIndex * 7 + rowIndex * 56] - var text = (textString + ' ').slice(0, 7) // ensure to always clear a column - // console.log("display:" + text) - for (var i = 0; i < 7; ++i) - data.push(text.charCodeAt(i)) - data.push(0xf7) +// var text = (textString + ' ').slice(0, 7) // ensure to always clear a column +// // console.log("display:" + text) +// for (var i = 0; i < 7; ++i) +// data.push(text.charCodeAt(i)) +// data.push(0xf7) - return data -} +// return data +// } function setTextOfColumn(columnIndex, col_text, original_text) { @@ -29,31 +29,37 @@ function setTextOfColumn(columnIndex, col_text, original_text) { return new_text } - -function displaySetTextOfLine(rowIndex, textString) { - var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, - rowIndex * 56] +function setTextOfLine(textString) { var blank = Array(56).join(" ") var text = (textString + blank).slice(0, 56) // ensure to always clear the entire row - // console.log("display:" + text) - for (var i = 0; i < 56; ++i) - data.push(text.charCodeAt(i)) - data.push(0xf7) - return data + return text } +// function displaySetTextOfLine(rowIndex, textString) { +// var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, +// rowIndex * 56] +// var blank = Array(56).join(" ") +// var text = (textString + blank).slice(0, 56) // ensure to always clear the entire row +// // console.log("display:" + text) +// for (var i = 0; i < 56; ++i) +// data.push(text.charCodeAt(i)) +// data.push(0xf7) + +// return data +// } + /** * @param {MR_ActiveDevice} activeDevice * @param {MR_DeviceMidiOutput} outPort */ -function resetDisplay(activeDevice, outPort) { - for (var i = 0; i < 8; ++i) { - for (var k = 0; k < 2; ++k) { - outPort.sendMidi(activeDevice, displaySetTextOfColumn(i, k, " ")) - } - } -} +// function resetDisplay(activeDevice, outPort) { +// for (var i = 0; i < 8; ++i) { +// for (var k = 0; k < 2; ++k) { +// outPort.sendMidi(activeDevice, displaySetTextOfColumn(i, k, " ")) +// } +// } +// } function makeLabel(value, length) { // console.log("makeLabel:" + value) @@ -82,13 +88,14 @@ function makeLabel(value, length) { } module.exports = { - sysex: { - displaySetTextOfColumn: displaySetTextOfColumn, - displaySetTextOfLine: displaySetTextOfLine - }, + // sysex: { + // displaySetTextOfColumn: displaySetTextOfColumn, + // displaySetTextOfLine: displaySetTextOfLine + // }, display: { - reset: resetDisplay, + // reset: resetDisplay, makeLabel: makeLabel, - setTextOfColumn: setTextOfColumn + setTextOfColumn: setTextOfColumn, + setTextOfLine: setTextOfLine } } diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index a9c53a1..45f0ed8 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -1,97 +1,64 @@ var helper = require('./helper') var makeLabel = helper.display.makeLabel var setTextOfColumn = helper.display.setTextOfColumn -var flip = false // WIP delete me... -var fader_view = true - -function Helper_updateDisplay(/** @type {string} */idRow1, /** @type {string} */idRow2, /** @type {MR_ActiveDevice} */activeDevice, /** @type {MR_DeviceMidiOutput} */midiOutput) { - // console.log("Helper Update Display") - var displayRow1 = activeDevice.getState(idRow1) - var displayRow2 = activeDevice.getState(idRow2) - - activeDevice.setState('Row1', displayRow1) - activeDevice.setState('Row2', displayRow2) - - var lenRow1 = displayRow1.length < 56 ? displayRow1.length : 56 - var lenRow2 = displayRow2.length < 56 ? displayRow2.length : 56 +var setTextOfLine = helper.display.setTextOfLine +function _sendDisplayData(row, text, activeDevice, midiOutput) { + var lenText = text.length < 56 ? text.length : 56 var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12] + var out = data.concat(56 * row) // Row 1 offset - // Row 1 - var out = data.concat(56) // Row 1 offset - - for (var i = 0; i < lenRow1; ++i) - out.push(displayRow1.charCodeAt(i)) - while (lenRow1++ < 56) + for (var i = 0; i < lenText; ++i) + out.push(text.charCodeAt(i)) + while (lenText++ < 56) out.push(0x20) // spaces for the rest out.push(0xf7) midiOutput.sendMidi(activeDevice, out) - // Row 2 - out = data.concat(0) // Row 2 offset - - for (var i = 0; i < lenRow2; ++i) - out.push(displayRow2.charCodeAt(i)) - while (lenRow2++ < 56) - out.push(0x20) // spaces for the rest - out.push(0xf7) - midiOutput.sendMidi(activeDevice, out) } - -function updateDisplay(/** @type {MR_ActiveDevice} */activeDevice, /** @type {MR_DeviceMidiOutput} */midiOutput, /** @type {Object} */surfaceElements) { - var activePage = activeDevice.getState("activePage") - var activeSubPage = activeDevice.getState("activeSubPage") - // WIP faderObjectTitle, faderValueTitle - need to be set in the respective OnDisplayUpdate etcs so they are not grabbed from the element - // WIP because the element changes with subPage etc. - switch (activePage) { - case "Mixer": - for (var i = 0; i < surfaceElements.numStrips; ++i) { - var element = surfaceElements.channelControls[i] - if (!flip) { - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 1, makeLabel(element.faderObjectTitle, 6))) - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel(element.faderValueTitle, 6))) - midiOutput.sendMidi(activeDevice, [0x90, 84, 0]) // Mixer - } - else { - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 1, makeLabel(element.panObjectTitle, 6))) - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel(element.panValueTitle, 6))) - midiOutput.sendMidi(activeDevice, [0x90, 84, 127]) // Mixer - } - } - break; - case "SelectedTrack": - var msg = surfaceElements.channelControls[0].trackObjectTitle - if (!flip) { - midiOutput.sendMidi(activeDevice, [0x90, 84, 0]) // Mixer - // For selected track all the trackObjectTitle are set to the same value - // So send it once to the display and use the entire top line for the title - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel('QC-' + msg, 56))) - for (var i = 0; i < surfaceElements.numStrips; ++i) { - var element = surfaceElements.channelControls[i] - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel(element.faderValueTitle, 6))) - } - } - else { - midiOutput.sendMidi(activeDevice, [0x90, 84, 127]) // Mixer - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("Sends-" + msg, 56))) - for (var i = 0; i < surfaceElements.numStrips; ++i) { - var element = surfaceElements.channelControls[i] - if (element.panPushValue == "On") { - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel(element.panObjectTitle, 6))) - } else { - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel("Off", 6))) - } - } - } - break; - default: - console.log("No page specific binding defined") - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("No " + activePage + " specific binding defined", 56))) - break; +function Helper_updateDisplay(/** @type {string} */idRow1, /** @type {string} */idRow2, /** @type {string} */idAltRow1, /** @type {string} */idAltRow2,/** @type {MR_ActiveDevice} */activeDevice, /** @type {MR_DeviceMidiOutput} */midiOutput) { + // New values + var newRow1 = activeDevice.getState(idRow1) + var newRow2 = activeDevice.getState(idRow2) + var newAltRow1 = activeDevice.getState(idAltRow1) + var newAltRow2 = activeDevice.getState(idAltRow2) + // console.log("Helper Update Display...") + // Previous values + var prevRow1 = activeDevice.getState('Row1') + var prevRow2 = activeDevice.getState('Row2') + var prevAltRow1 = activeDevice.getState('AltRow1') + var prevAltRow2 = activeDevice.getState('AltRow2') + var activeDisplayType = activeDevice.getState('activeDisplayType') + // Display Fader or Panner values + var displayType = activeDevice.getState("displayType") + + if (displayType === "Pan") { + // Update display if it has changed + if ((newAltRow1 !== prevAltRow1) || (newAltRow2 !== prevAltRow2) || (activeDisplayType !== displayType)) { + // console.log("AltRows Display update: " + newAltRow1+"::"+newAltRow2) + _sendDisplayData(1, newAltRow1, activeDevice, midiOutput) + _sendDisplayData(0, newAltRow2, activeDevice, midiOutput) + } + } else { + // Update display if it has changed + if ((newRow1 !== prevRow1) || (newRow2 !== prevRow2) || (activeDisplayType !== displayType)) { + // console.log("Rows Display update" + newRow1+"::"+newRow2) + _sendDisplayData(1, newRow1, activeDevice, midiOutput) + _sendDisplayData(0, newRow2, activeDevice, midiOutput) + } } + // Update Active display state + activeDevice.setState('Row1', newRow1) + activeDevice.setState('Row2', newRow2) + + activeDevice.setState('AltRow1', newAltRow1) + activeDevice.setState('AltRow2', newAltRow2) - // Update indicator characters - last char of each row + activeDevice.setState('activeDisplayType', displayType) + // console.log("Helper Update Display...DONE") + + // Indicators for the Zoom and Jog function subpages function display_indicator(row, indicator) { var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, ] @@ -112,6 +79,78 @@ function updateDisplay(/** @type {MR_ActiveDevice} */activeDevice, /** @type {MR display_indicator(0, indicator2) } + +// function updateDisplay(/** @type {MR_ActiveDevice} */activeDevice, /** @type {MR_DeviceMidiOutput} */midiOutput, /** @type {Object} */surfaceElements) { +// var activePage = activeDevice.getState("activePage") +// var activeSubPage = activeDevice.getState("activeSubPage") +// switch (activePage) { +// case "Mixer": +// for (var i = 0; i < surfaceElements.numStrips; ++i) { +// var element = surfaceElements.channelControls[i] +// if (!flip) { +// midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 1, makeLabel(element.faderObjectTitle, 6))) +// midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel(element.faderValueTitle, 6))) +// midiOutput.sendMidi(activeDevice, [0x90, 84, 0]) // Mixer +// } +// else { +// midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 1, makeLabel(element.panObjectTitle, 6))) +// midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel(element.panValueTitle, 6))) +// midiOutput.sendMidi(activeDevice, [0x90, 84, 127]) // Mixer +// } +// } +// break; +// case "SelectedTrack": +// var msg = surfaceElements.channelControls[0].trackObjectTitle +// if (!flip) { +// midiOutput.sendMidi(activeDevice, [0x90, 84, 0]) // Mixer +// // For selected track all the trackObjectTitle are set to the same value +// // So send it once to the display and use the entire top line for the title +// midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel('QC-' + msg, 56))) +// for (var i = 0; i < surfaceElements.numStrips; ++i) { +// var element = surfaceElements.channelControls[i] +// midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel(element.faderValueTitle, 6))) +// } +// } +// else { +// midiOutput.sendMidi(activeDevice, [0x90, 84, 127]) // Mixer +// midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("Sends-" + msg, 56))) +// for (var i = 0; i < surfaceElements.numStrips; ++i) { +// var element = surfaceElements.channelControls[i] +// if (element.panPushValue == "On") { +// midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel(element.panObjectTitle, 6))) +// } else { +// midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel("Off", 6))) +// } +// } +// } +// break; +// default: +// console.log("No page specific binding defined") +// midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("No " + activePage + " specific binding defined", 56))) +// break; +// } + +// // Update indicator characters - last char of each row +// function display_indicator(row, indicator) { +// var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, +// ] +// if (row === 0) { +// data.push(55) +// } else { +// data.push(111) +// } +// data.push(indicator.charCodeAt(0)) +// data.push(0xf7) +// midiOutput.sendMidi(activeDevice, data) +// } + +// var indicator1 = activeDevice.getState("indicator1") +// var indicator2 = activeDevice.getState("indicator2") + +// display_indicator(1, indicator1) +// display_indicator(0, indicator2) +// } + /** * @param {MR_DeviceSurface} surface * @param {MR_DeviceMidiInput} midiInput @@ -166,7 +205,7 @@ function clearAllLeds(/** @type {MR_ActiveDevice} */activeDevice, /** @type {MR_ midiOutput.sendMidi(activeDevice, [0x90, 95, 0]) midiOutput.sendMidi(activeDevice, [0x90, 86, 0]) - helper.display.reset(activeDevice, midiOutput) + // helper.display.reset(activeDevice, midiOutput) } /** @@ -238,21 +277,6 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf channelControl.y = y; channelControl.instance = instance; // Channel number, 1-8 - // Channel Displays - channelControl.trackNameDisplay = channelControl.surface.makeCustomValueVariable('trackNameDisplay'); - channelControl.trackObjectTitle = "" - channelControl.trackValueTitle = "" - channelControl.faderTitlesDisplay = channelControl.surface.makeCustomValueVariable('faderTitlesDisplay'); - channelControl.panTitlesDisplay = channelControl.surface.makeCustomValueVariable('panTitlesDisplay'); - channelControl.faderObjectTitle = "" - channelControl.faderValueTitle = "" - channelControl.faderValue = "" - channelControl.faderTouched = 0 // 0 - not touched, 1 - touched - channelControl.panObjectTitle = "" - channelControl.panValueTitle = "" - channelControl.panValue = "" - channelControl.panPushValue = "" - // Pot encoder channelControl.pushEncoder = channelControl.surface.makePushEncoder(channelControl.x, y + 2, 4, 4) @@ -280,124 +304,75 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf var channelIndex = channelControl.instance - function _updateDisplay(activeDevice, midiOutput ) { - if (fader_view) { - Helper_updateDisplay('Mixer - Fader - Title','Mixer - Fader - Values', activeDevice, midiOutput ) - } else { - Helper_updateDisplay('Mixer - Pan - Title','Mixer - Pan - Values', activeDevice, midiOutput ) - } - } - - channelControl.trackNameDisplay.mOnTitleChange = (function (activeDevice, objectTitle, valueTitle) { - channelControl.trackObjectTitle = objectTitle // WIP Delete me - channelControl.trackValueTitle = valueTitle // WIP Delete me - var trackTitles= activeDevice.getState('Mixer - Track - Title') - var trackValues = activeDevice.getState('Mixer - Track - Values') - activeDevice.setState('Mixer - Track - Title', setTextOfColumn(channelIndex, makeLabel(objectTitle,6), trackTitles)) - activeDevice.setState('Mixer - Track - Values', setTextOfColumn(channelIndex, makeLabel(valueTitle,6), trackValues)) - _updateDisplay(activeDevice, midiOutput ) - }).bind({ midiOutput }) - - channelControl.faderTitlesDisplay.mOnTitleChange = (function (activeDevice, objectTitle, valueTitle) { - channelControl.faderObjectTitle = objectTitle // WIP Delete me - channelControl.faderValueTitle = valueTitle // WIP Delete me - - var faderTitles= activeDevice.getState('Mixer - Fader - Title') - var faderValues = activeDevice.getState('Mixer - Fader - Values') - activeDevice.setState('Mixer - Fader - Title', setTextOfColumn(channelIndex, makeLabel(objectTitle,6), faderTitles)) - activeDevice.setState('Mixer - Fader - Values', setTextOfColumn(channelIndex, makeLabel(valueTitle,6), faderValues)) - _updateDisplay(activeDevice, midiOutput ) - }).bind({ midiOutput }) - - channelControl.fader_touch.mSurfaceValue.mOnProcessValueChange = (function (activeDevice, touched, value2) { - channelControl.faderTouched = touched + channelControl.fader.mSurfaceValue.mOnTitleChange = (function (activeDevice, objectTitle, valueTitle) { + // console.log("Fader Title Change: " + channelIndex + "::" + objectTitle + ":" + valueTitle) var activePage = activeDevice.getState("activePage") + var faderTitles = activeDevice.getState(activePage + ' - Fader - Title') + var faderValueTitles = activeDevice.getState(activePage + ' - Fader - ValueTitles') + switch (activePage) { - case "Mixer": - if (touched) { - setTextOfColumn(channelIndex, makeLabel(channelControl.faderValueTitle,6), "") - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderValueTitle, 6))) - } - else { - updateDisplay(activeDevice, midiOutput, surfaceElements) - } - break; case "SelectedTrack": - if (touched) { - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.faderValueTitle, 56))) - } - else { - updateDisplay(activeDevice, midiOutput, surfaceElements) - } + activeDevice.setState(activePage + ' - Fader - ValueTitles', setTextOfColumn(channelIndex, makeLabel(valueTitle, 6), faderValueTitles)) + Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) break; default: - console.log("No page specific binding defined") - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("No " + activePage + " specific binding defined", 56))) + activeDevice.setState(activePage + ' - Fader - Title', setTextOfColumn(channelIndex, makeLabel(objectTitle, 6), faderTitles)) + activeDevice.setState(activePage + ' - Fader - ValueTitles', setTextOfColumn(channelIndex, makeLabel(valueTitle, 6), faderValueTitles)) + Helper_updateDisplay(activePage + ' - Fader - Title', activePage + ' - Fader - Values', activePage + ' - Pan - Title', activePage + ' - Pan - Values', activeDevice, midiOutput) break; } }).bind({ midiOutput }) - channelControl.faderTitlesDisplay.mOnDisplayValueChange = (function (activeDevice, value, units) { - console.log("Fader Value Change: " + value + ":" + units) - channelControl.faderValue = value + channelControl.fader.mSurfaceValue.mOnDisplayValueChange = (function (activeDevice, value, units) { + console.log("Fader Display Value Change: " + value + ":" + units) var activePage = activeDevice.getState("activePage") - switch (activePage) { - case "Mixer": - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value, 6))) - break; - case "SelectedTrack": - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value, 6))) - break; - default: - console.log("No page specific binding defined") - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("No " + activePage + " specific binding defined", 56))) - break; - } - }).bind({ midiOutput }) + var faderValues = activeDevice.getState(activePage + ' - Fader - Values') + + activeDevice.setState(activePage + ' - Fader - Values', setTextOfColumn(channelIndex, makeLabel(value, 6), faderValues)) + Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', 'AltRow1', 'AltRow2', activeDevice, midiOutput) - channelControl.panTitlesDisplay.mOnTitleChange = (function (activeDevice, objectTitle, valueTitle) { - channelControl.panObjectTitle = objectTitle - channelControl.panValueTitle = valueTitle + }).bind({ midiOutput, channelIndex }) + + channelControl.pushEncoder.mEncoderValue.mOnTitleChange = (function (activeDevice, objectTitle, valueTitle) { console.log("Pan Title Changed:" + objectTitle + ":" + valueTitle) var activePage = activeDevice.getState("activePage") + var panTitles = activeDevice.getState(activePage + ' - Pan - Title') + var panValueTitles = activeDevice.getState(activePage + ' - Pan - ValueTitles') + switch (activePage) { case "SelectedTrack": - // For selected track trime the send channel number since it's lined up with the Platform M+ numbering anyway - channelControl.panObjectTitle = channelControl.panObjectTitle.slice(3) + var title = objectTitle.slice(2) + if (title.length === 0) { + title = "None" + } + activeDevice.setState(activePage + ' - Pan - ValueTitles', setTextOfColumn(channelIndex, makeLabel(title, 6), panValueTitles)) + Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) break; default: - console.log("No page specific binding defined") - // do nothing + activeDevice.setState(activePage + ' - Pan - Title', setTextOfColumn(channelIndex, makeLabel(objectTitle, 6), panTitles)) + activeDevice.setState(activePage + ' - Pan - ValueTitles', setTextOfColumn(channelIndex, makeLabel(valueTitle, 6), panValueTitles)) + Helper_updateDisplay(activePage + ' - Fader - Title', activePage + ' - Fader - Values', activePage + ' - Pan - Title', activePage + ' - Pan - Values', activeDevice, midiOutput) break; } - updateDisplay(activeDevice, midiOutput, surfaceElements) - }).bind({ midiOutput }) - channelControl.panTitlesDisplay.mOnDisplayValueChange = (function (activeDevice, value, units) { + }).bind({ midiOutput, channelIndex }) + + channelControl.pushEncoder.mEncoderValue.mOnDisplayValueChange = (function (activeDevice, value, units) { console.log("Pan Value Change: " + value + ":" + units) - channelControl.panValue = value var activePage = activeDevice.getState("activePage") + var panValues = activeDevice.getState(activePage + ' - Pan - Values') + + activeDevice.setState(activePage + ' - Pan - Values', setTextOfColumn(channelIndex, makeLabel(value, 6), panValues)) switch (activePage) { - case "Mixer": - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value, 6))) - break; case "SelectedTrack": - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel('Sends-' + channelControl.trackObjectTitle + "-" + channelControl.panObjectTitle, 56))) - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(value, 6))) + Helper_updateDisplay('Row1', 'Row2', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) break; default: - console.log("No page specific binding defined") - midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("No " + activePage + " specific binding defined", 56))) + Helper_updateDisplay('Row1', 'Row2', activePage + ' - Pan - Title', activePage + ' - Pan - Values', activeDevice, midiOutput) break; } - }).bind({ midiOutput }) - // ! Hmm, I wonder if my use of the *TitlesDisplay custom variables is unnecessary based on this one - channelControl.pushEncoder.mPushValue.mOnDisplayValueChange = (function (activeDevice, value, units) { - console.log("Pan push Value Change: " + value + ":" + units) - channelControl.panPushValue = value - updateDisplay(activeDevice, midiOutput, surfaceElements) - }).bind({ midiOutput }) + }).bind({ midiOutput, channelIndex }) return channelControl @@ -439,13 +414,20 @@ function makeMasterControl(surface, midiInput, midiOutput, x, y, instance, surfa masterControl.mixer_button.mSurfaceValue.mOnProcessValueChange = function (activeDevice) { var value = masterControl.mixer_button.mSurfaceValue.getProcessValue(activeDevice) if (value == 1) { - flip = !flip - if (flip) + var displayType = activeDevice.getState("displayType") + if (displayType === "Fader") { + displayType = "Pan" + } else { + displayType = "Fader" + } + activeDevice.setState("displayType", displayType) + + if (displayType === "Pan") midiOutput.sendMidi(activeDevice, [0x90, 84, 127]) else { midiOutput.sendMidi(activeDevice, [0x90, 84, 0]) } - updateDisplay(activeDevice, midiOutput, surfaceElements) + Helper_updateDisplay('Row1', 'Row2', 'AltRow1', 'AltRow2', activeDevice, midiOutput) } } return masterControl @@ -500,12 +482,6 @@ function makeTransport(surface, midiInput, midiOutput, x, y, surfaceElements) { transport.btnFlip = surface.makeButton(x + 0.5, y + 15, 2, 2).setShapeCircle() bindMidiNote(transport.btnFlip, 0, 50) - transport.btnFlip.mSurfaceValue.mOnProcessValueChange = function (activeDevice, number1, number2) { - flip = !flip - updateDisplay(activeDevice, midiOutput, surfaceElements) - console.log("transport flip: " + flip) - } - // Pressing the Zoom keys simultaneously will toggle on and off a note event. If on // either zoom button will send a Note 100 when zoom is activated or deactivated by either button // If zoom is active and you simply press then other button the event will not be sent @@ -595,5 +571,5 @@ module.exports = { makeTouchFader, bindCommandKnob, clearAllLeds, - updateDisplay + Helper_updateDisplay } diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 3fe885a..1d49508 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -9,7 +9,7 @@ var makeChannelControl = iconElements.makeChannelControl var makeMasterControl = iconElements.makeMasterControl var makeTransport = iconElements.makeTransport var clearAllLeds = iconElements.clearAllLeds -var updateDisplay = iconElements.updateDisplay +var Helper_updateDisplay = iconElements.Helper_updateDisplay //----------------------------------------------------------------------------- // 1. DRIVER SETUP - create driver object, midi ports and detection information @@ -64,6 +64,13 @@ function makeSurfaceElements() { surfaceElements.faderMaster = makeMasterControl(surface, midiInput, midiOutput, xKnobStrip + 1, yKnobStrip + 4, surfaceElements.numStrips, surfaceElements) surfaceElements.transport = makeTransport(surface, midiInput, midiOutput, xKnobStrip + 63, yKnobStrip + 4, surfaceElements) + // Track the selected track name + surfaceElements.selectedTrack = surface.makeCustomValueVariable('selectedTrack'); + surfaceElements.selectedTrack.mOnTitleChange = function(activeDevice, objectTitle, valueTitle) { + console.log('selectedTrack title change:'+objectTitle) + activeDevice.setState('selectedTrackName', objectTitle) + } + return surfaceElements } @@ -80,24 +87,24 @@ function makeSubPage(subPageArea, name) { var msgText = 'sub page ' + name + ' activated' subPage.mOnActivate = (function (activeDevice) { console.log(msgText) - activeDevice.setState("activeSubPage",name) + activeDevice.setState("activeSubPage", name) var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, ] switch (name) { case "Scrub": - activeDevice.setState("indicator2","S") + activeDevice.setState("indicator2", "S") break; case "Nudge": - activeDevice.setState("indicator2","N") + activeDevice.setState("indicator2", "N") break; case "Nav": - activeDevice.setState("indicator1","N") + activeDevice.setState("indicator1", "N") break; case "Zoom": - activeDevice.setState("indicator1","Z") + activeDevice.setState("indicator1", "Z") break; } - updateDisplay(activeDevice, midiOutput, surfaceElements) + Helper_updateDisplay('Row1', 'Row2', 'AltRow1', 'AltRow2', activeDevice, midiOutput) }).bind({ subPage, name }) return subPage } @@ -152,7 +159,6 @@ function makePageWithDefaults(name) { var MasterFaderSubPageArea = page.makeSubPageArea('MasterFader') var subPageMasterFaderValue = makeSubPage(MasterFaderSubPageArea, 'MF_ValueUnderCursor') - // var subPageMasterFaderMain = makeSubPage(MasterFaderSubPageArea, 'MF_MainOut') page.makeValueBinding(surfaceElements.faderMaster.fader.mSurfaceValue, page.mHostAccess.mMouseCursor.mValueUnderMouse).setValueTakeOverModeJump().setSubPage(subPageMasterFaderValue) @@ -192,12 +198,6 @@ function makePageMixer() { var solo_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].solo_button.mSurfaceValue; var rec_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].rec_button.mSurfaceValue; - // Displays - // D2 - page.makeValueBinding(surfaceElements.channelControls[channelIndex].trackNameDisplay, hostMixerBankChannel.mValue.mVolume) - page.makeValueBinding(surfaceElements.channelControls[channelIndex].faderTitlesDisplay, hostMixerBankChannel.mValue.mVolume) // for Platform M+ D2 Display - page.makeValueBinding(surfaceElements.channelControls[channelIndex].panTitlesDisplay, hostMixerBankChannel.mValue.mPan) // for Platform M+ D2 Display - // FaderKnobs - Volume, Pan, Editor Open page.makeValueBinding(knobSurfaceValue, hostMixerBankChannel.mValue.mPan).setSubPage(subPageFaderVolume) page.makeValueBinding(knobPushValue, hostMixerBankChannel.mValue.mEditorOpen).setTypeToggle().setSubPage(subPageFaderVolume) @@ -222,6 +222,8 @@ function makePageSelectedTrack() { var selectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel + // Custom variable for track the selectedTrack so we can get to it's name + page.makeValueBinding(surfaceElements.selectedTrack, selectedTrackChannel.mValue.mVolume) /// SendsQC subPage // Sends on PushEncodes and mute button for pre/post // Focus QC on Faders @@ -231,11 +233,6 @@ function makePageSelectedTrack() { var knobPushValue = surfaceElements.channelControls[idx].pushEncoder.mPushValue; var faderSurfaceValue = surfaceElements.channelControls[idx].fader.mSurfaceValue; - // Displays - page.makeValueBinding(surfaceElements.channelControls[idx].trackNameDisplay, selectedTrackChannel.mValue.mVolume) - page.makeValueBinding(surfaceElements.channelControls[idx].faderTitlesDisplay, page.mHostAccess.mFocusedQuickControls.getByIndex(idx)) // for Platform M+ D2 Display - page.makeValueBinding(surfaceElements.channelControls[idx].panTitlesDisplay, selectedTrackChannel.mSends.getByIndex(idx).mLevel) // for Platform M+ D2 Display - page.makeValueBinding(knobSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mLevel).setSubPage(subPageSendsQC) page.makeValueBinding(knobPushValue, selectedTrackChannel.mSends.getByIndex(idx).mOn).setTypeToggle().setSubPage(subPageSendsQC) page.makeValueBinding(faderSurfaceValue, page.mHostAccess.mFocusedQuickControls.getByIndex(idx)).setValueTakeOverModeJump().setSubPage(subPageSendsQC) @@ -336,99 +333,104 @@ function makePageSelectedTrack() { return page } -function makePageChannelStrip() { - var page = makePageWithDefaults('Channelstrip') - - var strip = page.makeSubPageArea('strip') - var gatePage = makeSubPage(strip, 'Gate') - var compressorPage = makeSubPage(strip, 'Compressor') - var toolsPage = makeSubPage(strip, 'Tools') - var saturatorPage = makeSubPage(strip, 'Saturator') - var limiterPage = makeSubPage(strip, 'Limiter') - - - var selectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel - var stripEffects = selectedTrackChannel.mInsertAndStripEffects.mStripEffects - - for (var idx = 0; idx < surfaceElements.numStrips; ++idx) { - var knobSurfaceValue = surfaceElements.channelControls[idx].pushEncoder.mEncoderValue; - var knobPushValue = surfaceElements.channelControls[idx].pushEncoder.mPushValue; - var faderSurfaceValue = surfaceElements.channelControls[idx].fader.mSurfaceValue; - - page.makeValueBinding(faderSurfaceValue, stripEffects.mGate.mParameterBankZone.makeParameterValue()).setSubPage(gatePage) - page.makeValueBinding(faderSurfaceValue, stripEffects.mCompressor.mParameterBankZone.makeParameterValue()).setSubPage(compressorPage) - page.makeValueBinding(faderSurfaceValue, stripEffects.mTools.mParameterBankZone.makeParameterValue()).setSubPage(toolsPage) - page.makeValueBinding(faderSurfaceValue, stripEffects.mSaturator.mParameterBankZone.makeParameterValue()).setSubPage(saturatorPage) - page.makeValueBinding(faderSurfaceValue, stripEffects.mLimiter.mParameterBankZone.makeParameterValue()).setSubPage(limiterPage) - } - - for (var idx = 0; idx < 5; ++idx) { - var faderStrip = surfaceElements.channelControls[idx] - var type = ['mGate', 'mCompressor', 'mTools', 'mSaturator', 'mLimiter'][idx] - page.makeValueBinding(faderStrip.rec_button.mSurfaceValue, stripEffects[type].mOn).setTypeToggle() - page.makeValueBinding(faderStrip.mute_button.mSurfaceValue, stripEffects[type].mBypass).setTypeToggle() - } - - page.makeActionBinding(surfaceElements.channelControls[0].sel_button.mSurfaceValue, gatePage.mAction.mActivate) - page.makeActionBinding(surfaceElements.channelControls[1].sel_button.mSurfaceValue, compressorPage.mAction.mActivate) - page.makeActionBinding(surfaceElements.channelControls[2].sel_button.mSurfaceValue, toolsPage.mAction.mActivate) - page.makeActionBinding(surfaceElements.channelControls[3].sel_button.mSurfaceValue, saturatorPage.mAction.mActivate) - page.makeActionBinding(surfaceElements.channelControls[4].sel_button.mSurfaceValue, limiterPage.mAction.mActivate) - - gatePage.mOnActivate = function (device) { setLeds(device, 24, 'Gate') } - compressorPage.mOnActivate = function (device) { setLeds(device, 25, 'Compressor') } - toolsPage.mOnActivate = function (device) { setLeds(device, 26, 'Tools') } - saturatorPage.mOnActivate = function (device) { setLeds(device, 27, 'Saturator') } - limiterPage.mOnActivate = function (device) { setLeds(device, 28, 'Limiter') } - - function setLeds(device, value, text) { - console.log('from script: Platform M+ subpage "' + text + '" activated') - for (var i = 0; i < 5; ++i) { - midiOutput.sendMidi(device, [0x90, 24 + i, 0]) - } - midiOutput.sendMidi(device, [0x90, value, 127]) - } - - return page -} +// function makePageChannelStrip() { +// var page = makePageWithDefaults('Channelstrip') + +// var strip = page.makeSubPageArea('strip') +// var gatePage = makeSubPage(strip, 'Gate') +// var compressorPage = makeSubPage(strip, 'Compressor') +// var toolsPage = makeSubPage(strip, 'Tools') +// var saturatorPage = makeSubPage(strip, 'Saturator') +// var limiterPage = makeSubPage(strip, 'Limiter') + + +// var selectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel +// var stripEffects = selectedTrackChannel.mInsertAndStripEffects.mStripEffects + +// for (var idx = 0; idx < surfaceElements.numStrips; ++idx) { +// var knobSurfaceValue = surfaceElements.channelControls[idx].pushEncoder.mEncoderValue; +// var knobPushValue = surfaceElements.channelControls[idx].pushEncoder.mPushValue; +// var faderSurfaceValue = surfaceElements.channelControls[idx].fader.mSurfaceValue; + +// page.makeValueBinding(faderSurfaceValue, stripEffects.mGate.mParameterBankZone.makeParameterValue()).setSubPage(gatePage) +// page.makeValueBinding(faderSurfaceValue, stripEffects.mCompressor.mParameterBankZone.makeParameterValue()).setSubPage(compressorPage) +// page.makeValueBinding(faderSurfaceValue, stripEffects.mTools.mParameterBankZone.makeParameterValue()).setSubPage(toolsPage) +// page.makeValueBinding(faderSurfaceValue, stripEffects.mSaturator.mParameterBankZone.makeParameterValue()).setSubPage(saturatorPage) +// page.makeValueBinding(faderSurfaceValue, stripEffects.mLimiter.mParameterBankZone.makeParameterValue()).setSubPage(limiterPage) +// } + +// for (var idx = 0; idx < 5; ++idx) { +// var faderStrip = surfaceElements.channelControls[idx] +// var type = ['mGate', 'mCompressor', 'mTools', 'mSaturator', 'mLimiter'][idx] +// page.makeValueBinding(faderStrip.rec_button.mSurfaceValue, stripEffects[type].mOn).setTypeToggle() +// page.makeValueBinding(faderStrip.mute_button.mSurfaceValue, stripEffects[type].mBypass).setTypeToggle() +// } + +// page.makeActionBinding(surfaceElements.channelControls[0].sel_button.mSurfaceValue, gatePage.mAction.mActivate) +// page.makeActionBinding(surfaceElements.channelControls[1].sel_button.mSurfaceValue, compressorPage.mAction.mActivate) +// page.makeActionBinding(surfaceElements.channelControls[2].sel_button.mSurfaceValue, toolsPage.mAction.mActivate) +// page.makeActionBinding(surfaceElements.channelControls[3].sel_button.mSurfaceValue, saturatorPage.mAction.mActivate) +// page.makeActionBinding(surfaceElements.channelControls[4].sel_button.mSurfaceValue, limiterPage.mAction.mActivate) + +// gatePage.mOnActivate = function (device) { setLeds(device, 24, 'Gate') } +// compressorPage.mOnActivate = function (device) { setLeds(device, 25, 'Compressor') } +// toolsPage.mOnActivate = function (device) { setLeds(device, 26, 'Tools') } +// saturatorPage.mOnActivate = function (device) { setLeds(device, 27, 'Saturator') } +// limiterPage.mOnActivate = function (device) { setLeds(device, 28, 'Limiter') } + +// function setLeds(device, value, text) { +// console.log('from script: Platform M+ subpage "' + text + '" activated') +// for (var i = 0; i < 5; ++i) { +// midiOutput.sendMidi(device, [0x90, 24 + i, 0]) +// } +// midiOutput.sendMidi(device, [0x90, value, 127]) +// } + +// return page +// } var mixerPage = makePageMixer() var selectedTrackPage = makePageSelectedTrack() -var channelStripPage = makePageChannelStrip() +// WIP Add Channel Strip Page +// var channelStripPage = makePageChannelStrip() +// WIP Add Control Room Page +// WIP Add MIDI CC Page and extra MIDI Port // Function to clear out the Channel State for the display titles/values // the OnDisplayChange callback is not called if the Channel doesn't have an updated // Title. So swtiching to QC would leave the old Mixer Page "Volume" title kicking around // in the state. By clearing state on the page activation it will update all that are changing. -function clearChannelState() { - for (var i = 0; i < surfaceElements.numStrips; ++i) { - surfaceElements.channelControls[i].faderObjectTitle = "" - surfaceElements.channelControls[i].faderValueTitle = "" - surfaceElements.channelControls[i].faderValue = "" - surfaceElements.channelControls[i].panObjectTitle = "" - surfaceElements.channelControls[i].panValueTitle = "" - surfaceElements.channelControls[i].panValue = "" - surfaceElements.channelControls[i].panPushValue = "" - } +function clearChannelState(/** @type {MR_ActiveDevice} */activeDevice) { + var activePage = activeDevice.getState("activePage") + + activeDevice.setState(activePage + ' - Fader - Title', "") + activeDevice.setState(activePage + ' - Fader - ValueTitles', "") + activeDevice.setState(activePage + ' - Fader - Values', "") + activeDevice.setState(activePage + ' - Pan - Title', "") + activeDevice.setState(activePage + ' - Pan - ValueTitles', "") + activeDevice.setState(activePage + ' - Pan - Values', "") + + activeDevice.setState("displayType", "Fader") } mixerPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDevice) { console.log('from script: Platform M+ page "Mixer" activated') activeDevice.setState("activePage", "Mixer") clearAllLeds(activeDevice, midiOutput) - clearChannelState() + clearChannelState(activeDevice) }).bind({ midiOutput }) selectedTrackPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDevice) { console.log('from script: Platform M+ page "Selected Track" activated') activeDevice.setState("activePage", "SelectedTrack") clearAllLeds(activeDevice, midiOutput) - clearChannelState() + clearChannelState(activeDevice) }).bind({ midiOutput }) -channelStripPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDevice) { - console.log('from script: Platform M+ page "Channel Strip" activated') - activeDevice.setState("activePage", "ChannelStrip") - clearAllLeds(activeDevice, midiOutput) - clearChannelState() -}).bind({ midiOutput }) +// WIP Add Channel Strip Page +// channelStripPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDevice) { +// console.log('from script: Platform M+ page "Channel Strip" activated') +// activeDevice.setState("activePage", "ChannelStrip") +// clearAllLeds(activeDevice, midiOutput) +// clearChannelState(activeDevice) +// }).bind({ midiOutput }) From a6ee4a6982a4042a167d52f56eceb8e5769eaacf Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 18 Dec 2022 11:57:51 +1100 Subject: [PATCH 49/65] Remove no longer required code --- icon/platformmplus/helper.js | 44 ------------ icon/platformmplus/icon_elements.js | 103 ---------------------------- 2 files changed, 147 deletions(-) diff --git a/icon/platformmplus/helper.js b/icon/platformmplus/helper.js index 1ed5086..53521fe 100644 --- a/icon/platformmplus/helper.js +++ b/icon/platformmplus/helper.js @@ -1,18 +1,3 @@ - -// function displaySetTextOfColumn(columnIndex, rowIndex, textString) { -// var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, -// columnIndex * 7 + rowIndex * 56] - -// var text = (textString + ' ').slice(0, 7) // ensure to always clear a column -// // console.log("display:" + text) -// for (var i = 0; i < 7; ++i) -// data.push(text.charCodeAt(i)) -// data.push(0xf7) - -// return data -// } - - function setTextOfColumn(columnIndex, col_text, original_text) { var col = columnIndex * 7 var text = (col_text + ' ').slice(0, 7) // ensure to always clear a column @@ -36,31 +21,6 @@ function setTextOfLine(textString) { return text } -// function displaySetTextOfLine(rowIndex, textString) { -// var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, -// rowIndex * 56] -// var blank = Array(56).join(" ") -// var text = (textString + blank).slice(0, 56) // ensure to always clear the entire row -// // console.log("display:" + text) -// for (var i = 0; i < 56; ++i) -// data.push(text.charCodeAt(i)) -// data.push(0xf7) - -// return data -// } - -/** - * @param {MR_ActiveDevice} activeDevice - * @param {MR_DeviceMidiOutput} outPort - */ -// function resetDisplay(activeDevice, outPort) { -// for (var i = 0; i < 8; ++i) { -// for (var k = 0; k < 2; ++k) { -// outPort.sendMidi(activeDevice, displaySetTextOfColumn(i, k, " ")) -// } -// } -// } - function makeLabel(value, length) { // console.log("makeLabel:" + value) // Do nothing if the label is already short enough @@ -88,10 +48,6 @@ function makeLabel(value, length) { } module.exports = { - // sysex: { - // displaySetTextOfColumn: displaySetTextOfColumn, - // displaySetTextOfLine: displaySetTextOfLine - // }, display: { // reset: resetDisplay, makeLabel: makeLabel, diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 45f0ed8..5643483 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -80,77 +80,6 @@ function Helper_updateDisplay(/** @type {string} */idRow1, /** @type {string} */ } -// function updateDisplay(/** @type {MR_ActiveDevice} */activeDevice, /** @type {MR_DeviceMidiOutput} */midiOutput, /** @type {Object} */surfaceElements) { -// var activePage = activeDevice.getState("activePage") -// var activeSubPage = activeDevice.getState("activeSubPage") -// switch (activePage) { -// case "Mixer": -// for (var i = 0; i < surfaceElements.numStrips; ++i) { -// var element = surfaceElements.channelControls[i] -// if (!flip) { -// midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 1, makeLabel(element.faderObjectTitle, 6))) -// midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel(element.faderValueTitle, 6))) -// midiOutput.sendMidi(activeDevice, [0x90, 84, 0]) // Mixer -// } -// else { -// midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 1, makeLabel(element.panObjectTitle, 6))) -// midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel(element.panValueTitle, 6))) -// midiOutput.sendMidi(activeDevice, [0x90, 84, 127]) // Mixer -// } -// } -// break; -// case "SelectedTrack": -// var msg = surfaceElements.channelControls[0].trackObjectTitle -// if (!flip) { -// midiOutput.sendMidi(activeDevice, [0x90, 84, 0]) // Mixer -// // For selected track all the trackObjectTitle are set to the same value -// // So send it once to the display and use the entire top line for the title -// midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel('QC-' + msg, 56))) -// for (var i = 0; i < surfaceElements.numStrips; ++i) { -// var element = surfaceElements.channelControls[i] -// midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel(element.faderValueTitle, 6))) -// } -// } -// else { -// midiOutput.sendMidi(activeDevice, [0x90, 84, 127]) // Mixer -// midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("Sends-" + msg, 56))) -// for (var i = 0; i < surfaceElements.numStrips; ++i) { -// var element = surfaceElements.channelControls[i] -// if (element.panPushValue == "On") { -// midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel(element.panObjectTitle, 6))) -// } else { -// midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(i, 0, makeLabel("Off", 6))) -// } -// } -// } -// break; -// default: -// console.log("No page specific binding defined") -// midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("No " + activePage + " specific binding defined", 56))) -// break; -// } - -// // Update indicator characters - last char of each row -// function display_indicator(row, indicator) { -// var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, -// ] -// if (row === 0) { -// data.push(55) -// } else { -// data.push(111) -// } -// data.push(indicator.charCodeAt(0)) -// data.push(0xf7) -// midiOutput.sendMidi(activeDevice, data) -// } - -// var indicator1 = activeDevice.getState("indicator1") -// var indicator2 = activeDevice.getState("indicator2") - -// display_indicator(1, indicator1) -// display_indicator(0, indicator2) -// } - /** * @param {MR_DeviceSurface} surface * @param {MR_DeviceMidiInput} midiInput @@ -488,38 +417,6 @@ function makeTransport(surface, midiInput, midiOutput, x, y, surfaceElements) { // transport.btnZoomOnOff = surface.makeButton(x + 3.5, y + 15, 2, 2).setShapeCircle() bindMidiNote(transport.btnZoomOnOff, 0, 100) - // transport.zoomState = surface.makeCustomValueVariable('ZoomState'); - // transport.zoomState.mMidiBinding.setInputPort(midiInput).bindToNote(0, 100) - // transport.zoomState.mOnProcessValueChange = function (activeDevice, number1, number2) { - - // console.log("zoomState: " + number1 + ":" + number2) - // // switch (activePage) { - // // case "Mixer": - // // if (touched) { - // // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderValueTitle, 6))) - // // } - // // else { - // // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 1, makeLabel(channelControl.faderObjectTitle, 6))) - // // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(channelControl.faderValueTitle, 6))) - // // } - // // break; - // // case "SelectedTrack": - // // if (touched) { - // // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.faderValueTitle, 56))) - // // } - // // else { - // // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel(channelControl.trackObjectTitle, 56))) - // // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(channelIndex, 0, makeLabel(channelControl.faderValueTitle, 6))) - // // } - // // break; - // // default: - // // console.log("No page specific binding defined") - // // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfLine(1, makeLabel("No "+activePage+" specific binding defined", 56))) - // // break; - // // } - - // } - // The Jog wheel will change CC/Note based on which of thte Zoom buttons have been activated // None - CC 60 From 7eb8f21cf31c67706243e8c671db76cf6248c5f6 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 18 Dec 2022 12:05:57 +1100 Subject: [PATCH 50/65] Simplify value change (and fix faders saying Volume!!) --- icon/platformmplus/icon_elements.js | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 5643483..b770947 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -258,7 +258,7 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf var faderValues = activeDevice.getState(activePage + ' - Fader - Values') activeDevice.setState(activePage + ' - Fader - Values', setTextOfColumn(channelIndex, makeLabel(value, 6), faderValues)) - Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', 'AltRow1', 'AltRow2', activeDevice, midiOutput) + Helper_updateDisplay('Row1', activePage + ' - Fader - Values', 'AltRow1', 'AltRow2', activeDevice, midiOutput) }).bind({ midiOutput, channelIndex }) @@ -292,14 +292,7 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf var panValues = activeDevice.getState(activePage + ' - Pan - Values') activeDevice.setState(activePage + ' - Pan - Values', setTextOfColumn(channelIndex, makeLabel(value, 6), panValues)) - switch (activePage) { - case "SelectedTrack": - Helper_updateDisplay('Row1', 'Row2', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) - break; - default: - Helper_updateDisplay('Row1', 'Row2', activePage + ' - Pan - Title', activePage + ' - Pan - Values', activeDevice, midiOutput) - break; - } + Helper_updateDisplay('Row1', 'Row2', 'AltRow1', activePage + ' - Pan - Values', activeDevice, midiOutput) }).bind({ midiOutput, channelIndex }) From e78320d88d5297f8a7e92606cdd279e4e33b43f9 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 18 Dec 2022 12:52:29 +1100 Subject: [PATCH 51/65] Logs less busy --- icon/platformmplus/icon_elements.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index b770947..3f81d17 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -253,7 +253,7 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf }).bind({ midiOutput }) channelControl.fader.mSurfaceValue.mOnDisplayValueChange = (function (activeDevice, value, units) { - console.log("Fader Display Value Change: " + value + ":" + units) + // console.log("Fader Display Value Change: " + value + ":" + units) var activePage = activeDevice.getState("activePage") var faderValues = activeDevice.getState(activePage + ' - Fader - Values') @@ -263,7 +263,7 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf }).bind({ midiOutput, channelIndex }) channelControl.pushEncoder.mEncoderValue.mOnTitleChange = (function (activeDevice, objectTitle, valueTitle) { - console.log("Pan Title Changed:" + objectTitle + ":" + valueTitle) + // console.log("Pan Title Changed:" + objectTitle + ":" + valueTitle) var activePage = activeDevice.getState("activePage") var panTitles = activeDevice.getState(activePage + ' - Pan - Title') var panValueTitles = activeDevice.getState(activePage + ' - Pan - ValueTitles') @@ -287,7 +287,7 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf }).bind({ midiOutput, channelIndex }) channelControl.pushEncoder.mEncoderValue.mOnDisplayValueChange = (function (activeDevice, value, units) { - console.log("Pan Value Change: " + value + ":" + units) + // console.log("Pan Value Change: " + value + ":" + units) var activePage = activeDevice.getState("activePage") var panValues = activeDevice.getState(activePage + ' - Pan - Values') From 02d4259b5826c2b8690adce05bf962ac9e82ff5a Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 18 Dec 2022 13:30:37 +1100 Subject: [PATCH 52/65] SelectedChannel subPage display tidy up --- icon/platformmplus/icon_elements.js | 23 +++++++++--- icon/platformmplus/icon_platformmplus.js | 46 +++++++++++++++++++++--- 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 3f81d17..a83852d 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -265,17 +265,30 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf channelControl.pushEncoder.mEncoderValue.mOnTitleChange = (function (activeDevice, objectTitle, valueTitle) { // console.log("Pan Title Changed:" + objectTitle + ":" + valueTitle) var activePage = activeDevice.getState("activePage") + var activeSubPage = activeDevice.getState("activeSubPage") var panTitles = activeDevice.getState(activePage + ' - Pan - Title') var panValueTitles = activeDevice.getState(activePage + ' - Pan - ValueTitles') switch (activePage) { case "SelectedTrack": - var title = objectTitle.slice(2) - if (title.length === 0) { - title = "None" + switch (activeSubPage) { + case "SendsQC": + var title = objectTitle.slice(2) + if (title.length === 0) { + title = "None" + } + activeDevice.setState(activePage + ' - Pan - ValueTitles', setTextOfColumn(channelIndex, makeLabel(title, 6), panValueTitles)) + Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) + break; + default: + var title = valueTitle + if (title.length === 0) { + title = "None" + } + activeDevice.setState(activePage + ' - Pan - ValueTitles', setTextOfColumn(channelIndex, makeLabel(title, 6), panValueTitles)) + Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) + break; } - activeDevice.setState(activePage + ' - Pan - ValueTitles', setTextOfColumn(channelIndex, makeLabel(title, 6), panValueTitles)) - Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) break; default: activeDevice.setState(activePage + ' - Pan - Title', setTextOfColumn(channelIndex, makeLabel(objectTitle, 6), panTitles)) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 1d49508..fd143d3 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -66,8 +66,8 @@ function makeSurfaceElements() { // Track the selected track name surfaceElements.selectedTrack = surface.makeCustomValueVariable('selectedTrack'); - surfaceElements.selectedTrack.mOnTitleChange = function(activeDevice, objectTitle, valueTitle) { - console.log('selectedTrack title change:'+objectTitle) + surfaceElements.selectedTrack.mOnTitleChange = function (activeDevice, objectTitle, valueTitle) { + console.log('selectedTrack title change:' + objectTitle) activeDevice.setState('selectedTrackName', objectTitle) } @@ -85,7 +85,7 @@ var surfaceElements = makeSurfaceElements() function makeSubPage(subPageArea, name) { var subPage = subPageArea.makeSubPage(name) var msgText = 'sub page ' + name + ' activated' - subPage.mOnActivate = (function (activeDevice) { + subPage.mOnActivate = (function (/** @type {MR_ActiveDevice} **/activeDevice) { console.log(msgText) activeDevice.setState("activeSubPage", name) var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, @@ -103,6 +103,39 @@ function makeSubPage(subPageArea, name) { case "Zoom": activeDevice.setState("indicator1", "Z") break; + case "SendsQC": + // An action binding cannot be set to ta Toggle type button so manually adjust the rec button lights + // based on the subpage selection. + midiOutput.sendMidi(activeDevice, [0x90, 0, 127]) + midiOutput.sendMidi(activeDevice, [0x90, 1, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 2, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 3, 0]) + break; + case "EQ": + // An action binding cannot be set to ta Toggle type button so manually adjust the rec button lights + // based on the subpage selection. + midiOutput.sendMidi(activeDevice, [0x90, 0, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 1, 127]) + midiOutput.sendMidi(activeDevice, [0x90, 2, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 3, 0]) + break; + case "PreFilter": + // An action binding cannot be set to ta Toggle type button so manually adjust the rec button lights + // based on the subpage selection. + midiOutput.sendMidi(activeDevice, [0x90, 0, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 1, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 2, 127]) + midiOutput.sendMidi(activeDevice, [0x90, 3, 0]) + break; + case "CueSends": + // An action binding cannot be set to ta Toggle type button so manually adjust the rec button lights + // based on the subpage selection. + midiOutput.sendMidi(activeDevice, [0x90, 0, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 1, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 2, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 3, 127]) + break; + } Helper_updateDisplay('Row1', 'Row2', 'AltRow1', 'AltRow2', activeDevice, midiOutput) }).bind({ subPage, name }) @@ -263,7 +296,6 @@ function makePageSelectedTrack() { page.makeActionBinding(surfaceElements.channelControls[2].rec_button.mSurfaceValue, subPagePreFilter.mAction.mActivate).setSubPage(subPageSendsQC) page.makeActionBinding(surfaceElements.channelControls[3].rec_button.mSurfaceValue, subPageCueSends.mAction.mActivate).setSubPage(subPageSendsQC) - // WIP Add Subpage Displays to Selected channel // EQ Subpage const eqBand = [] eqBand[0] = selectedTrackChannel.mChannelEQ.mBand1 @@ -424,6 +456,12 @@ selectedTrackPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeD activeDevice.setState("activePage", "SelectedTrack") clearAllLeds(activeDevice, midiOutput) clearChannelState(activeDevice) + // Set the Rec leds which correspond to the different subages to their starting state + activeDevice.setState("activeSubPage", "SendsQC") + midiOutput.sendMidi(activeDevice, [0x90, 0, 127]) + midiOutput.sendMidi(activeDevice, [0x90, 1, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 2, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 3, 0]) }).bind({ midiOutput }) // WIP Add Channel Strip Page From 7f0f042eddd29d05054c10913f669f4e6a7fd914 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 18 Dec 2022 14:11:29 +1100 Subject: [PATCH 53/65] A channelstrip of sorts --- icon/platformmplus/icon_elements.js | 6 +- icon/platformmplus/icon_platformmplus.js | 162 ++++++++++++++--------- 2 files changed, 102 insertions(+), 66 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index a83852d..ddc11a6 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -234,12 +234,16 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf var channelIndex = channelControl.instance channelControl.fader.mSurfaceValue.mOnTitleChange = (function (activeDevice, objectTitle, valueTitle) { - // console.log("Fader Title Change: " + channelIndex + "::" + objectTitle + ":" + valueTitle) + console.log("Fader Title Change: " + channelIndex + "::" + objectTitle + ":" + valueTitle) var activePage = activeDevice.getState("activePage") var faderTitles = activeDevice.getState(activePage + ' - Fader - Title') var faderValueTitles = activeDevice.getState(activePage + ' - Fader - ValueTitles') switch (activePage) { + case "ChannelStrip": + activeDevice.setState(activePage + ' - Fader - ValueTitles', setTextOfColumn(channelIndex, makeLabel(valueTitle, 6), faderValueTitles)) + Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) + break; case "SelectedTrack": activeDevice.setState(activePage + ' - Fader - ValueTitles', setTextOfColumn(channelIndex, makeLabel(valueTitle, 6), faderValueTitles)) Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index fd143d3..ea5d5f9 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -135,7 +135,51 @@ function makeSubPage(subPageArea, name) { midiOutput.sendMidi(activeDevice, [0x90, 2, 0]) midiOutput.sendMidi(activeDevice, [0x90, 3, 127]) break; - + case "Gate": + // An action binding cannot be set to ta Toggle type button so manually adjust the sel button lights + // based on the subpage selection. + midiOutput.sendMidi(activeDevice, [0x90, 24, 127]) + midiOutput.sendMidi(activeDevice, [0x90, 25, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 26, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 27, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 28, 0]) + break; + case "Compressor": + // An action binding cannot be set to ta Toggle type button so manually adjust the sel button lights + // based on the subpage selection. + midiOutput.sendMidi(activeDevice, [0x90, 24, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 25, 127]) + midiOutput.sendMidi(activeDevice, [0x90, 26, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 27, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 28, 0]) + break; + case "Tools": + // An action binding cannot be set to ta Toggle type button so manually adjust the sel button lights + // based on the subpage selection. + midiOutput.sendMidi(activeDevice, [0x90, 24, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 25, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 26, 127]) + midiOutput.sendMidi(activeDevice, [0x90, 27, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 28, 0]) + break; + case "Saturator": + // An action binding cannot be set to ta Toggle type button so manually adjust the sel button lights + // based on the subpage selection. + midiOutput.sendMidi(activeDevice, [0x90, 24, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 25, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 26, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 27, 127]) + midiOutput.sendMidi(activeDevice, [0x90, 28, 0]) + break; + case "Limiter": + // An action binding cannot be set to ta Toggle type button so manually adjust the sel button lights + // based on the subpage selection. + midiOutput.sendMidi(activeDevice, [0x90, 24, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 25, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 26, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 27, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 28, 127]) + break; } Helper_updateDisplay('Row1', 'Row2', 'AltRow1', 'AltRow2', activeDevice, midiOutput) }).bind({ subPage, name }) @@ -365,66 +409,49 @@ function makePageSelectedTrack() { return page } -// function makePageChannelStrip() { -// var page = makePageWithDefaults('Channelstrip') - -// var strip = page.makeSubPageArea('strip') -// var gatePage = makeSubPage(strip, 'Gate') -// var compressorPage = makeSubPage(strip, 'Compressor') -// var toolsPage = makeSubPage(strip, 'Tools') -// var saturatorPage = makeSubPage(strip, 'Saturator') -// var limiterPage = makeSubPage(strip, 'Limiter') - - -// var selectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel -// var stripEffects = selectedTrackChannel.mInsertAndStripEffects.mStripEffects - -// for (var idx = 0; idx < surfaceElements.numStrips; ++idx) { -// var knobSurfaceValue = surfaceElements.channelControls[idx].pushEncoder.mEncoderValue; -// var knobPushValue = surfaceElements.channelControls[idx].pushEncoder.mPushValue; -// var faderSurfaceValue = surfaceElements.channelControls[idx].fader.mSurfaceValue; - -// page.makeValueBinding(faderSurfaceValue, stripEffects.mGate.mParameterBankZone.makeParameterValue()).setSubPage(gatePage) -// page.makeValueBinding(faderSurfaceValue, stripEffects.mCompressor.mParameterBankZone.makeParameterValue()).setSubPage(compressorPage) -// page.makeValueBinding(faderSurfaceValue, stripEffects.mTools.mParameterBankZone.makeParameterValue()).setSubPage(toolsPage) -// page.makeValueBinding(faderSurfaceValue, stripEffects.mSaturator.mParameterBankZone.makeParameterValue()).setSubPage(saturatorPage) -// page.makeValueBinding(faderSurfaceValue, stripEffects.mLimiter.mParameterBankZone.makeParameterValue()).setSubPage(limiterPage) -// } - -// for (var idx = 0; idx < 5; ++idx) { -// var faderStrip = surfaceElements.channelControls[idx] -// var type = ['mGate', 'mCompressor', 'mTools', 'mSaturator', 'mLimiter'][idx] -// page.makeValueBinding(faderStrip.rec_button.mSurfaceValue, stripEffects[type].mOn).setTypeToggle() -// page.makeValueBinding(faderStrip.mute_button.mSurfaceValue, stripEffects[type].mBypass).setTypeToggle() -// } - -// page.makeActionBinding(surfaceElements.channelControls[0].sel_button.mSurfaceValue, gatePage.mAction.mActivate) -// page.makeActionBinding(surfaceElements.channelControls[1].sel_button.mSurfaceValue, compressorPage.mAction.mActivate) -// page.makeActionBinding(surfaceElements.channelControls[2].sel_button.mSurfaceValue, toolsPage.mAction.mActivate) -// page.makeActionBinding(surfaceElements.channelControls[3].sel_button.mSurfaceValue, saturatorPage.mAction.mActivate) -// page.makeActionBinding(surfaceElements.channelControls[4].sel_button.mSurfaceValue, limiterPage.mAction.mActivate) - -// gatePage.mOnActivate = function (device) { setLeds(device, 24, 'Gate') } -// compressorPage.mOnActivate = function (device) { setLeds(device, 25, 'Compressor') } -// toolsPage.mOnActivate = function (device) { setLeds(device, 26, 'Tools') } -// saturatorPage.mOnActivate = function (device) { setLeds(device, 27, 'Saturator') } -// limiterPage.mOnActivate = function (device) { setLeds(device, 28, 'Limiter') } - -// function setLeds(device, value, text) { -// console.log('from script: Platform M+ subpage "' + text + '" activated') -// for (var i = 0; i < 5; ++i) { -// midiOutput.sendMidi(device, [0x90, 24 + i, 0]) -// } -// midiOutput.sendMidi(device, [0x90, value, 127]) -// } - -// return page -// } +function makePageChannelStrip() { + var page = makePageWithDefaults('Channelstrip') + + var strip = page.makeSubPageArea('Strip') + var gatePage = makeSubPage(strip, 'Gate') + var compressorPage = makeSubPage(strip, 'Compressor') + var toolsPage = makeSubPage(strip, 'Tools') + var saturatorPage = makeSubPage(strip, 'Saturator') + var limiterPage = makeSubPage(strip, 'Limiter') + + + var selectedTrackChannel = page.mHostAccess.mTrackSelection.mMixerChannel + var stripEffects = selectedTrackChannel.mInsertAndStripEffects.mStripEffects + + for (var idx = 0; idx < surfaceElements.numStrips; ++idx) { + var faderSurfaceValue = surfaceElements.channelControls[idx].fader.mSurfaceValue; + + page.makeValueBinding(faderSurfaceValue, stripEffects.mGate.mParameterBankZone.makeParameterValue()).setSubPage(gatePage) + page.makeValueBinding(faderSurfaceValue, stripEffects.mCompressor.mParameterBankZone.makeParameterValue()).setSubPage(compressorPage) + page.makeValueBinding(faderSurfaceValue, stripEffects.mTools.mParameterBankZone.makeParameterValue()).setSubPage(toolsPage) + page.makeValueBinding(faderSurfaceValue, stripEffects.mSaturator.mParameterBankZone.makeParameterValue()).setSubPage(saturatorPage) + page.makeValueBinding(faderSurfaceValue, stripEffects.mLimiter.mParameterBankZone.makeParameterValue()).setSubPage(limiterPage) + } + + for (var idx = 0; idx < 5; ++idx) { + var faderStrip = surfaceElements.channelControls[idx] + var type = ['mGate', 'mCompressor', 'mTools', 'mSaturator', 'mLimiter'][idx] + page.makeValueBinding(faderStrip.rec_button.mSurfaceValue, stripEffects[type].mOn).setTypeToggle() + page.makeValueBinding(faderStrip.mute_button.mSurfaceValue, stripEffects[type].mBypass).setTypeToggle() + } + + page.makeActionBinding(surfaceElements.channelControls[0].sel_button.mSurfaceValue, gatePage.mAction.mActivate) + page.makeActionBinding(surfaceElements.channelControls[1].sel_button.mSurfaceValue, compressorPage.mAction.mActivate) + page.makeActionBinding(surfaceElements.channelControls[2].sel_button.mSurfaceValue, toolsPage.mAction.mActivate) + page.makeActionBinding(surfaceElements.channelControls[3].sel_button.mSurfaceValue, saturatorPage.mAction.mActivate) + page.makeActionBinding(surfaceElements.channelControls[4].sel_button.mSurfaceValue, limiterPage.mAction.mActivate) + + return page +} var mixerPage = makePageMixer() var selectedTrackPage = makePageSelectedTrack() -// WIP Add Channel Strip Page -// var channelStripPage = makePageChannelStrip() +var channelStripPage = makePageChannelStrip() // WIP Add Control Room Page // WIP Add MIDI CC Page and extra MIDI Port @@ -464,11 +491,16 @@ selectedTrackPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeD midiOutput.sendMidi(activeDevice, [0x90, 3, 0]) }).bind({ midiOutput }) -// WIP Add Channel Strip Page -// channelStripPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDevice) { -// console.log('from script: Platform M+ page "Channel Strip" activated') -// activeDevice.setState("activePage", "ChannelStrip") -// clearAllLeds(activeDevice, midiOutput) -// clearChannelState(activeDevice) -// }).bind({ midiOutput }) +channelStripPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDevice) { + console.log('from script: Platform M+ page "Channel Strip" activated') + activeDevice.setState("activePage", "ChannelStrip") + clearAllLeds(activeDevice, midiOutput) + clearChannelState(activeDevice) + activeDevice.setState("activeSubPage", "Gate") + midiOutput.sendMidi(activeDevice, [0x90, 24, 127]) + midiOutput.sendMidi(activeDevice, [0x90, 25, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 26, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 27, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 28, 0]) +}).bind({ midiOutput }) From d1f87cc6caf8f4b8b2dea5b28baceb7a73d01c51 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 18 Dec 2022 14:59:21 +1100 Subject: [PATCH 54/65] A basic control room page now --- icon/platformmplus/icon_elements.js | 5 +--- icon/platformmplus/icon_platformmplus.js | 38 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index ddc11a6..cd6eaed 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -43,7 +43,7 @@ function Helper_updateDisplay(/** @type {string} */idRow1, /** @type {string} */ } else { // Update display if it has changed if ((newRow1 !== prevRow1) || (newRow2 !== prevRow2) || (activeDisplayType !== displayType)) { - // console.log("Rows Display update" + newRow1+"::"+newRow2) + console.log("Rows Display update" + newRow1+"::"+newRow2) _sendDisplayData(1, newRow1, activeDevice, midiOutput) _sendDisplayData(0, newRow2, activeDevice, midiOutput) } @@ -241,9 +241,6 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf switch (activePage) { case "ChannelStrip": - activeDevice.setState(activePage + ' - Fader - ValueTitles', setTextOfColumn(channelIndex, makeLabel(valueTitle, 6), faderValueTitles)) - Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) - break; case "SelectedTrack": activeDevice.setState(activePage + ' - Fader - ValueTitles', setTextOfColumn(channelIndex, makeLabel(valueTitle, 6), faderValueTitles)) Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index ea5d5f9..1581b6f 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -449,10 +449,41 @@ function makePageChannelStrip() { return page } +function makePageControlRoom() { + var page = makePageWithDefaults('ControlRoom') + + var controlRoom = page.mHostAccess.mControlRoom + + // Main + page.makeValueBinding(surfaceElements.channelControls[0].fader.mSurfaceValue, controlRoom.mMainChannel.mLevelValue).setValueTakeOverModeJump() + page.makeValueBinding(surfaceElements.channelControls[0].mute_button.mSurfaceValue, controlRoom.mMainChannel.mMuteValue).setTypeToggle() + page.makeValueBinding(surfaceElements.channelControls[0].sel_button.mSurfaceValue, controlRoom.mMainChannel.mMetronomeClickActiveValue).setTypeToggle() + // Phones[0] + page.makeValueBinding(surfaceElements.channelControls[1].fader.mSurfaceValue, controlRoom.getPhonesChannelByIndex(0).mLevelValue).setValueTakeOverModeJump() + page.makeValueBinding(surfaceElements.channelControls[1].mute_button.mSurfaceValue, controlRoom.getPhonesChannelByIndex(0).mMuteValue).setTypeToggle() + page.makeValueBinding(surfaceElements.channelControls[1].sel_button.mSurfaceValue, controlRoom.getPhonesChannelByIndex(0).mMetronomeClickActiveValue).setTypeToggle() + + var maxCueSends = controlRoom.getMaxCueChannels() < 8 ? controlRoom.getMaxCueChannels() : 8 + + for (var i = 0; i < maxCueSends; ++i) { + var cueSend = controlRoom.getCueChannelByIndex(i) + + var knobSurfaceValue = surfaceElements.channelControls[i].pushEncoder.mEncoderValue; + var knobPushValue = surfaceElements.channelControls[i].pushEncoder.mPushValue; + + page.makeValueBinding(knobSurfaceValue, cueSend.mLevelValue) + page.makeValueBinding(knobPushValue, cueSend.mMuteValue).setTypeToggle() + + } + + return page +} + var mixerPage = makePageMixer() var selectedTrackPage = makePageSelectedTrack() var channelStripPage = makePageChannelStrip() // WIP Add Control Room Page +var controlRoomPage = makePageControlRoom() // WIP Add MIDI CC Page and extra MIDI Port // Function to clear out the Channel State for the display titles/values @@ -504,3 +535,10 @@ channelStripPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDe midiOutput.sendMidi(activeDevice, [0x90, 28, 0]) }).bind({ midiOutput }) +controlRoomPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDevice) { + console.log('from script: Platform M+ page "ControlRoom" activated') + activeDevice.setState("activePage", "ControlRoom") + clearAllLeds(activeDevice, midiOutput) + clearChannelState(activeDevice) + console.log("finish cr onactivate") +}).bind({ midiOutput }) From 73813833f1a0630cc72cdc612cf1a154226570e6 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 18 Dec 2022 18:54:59 +1100 Subject: [PATCH 55/65] New MIDI CC page using multiple output ports (Windows loop midi required) --- icon/platformmplus/icon_elements.js | 30 +++++-- icon/platformmplus/icon_platformmplus.js | 108 +++++++++++++++++++++-- 2 files changed, 125 insertions(+), 13 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index cd6eaed..44e044c 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -43,7 +43,8 @@ function Helper_updateDisplay(/** @type {string} */idRow1, /** @type {string} */ } else { // Update display if it has changed if ((newRow1 !== prevRow1) || (newRow2 !== prevRow2) || (activeDisplayType !== displayType)) { - console.log("Rows Display update" + newRow1+"::"+newRow2) + // console.log("Rows Display update" + idRow1+"::"+idRow2) + // console.log("Rows Display update" + newRow1+"::"+newRow2) _sendDisplayData(1, newRow1, activeDevice, midiOutput) _sendDisplayData(0, newRow2, activeDevice, midiOutput) } @@ -234,12 +235,18 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf var channelIndex = channelControl.instance channelControl.fader.mSurfaceValue.mOnTitleChange = (function (activeDevice, objectTitle, valueTitle) { - console.log("Fader Title Change: " + channelIndex + "::" + objectTitle + ":" + valueTitle) + // console.log("Fader Title Change: " + channelIndex + "::" + objectTitle + ":" + valueTitle) var activePage = activeDevice.getState("activePage") var faderTitles = activeDevice.getState(activePage + ' - Fader - Title') var faderValueTitles = activeDevice.getState(activePage + ' - Fader - ValueTitles') switch (activePage) { + case "Midi": + // MIDI Page is special since it uses a separate midi port and completely separate display and MIDI routing setup + // This update of the display is simply to ensure that should this event be received (which it is during init for example) then + // the Midi display state values won't be overwritten as they are handed by the custom onValueChange call in the page + Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) + break; case "ChannelStrip": case "SelectedTrack": activeDevice.setState(activePage + ' - Fader - ValueTitles', setTextOfColumn(channelIndex, makeLabel(valueTitle, 6), faderValueTitles)) @@ -254,12 +261,19 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf }).bind({ midiOutput }) channelControl.fader.mSurfaceValue.mOnDisplayValueChange = (function (activeDevice, value, units) { - // console.log("Fader Display Value Change: " + value + ":" + units) var activePage = activeDevice.getState("activePage") var faderValues = activeDevice.getState(activePage + ' - Fader - Values') - activeDevice.setState(activePage + ' - Fader - Values', setTextOfColumn(channelIndex, makeLabel(value, 6), faderValues)) - Helper_updateDisplay('Row1', activePage + ' - Fader - Values', 'AltRow1', 'AltRow2', activeDevice, midiOutput) + // console.log("Fader Display Value Change: " + value + ":" + activePage) + + switch (activePage) { + case "Midi": + break; + default: + activeDevice.setState(activePage + ' - Fader - Values', setTextOfColumn(channelIndex, makeLabel(value, 6), faderValues)) + Helper_updateDisplay('Row1', activePage + ' - Fader - Values', 'AltRow1', 'AltRow2', activeDevice, midiOutput) + break; + } }).bind({ midiOutput, channelIndex }) @@ -271,6 +285,12 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf var panValueTitles = activeDevice.getState(activePage + ' - Pan - ValueTitles') switch (activePage) { + case "Midi": + // MIDI Page is special since it uses a separate midi port and completely separate display and MIDI routing setup + // This update of the display is simply to ensure that should this event be received (which it is during init for example) then + // the Midi display state values won't be overwritten as they are handed by the custom onValueChange call in the page + Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) + break; case "SelectedTrack": switch (activeSubPage) { case "SendsQC": diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 1581b6f..264450c 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -11,6 +11,10 @@ var makeTransport = iconElements.makeTransport var clearAllLeds = iconElements.clearAllLeds var Helper_updateDisplay = iconElements.Helper_updateDisplay +var helper = require('./helper') +var makeLabel = helper.display.makeLabel +var setTextOfColumn = helper.display.setTextOfColumn +var setTextOfLine = helper.display.setTextOfLine //----------------------------------------------------------------------------- // 1. DRIVER SETUP - create driver object, midi ports and detection information //----------------------------------------------------------------------------- @@ -22,8 +26,10 @@ var midiremote_api = require('midiremote_api_v1') var deviceDriver = midiremote_api.makeDeviceDriver('Icon', 'Platform Mplus', 'Big Fat Wombat') // create objects representing the hardware's MIDI ports -var midiInput = deviceDriver.mPorts.makeMidiInput() -var midiOutput = deviceDriver.mPorts.makeMidiOutput() +var midiInput = deviceDriver.mPorts.makeMidiInput('Platform M+') +var midiOutput = deviceDriver.mPorts.makeMidiOutput('Platform M+') +// var midiPageInput = deviceDriver.mPorts.makeMidiInput('Icon - CC - In') +var midiPageOutput = deviceDriver.mPorts.makeMidiOutput('Icon - CC - Out') deviceDriver.mOnActivate = function (activeDevice) { console.log('Icon Platform M+ Activated'); @@ -39,6 +45,10 @@ deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput) .expectInputNameContains('Platform M+') .expectOutputNameContains('Platform M+') +// deviceDriver.makeDetectionUnit().detectPortPair(midiPageInput, midiPageOutput) +// .expectInputNameEquals('Icon - CC - In') +// .expectOutputNameEquals('Icon - CC - Out') + var surface = deviceDriver.mSurface //----------------------------------------------------------------------------- @@ -67,10 +77,9 @@ function makeSurfaceElements() { // Track the selected track name surfaceElements.selectedTrack = surface.makeCustomValueVariable('selectedTrack'); surfaceElements.selectedTrack.mOnTitleChange = function (activeDevice, objectTitle, valueTitle) { - console.log('selectedTrack title change:' + objectTitle) + // console.log('selectedTrack title change:' + objectTitle) activeDevice.setState('selectedTrackName', objectTitle) } - return surfaceElements } @@ -410,7 +419,7 @@ function makePageSelectedTrack() { } function makePageChannelStrip() { - var page = makePageWithDefaults('Channelstrip') + var page = makePageWithDefaults('ChannelStrip') var strip = page.makeSubPageArea('Strip') var gatePage = makeSubPage(strip, 'Gate') @@ -479,12 +488,79 @@ function makePageControlRoom() { return page } +function makePageMidi() { + var page = makePageWithDefaults('Midi') + + function makeMidiCCBinding( /** @type {MR_FactoryMappingPage} */page, /** @type {string} */displayName, /** @type {number} */cc, /** @type {number} */fader) { + // ? I have no idea what page.mCustom.makeHostValueVariable actually does- all I know is I can make a value binding this way. I can't seem to be able to look it up + // ? or access it all once made. + page.makeValueBinding(surfaceElements.channelControls[fader].fader.mSurfaceValue, page.mCustom.makeHostValueVariable(displayName)).setValueTakeOverModeJump() + .mOnValueChange = function (activeDevice, mapping, value, value2) { + // console.log(displayName + ":" + mapping + "::" + value + "::" + value2) + var activePage = activeDevice.getState("activePage") + var faderValueTitles = activeDevice.getState(activePage + ' - Fader - ValueTitles') + var faderValues = activeDevice.getState(activePage + ' - Fader - Values') + + var ccValue = Math.ceil(value * 127) + var pitchBendValue = Math.ceil(value * 16383) + var value1 = pitchBendValue % 128 + var value2 = Math.floor(pitchBendValue / 128) + + // this is the value going back to the icon Fader + midiOutput.sendMidi(activeDevice, [0xE0 + fader, value1, value2]) + // this is the value going back to Cubendo + midiPageOutput.sendMidi(activeDevice, [0xB0, cc, ccValue]) + // and this updates the D2 Display + activeDevice.setState(activePage + ' - Fader - ValueTitles', setTextOfColumn(fader, makeLabel(displayName, 6), faderValueTitles)) + activeDevice.setState(activePage + ' - Fader - Values', setTextOfColumn(fader, makeLabel(ccValue.toString(), 6), faderValues)) + Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) + } + } + + makeMidiCCBinding(page, "CC1", 1, 0) + makeMidiCCBinding(page, "CC11", 11, 1) + + // In order to bind a fader so we can get it's value I'm using a dummy function. + // var dummy = page.makeSubPageArea('Dummy') + // This fader sends pitchbend + // page.makeActionBinding(surfaceElements.channelControls[0].fader.mSurfaceValue, dummy.mAction.mReset).mOnValueChange = function (activeDevice, mapping, value) { + // var faderNumber = 0 + // var valueInput = value + // var pitchBendValue = Math.ceil(valueInput * 16383) + // var value1 = pitchBendValue % 128 + // var value2 = Math.floor(pitchBendValue / 128) + // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(0, 1, 'PB')) + // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(faderNumber, 0, (valueInput * 4 - 2).toFixed(1))) + // midiOutput2.sendMidi(activeDevice, [0xE0, value1, value2]) + // } + + // // On release we want the pitchbend fader to jump back to the mid position, + // //but for some reason I can get it to work with sending the value. that's why I just added it on the page load + // // So here I'm just setting the display back to the "middle" value. + // page.makeActionBinding(surfaceElements.channelControls[0].fader_touch.mSurfaceValue, dummy.mAction.mReset).mOnValueChange = function (activeDevice, mapping, value) { + // if (value == 0) { + // var faderNumber = 0 + // var valueInput = 0.5 + // var pitchBendValue = Math.ceil(valueInput * 16383) + // var value1 = pitchBendValue % 128 + // var value2 = Math.floor(pitchBendValue / 128) + // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(faderNumber, 0, (valueInput * 4 - 2).toFixed(1))) + // midiOutput2.sendMidi(activeDevice, [0xE0, value1, value2]) + // } + // } + + // This sends CC1 feeding back the values to the Icon, in order for the fader to stay where you release it. Definitely not the best way, but at least one way. + + + return page +} + + var mixerPage = makePageMixer() var selectedTrackPage = makePageSelectedTrack() var channelStripPage = makePageChannelStrip() -// WIP Add Control Room Page var controlRoomPage = makePageControlRoom() -// WIP Add MIDI CC Page and extra MIDI Port +var midiPage = makePageMidi() // Function to clear out the Channel State for the display titles/values // the OnDisplayChange callback is not called if the Channel doesn't have an updated @@ -540,5 +616,21 @@ controlRoomPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDev activeDevice.setState("activePage", "ControlRoom") clearAllLeds(activeDevice, midiOutput) clearChannelState(activeDevice) - console.log("finish cr onactivate") }).bind({ midiOutput }) + +midiPage.mOnActivate = function (/** @type {MR_ActiveDevice} */activeDevice) { + console.log('from script: Platform M+ page "Midi" activated') + var activePage = "Midi" + activeDevice.setState("activePage", activePage) + clearAllLeds(activeDevice, midiOutput) + // clearChannelState(activeDevice) + // On load I'm setting the pitchbend fader to the center position. Whenever you release it it will jump back to this point + // midiOutput.sendMidi(activeDevice, [0xE0, 0, 64]) // to put pitchbend in center + // ! This init must match the CC bindings create in the makeMidiPage function - it's annoying and needs a refactor + // WIP Refactor me + var faderValueTitles = activeDevice.getState(activePage + ' - Fader - ValueTitles') + faderValueTitles = setTextOfColumn(0, makeLabel("CC1", 6), faderValueTitles) + faderValueTitles = setTextOfColumn(1, makeLabel("CC11", 6), faderValueTitles) + activeDevice.setState(activePage + ' - Fader - ValueTitles', setTextOfLine(faderValueTitles)) + Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) +} \ No newline at end of file From d6a895ccd85263b9ad48599d1c9e3ed86614ea99 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Tue, 20 Dec 2022 20:43:32 +1100 Subject: [PATCH 56/65] The AI Fader now provides feedback on what it is controlling and the value - few changes elsewhere to deal with quirks of midi remote --- icon/platformmplus/icon_elements.js | 75 +++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 10 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 44e044c..2b7dfa9 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -18,7 +18,13 @@ function _sendDisplayData(row, text, activeDevice, midiOutput) { } function Helper_updateDisplay(/** @type {string} */idRow1, /** @type {string} */idRow2, /** @type {string} */idAltRow1, /** @type {string} */idAltRow2,/** @type {MR_ActiveDevice} */activeDevice, /** @type {MR_DeviceMidiOutput} */midiOutput) { - // New values + // Display ids + activeDevice.setState('Display - idRow1', idRow1) + activeDevice.setState('Display - idRow2', idRow2) + activeDevice.setState('Display - idAltRow1', idAltRow1) + activeDevice.setState('Display - idAltRow2', idAltRow2) + + // New display values var newRow1 = activeDevice.getState(idRow1) var newRow2 = activeDevice.getState(idRow2) var newAltRow1 = activeDevice.getState(idAltRow1) @@ -266,13 +272,18 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf // console.log("Fader Display Value Change: " + value + ":" + activePage) - switch (activePage) { - case "Midi": - break; - default: - activeDevice.setState(activePage + ' - Fader - Values', setTextOfColumn(channelIndex, makeLabel(value, 6), faderValues)) - Helper_updateDisplay('Row1', activePage + ' - Fader - Values', 'AltRow1', 'AltRow2', activeDevice, midiOutput) - break; + // ? When adjusting the AI fader in Mixer mode there is no update to the other fader even if you adjust that fader with the AI control + // ? When adjusting the AI fader in SelectedChannel mode there IS an update to the other fader, so... + // ! Disable the update if the display in on MasterFader + if (activeDevice.getState('Display - idRow1') !== 'MasterFader - Title') { + switch (activePage) { + case "Midi": + break; + default: + activeDevice.setState(activePage + ' - Fader - Values', setTextOfColumn(channelIndex, makeLabel(value, 6), faderValues)) + Helper_updateDisplay(activeDevice.getState('Display - idRow1'), activePage + ' - Fader - Values', activeDevice.getState('Display - idAltRow1'), activeDevice.getState('Display - idAltRow2'), activeDevice, midiOutput) + break; + } } }).bind({ midiOutput, channelIndex }) @@ -326,7 +337,7 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf var panValues = activeDevice.getState(activePage + ' - Pan - Values') activeDevice.setState(activePage + ' - Pan - Values', setTextOfColumn(channelIndex, makeLabel(value, 6), panValues)) - Helper_updateDisplay('Row1', 'Row2', 'AltRow1', activePage + ' - Pan - Values', activeDevice, midiOutput) + Helper_updateDisplay(activeDevice.getState('Display - idRow1'), activeDevice.getState('Display - idRow2'), activeDevice.getState('Display - idAltRow1'), activePage + ' - Pan - Values', activeDevice, midiOutput) }).bind({ midiOutput, channelIndex }) @@ -363,6 +374,48 @@ function makeMasterControl(surface, midiInput, midiOutput, x, y, instance, surfa masterControl.fader = tf[0] masterControl.fader_touch = tf[1] + masterControl.fader.mSurfaceValue.mOnTitleChange = (function (activeDevice, objectTitle, valueTitle) { + // console.log("Fader Title Change: " + channelIndex + "::" + objectTitle + ":" + valueTitle) + var title = objectTitle ? objectTitle + ":" + valueTitle : "No AI Parameter under mouse" + activeDevice.setState('MasterFader - Title', title) + + }) + + masterControl.fader.mSurfaceValue.mOnDisplayValueChange = (function (activeDevice, value, units) { + + activeDevice.setState('MasterFader - Values', value + units) + // console.log("MasterFader Display Value Change: " + value + ":" + units) + // Check to see if we are in the correct display mode - otherwise don't display + // ! This isn't done via the touch value as the touch onProcessValueChange may be processed after the mOnDisplayValueChange + if (activeDevice.getState('Display - idRow1') === 'MasterFader - Title') { + Helper_updateDisplay('MasterFader - Title', 'MasterFader - Values', 'MasterFader - Title', 'MasterFader - Values', activeDevice, midiOutput) + } + }).bind({ midiOutput }) + + masterControl.fader_touch.mSurfaceValue.mOnProcessValueChange = (function (activeDevice, touched, value2) { + // console.log("masterFader Touch Change: " + touched + ":" + value2) + // value===-1 means touch released + if (value2 == -1) { + // Reset the display to previous values + Helper_updateDisplay(activeDevice.getState('MasterFader - stashRow1'), + activeDevice.getState('MasterFader - stashRow2'), + activeDevice.getState('MasterFader - stashAltRow1'), + activeDevice.getState('MasterFader - stashAltRow2'), + activeDevice, midiOutput) + } else { + // Stash previous display state + // console.log("masterFader stash: " + activeDevice.getState('Display - idAltRow1') + ":" + activeDevice.getState('Display - idAltRow2')) + activeDevice.setState('MasterFader - stashRow1', activeDevice.getState('Display - idRow1')) + activeDevice.setState('MasterFader - stashRow2', activeDevice.getState('Display - idRow2')) + activeDevice.setState('MasterFader - stashAltRow1', activeDevice.getState('Display - idAltRow1')) + activeDevice.setState('MasterFader - stashAltRow2', activeDevice.getState('Display - idAltRow2')) + Helper_updateDisplay('MasterFader - Title', 'MasterFader - Values', 'MasterFader - Title', 'MasterFader - Values', activeDevice, midiOutput) + } + }).bind({ midiOutput }) + + + + // Channel Buttons masterControl.mixer_button = makeLedButton(surface, midiInput, midiOutput, 84, fader_x + 3, fader_y + 6, 3, 3, false) masterControl.read_button = makeLedButton(surface, midiInput, midiOutput, 74, fader_x + 3, fader_y + 9, 3, 3, false) @@ -383,9 +436,11 @@ function makeMasterControl(surface, midiInput, midiOutput, x, y, instance, surfa else { midiOutput.sendMidi(activeDevice, [0x90, 84, 0]) } - Helper_updateDisplay('Row1', 'Row2', 'AltRow1', 'AltRow2', activeDevice, midiOutput) + Helper_updateDisplay(activeDevice.getState('Display - idRow1'), activeDevice.getState('Display - idRow2'), activeDevice.getState('Display - idAltRow1'), activeDevice.getState('Display - idAltRow2'), activeDevice, midiOutput) } } + + return masterControl } From 19cf08f945e9128e6bbbbd95646e1be95f43bf69 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 23 Jul 2023 10:13:30 +1000 Subject: [PATCH 57/65] Fix track names not updating bug introduced in Cubase 12.0.60+ - crazy need to duplicate a line --- icon/platformmplus/icon_platformmplus.js | 1 + 1 file changed, 1 insertion(+) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 264450c..eb4636d 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -288,6 +288,7 @@ function makePageMixer() { page.makeValueBinding(knobSurfaceValue, hostMixerBankChannel.mValue.mPan).setSubPage(subPageFaderVolume) page.makeValueBinding(knobPushValue, hostMixerBankChannel.mValue.mEditorOpen).setTypeToggle().setSubPage(subPageFaderVolume) page.makeValueBinding(faderSurfaceValue, hostMixerBankChannel.mValue.mVolume).setValueTakeOverModeJump().setSubPage(subPageFaderVolume) + page.makeValueBinding(faderSurfaceValue, hostMixerBankChannel.mValue.mVolume).setValueTakeOverModeJump().setSubPage(subPageFaderVolume) // ! Duplicate to overcome C12.0.60+ bug page.makeValueBinding(sel_buttonSurfaceValue, hostMixerBankChannel.mValue.mSelected).setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(mute_buttonSurfaceValue, hostMixerBankChannel.mValue.mMute).setTypeToggle().setSubPage(subPageButtonDefaultSet) page.makeValueBinding(solo_buttonSurfaceValue, hostMixerBankChannel.mValue.mSolo).setTypeToggle().setSubPage(subPageButtonDefaultSet) From 6c44186305c3a5fd97b5f338337aa8d748374142 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Thu, 7 Dec 2023 15:24:20 +1100 Subject: [PATCH 58/65] Fix FocussedQC not changine due to crazy Cubase 12.0.60 page Update to use fader Touch for Cubase 13.x --- icon/platformmplus/icon_elements.js | 20 ++++++---- icon/platformmplus/icon_platformmplus.js | 49 +++++------------------- 2 files changed, 22 insertions(+), 47 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 2b7dfa9..2e1b82f 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -161,10 +161,17 @@ function makeTouchFader(surface, midiInput, midiOutput, channel, x, y, w, h) { .setOutputPort(midiOutput) .bindToPitchBend(channel) - var fader_touch = surface.makeButton(x + 1, y - 1, 1, 1) - fader_touch.mSurfaceValue.mMidiBinding - .setInputPort(midiInput) - .bindToNote(0, 104 + channel) + // !!! Important !!! + // Test for the existing TouchState feature + // to make the script compatible with Cubase 12 as well + if(fader.mSurfaceValue.mTouchState) { + // create a custom value variable to bind agains the touch state midi message + var fader_touch = surface.makeCustomValueVariable('faderTouch'+channel.toString()) + fader_touch.mMidiBinding.setInputPort(midiInput).bindToNote(0, 104 + channel) + + // bind the custom value variable to the TouchState member. (new in API 1.1) + fader.mSurfaceValue.mTouchState.bindTo(fader_touch) + } return [fader, fader_touch] } @@ -392,7 +399,7 @@ function makeMasterControl(surface, midiInput, midiOutput, x, y, instance, surfa } }).bind({ midiOutput }) - masterControl.fader_touch.mSurfaceValue.mOnProcessValueChange = (function (activeDevice, touched, value2) { + masterControl.fader_touch.mOnProcessValueChange = (function (activeDevice, touched, value2) { // console.log("masterFader Touch Change: " + touched + ":" + value2) // value===-1 means touch released if (value2 == -1) { @@ -413,9 +420,6 @@ function makeMasterControl(surface, midiInput, midiOutput, x, y, instance, surfa } }).bind({ midiOutput }) - - - // Channel Buttons masterControl.mixer_button = makeLedButton(surface, midiInput, midiOutput, 84, fader_x + 3, fader_y + 6, 3, 3, false) masterControl.read_button = makeLedButton(surface, midiInput, midiOutput, 74, fader_x + 3, fader_y + 9, 3, 3, false) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index eb4636d..5206ffb 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -278,7 +278,7 @@ function makePageMixer() { var knobSurfaceValue = surfaceElements.channelControls[channelIndex].pushEncoder.mEncoderValue; var knobPushValue = surfaceElements.channelControls[channelIndex].pushEncoder.mPushValue; var faderSurfaceValue = surfaceElements.channelControls[channelIndex].fader.mSurfaceValue; - var faderTouchSurfaceValue = surfaceElements.channelControls[channelIndex].fader_touch.mSurfaceValue; + var faderTouchValue = surfaceElements.channelControls[channelIndex].fader_touch; var sel_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].sel_button.mSurfaceValue; var mute_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].mute_button.mSurfaceValue; var solo_buttonSurfaceValue = surfaceElements.channelControls[channelIndex].solo_button.mSurfaceValue; @@ -311,6 +311,7 @@ function makePageSelectedTrack() { // Custom variable for track the selectedTrack so we can get to it's name page.makeValueBinding(surfaceElements.selectedTrack, selectedTrackChannel.mValue.mVolume) + page.makeValueBinding(surfaceElements.selectedTrack, selectedTrackChannel.mValue.mVolume) // ! Duplicate to overcome C12.0.60+ bug /// SendsQC subPage // Sends on PushEncodes and mute button for pre/post // Focus QC on Faders @@ -320,9 +321,13 @@ function makePageSelectedTrack() { var knobPushValue = surfaceElements.channelControls[idx].pushEncoder.mPushValue; var faderSurfaceValue = surfaceElements.channelControls[idx].fader.mSurfaceValue; - page.makeValueBinding(knobSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mLevel).setSubPage(subPageSendsQC) - page.makeValueBinding(knobPushValue, selectedTrackChannel.mSends.getByIndex(idx).mOn).setTypeToggle().setSubPage(subPageSendsQC) - page.makeValueBinding(faderSurfaceValue, page.mHostAccess.mFocusedQuickControls.getByIndex(idx)).setValueTakeOverModeJump().setSubPage(subPageSendsQC) + var quickControlValue = page.mHostAccess.mFocusedQuickControls.getByIndex(idx) // ! Weird: If this isn't a var in the line below but a direct call then Cubase will not bind values correctly + var sends = selectedTrackChannel.mSends.getByIndex(idx) + + page.makeValueBinding(knobSurfaceValue, sends.mLevel).setSubPage(subPageSendsQC) + page.makeValueBinding(knobPushValue, sends.mOn).setTypeToggle().setSubPage(subPageSendsQC) + page.makeValueBinding(faderSurfaceValue, quickControlValue).setValueTakeOverModeJump().setSubPage(subPageSendsQC) + page.makeValueBinding(faderSurfaceValue, quickControlValue).setValueTakeOverModeJump().setSubPage(subPageSendsQC) // ! Duplicate to overcome C12.0.60+ bug page.makeValueBinding(surfaceElements.channelControls[idx].sel_button.mSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mOn).setTypeToggle().setSubPage(subPageSendsQC) page.makeValueBinding(surfaceElements.channelControls[idx].mute_button.mSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mPrePost).setTypeToggle().setSubPage(subPageSendsQC) @@ -521,38 +526,6 @@ function makePageMidi() { makeMidiCCBinding(page, "CC1", 1, 0) makeMidiCCBinding(page, "CC11", 11, 1) - // In order to bind a fader so we can get it's value I'm using a dummy function. - // var dummy = page.makeSubPageArea('Dummy') - // This fader sends pitchbend - // page.makeActionBinding(surfaceElements.channelControls[0].fader.mSurfaceValue, dummy.mAction.mReset).mOnValueChange = function (activeDevice, mapping, value) { - // var faderNumber = 0 - // var valueInput = value - // var pitchBendValue = Math.ceil(valueInput * 16383) - // var value1 = pitchBendValue % 128 - // var value2 = Math.floor(pitchBendValue / 128) - // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(0, 1, 'PB')) - // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(faderNumber, 0, (valueInput * 4 - 2).toFixed(1))) - // midiOutput2.sendMidi(activeDevice, [0xE0, value1, value2]) - // } - - // // On release we want the pitchbend fader to jump back to the mid position, - // //but for some reason I can get it to work with sending the value. that's why I just added it on the page load - // // So here I'm just setting the display back to the "middle" value. - // page.makeActionBinding(surfaceElements.channelControls[0].fader_touch.mSurfaceValue, dummy.mAction.mReset).mOnValueChange = function (activeDevice, mapping, value) { - // if (value == 0) { - // var faderNumber = 0 - // var valueInput = 0.5 - // var pitchBendValue = Math.ceil(valueInput * 16383) - // var value1 = pitchBendValue % 128 - // var value2 = Math.floor(pitchBendValue / 128) - // midiOutput.sendMidi(activeDevice, helper.sysex.displaySetTextOfColumn(faderNumber, 0, (valueInput * 4 - 2).toFixed(1))) - // midiOutput2.sendMidi(activeDevice, [0xE0, value1, value2]) - // } - // } - - // This sends CC1 feeding back the values to the Icon, in order for the fader to stay where you release it. Definitely not the best way, but at least one way. - - return page } @@ -569,6 +542,7 @@ var midiPage = makePageMidi() // in the state. By clearing state on the page activation it will update all that are changing. function clearChannelState(/** @type {MR_ActiveDevice} */activeDevice) { var activePage = activeDevice.getState("activePage") + // console.log('from script: clearChannelState'+activePage) activeDevice.setState(activePage + ' - Fader - Title', "") activeDevice.setState(activePage + ' - Fader - ValueTitles', "") @@ -624,9 +598,6 @@ midiPage.mOnActivate = function (/** @type {MR_ActiveDevice} */activeDevice) { var activePage = "Midi" activeDevice.setState("activePage", activePage) clearAllLeds(activeDevice, midiOutput) - // clearChannelState(activeDevice) - // On load I'm setting the pitchbend fader to the center position. Whenever you release it it will jump back to this point - // midiOutput.sendMidi(activeDevice, [0xE0, 0, 64]) // to put pitchbend in center // ! This init must match the CC bindings create in the makeMidiPage function - it's annoying and needs a refactor // WIP Refactor me var faderValueTitles = activeDevice.getState(activePage + ' - Fader - ValueTitles') From d5b8e33ae3aac0197b51dab307525bdeb956ea46 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Thu, 7 Dec 2023 16:12:30 +1100 Subject: [PATCH 59/65] More weird 12.0.60 driven coding to ensure displays update --- icon/platformmplus/icon_platformmplus.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 5206ffb..ea796b0 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -441,11 +441,19 @@ function makePageChannelStrip() { for (var idx = 0; idx < surfaceElements.numStrips; ++idx) { var faderSurfaceValue = surfaceElements.channelControls[idx].fader.mSurfaceValue; - page.makeValueBinding(faderSurfaceValue, stripEffects.mGate.mParameterBankZone.makeParameterValue()).setSubPage(gatePage) - page.makeValueBinding(faderSurfaceValue, stripEffects.mCompressor.mParameterBankZone.makeParameterValue()).setSubPage(compressorPage) - page.makeValueBinding(faderSurfaceValue, stripEffects.mTools.mParameterBankZone.makeParameterValue()).setSubPage(toolsPage) - page.makeValueBinding(faderSurfaceValue, stripEffects.mSaturator.mParameterBankZone.makeParameterValue()).setSubPage(saturatorPage) - page.makeValueBinding(faderSurfaceValue, stripEffects.mLimiter.mParameterBankZone.makeParameterValue()).setSubPage(limiterPage) + var gate = stripEffects.mGate.mParameterBankZone.makeParameterValue() + var compressor = stripEffects.mCompressor.mParameterBankZone.makeParameterValue() + var tools = stripEffects.mTools.mParameterBankZone.makeParameterValue() + var saturator = stripEffects.mSaturator.mParameterBankZone.makeParameterValue() + var limiter = stripEffects.mLimiter.mParameterBankZone.makeParameterValue() + + for (var i = 0; i < 2; i++) { // ! Workaround for Cubase 12.0.60+ bug + page.makeValueBinding(faderSurfaceValue, gate).setSubPage(gatePage) + page.makeValueBinding(faderSurfaceValue, compressor).setSubPage(compressorPage) + page.makeValueBinding(faderSurfaceValue, tools).setSubPage(toolsPage) + page.makeValueBinding(faderSurfaceValue, saturator).setSubPage(saturatorPage) + page.makeValueBinding(faderSurfaceValue, limiter).setSubPage(limiterPage) + } } for (var idx = 0; idx < 5; ++idx) { From d3accad193c8d14515c384d23be90c68398f963d Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Thu, 7 Dec 2023 16:17:10 +1100 Subject: [PATCH 60/65] Fix error in ChannelStrip page activation --- icon/platformmplus/icon_platformmplus.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index ea796b0..2d9af3b 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -459,8 +459,10 @@ function makePageChannelStrip() { for (var idx = 0; idx < 5; ++idx) { var faderStrip = surfaceElements.channelControls[idx] var type = ['mGate', 'mCompressor', 'mTools', 'mSaturator', 'mLimiter'][idx] - page.makeValueBinding(faderStrip.rec_button.mSurfaceValue, stripEffects[type].mOn).setTypeToggle() - page.makeValueBinding(faderStrip.mute_button.mSurfaceValue, stripEffects[type].mBypass).setTypeToggle() + for (var i = 0; i < 2; i++) { // ! Workaround for Cubase 12.0.60+ bug + page.makeValueBinding(faderStrip.rec_button.mSurfaceValue, stripEffects[type].mOn).setTypeToggle() + page.makeValueBinding(faderStrip.mute_button.mSurfaceValue, stripEffects[type].mBypass).setTypeToggle() + } } page.makeActionBinding(surfaceElements.channelControls[0].sel_button.mSurfaceValue, gatePage.mAction.mActivate) @@ -584,9 +586,9 @@ selectedTrackPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeD channelStripPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDevice) { console.log('from script: Platform M+ page "Channel Strip" activated') activeDevice.setState("activePage", "ChannelStrip") + activeDevice.setState("activeSubPage", "Gate") clearAllLeds(activeDevice, midiOutput) clearChannelState(activeDevice) - activeDevice.setState("activeSubPage", "Gate") midiOutput.sendMidi(activeDevice, [0x90, 24, 127]) midiOutput.sendMidi(activeDevice, [0x90, 25, 0]) midiOutput.sendMidi(activeDevice, [0x90, 26, 0]) From 86b09ff57d747efeb278e8b2fae68f0cd75e4fb2 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Fri, 8 Dec 2023 10:58:52 +1100 Subject: [PATCH 61/65] Quiet the logs --- icon/platformmplus/icon_elements.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index 2e1b82f..db6515c 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -116,7 +116,7 @@ function makeLedButton(surface, midiInput, midiOutput, note, x, y, w, h, circle) } function clearAllLeds(/** @type {MR_ActiveDevice} */activeDevice, /** @type {MR_DeviceMidiOutput} */midiOutput) { - console.log('Clear All Leds') + // console.log('Clear All Leds') // Mixer buttons for (var i = 0; i < 8; ++i) { midiOutput.sendMidi(activeDevice, [0x90, 24 + i, 0]) From fdbb942fc4b0d615f15dba12f00737b38ea44f55 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Fri, 8 Dec 2023 11:02:45 +1100 Subject: [PATCH 62/65] Tweaks to display handling for QCs - still seeing random incorrect updated. Probably need to rethink the display handling, it is to messy to see what the issues are. --- icon/platformmplus/icon_platformmplus.js | 55 +++++++++++++++++++++--- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 2d9af3b..156eafa 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -34,6 +34,7 @@ var midiPageOutput = deviceDriver.mPorts.makeMidiOutput('Icon - CC - Out') deviceDriver.mOnActivate = function (activeDevice) { console.log('Icon Platform M+ Activated'); clearAllLeds(activeDevice, midiOutput) + activeDevice.setState('lastTime', Date.now().toString()) } // define all possible namings the devices MIDI ports could have @@ -95,7 +96,7 @@ function makeSubPage(subPageArea, name) { var subPage = subPageArea.makeSubPage(name) var msgText = 'sub page ' + name + ' activated' subPage.mOnActivate = (function (/** @type {MR_ActiveDevice} **/activeDevice) { - console.log(msgText) + // console.log(msgText) activeDevice.setState("activeSubPage", name) var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, ] @@ -331,6 +332,33 @@ function makePageSelectedTrack() { page.makeValueBinding(surfaceElements.channelControls[idx].sel_button.mSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mOn).setTypeToggle().setSubPage(subPageSendsQC) page.makeValueBinding(surfaceElements.channelControls[idx].mute_button.mSurfaceValue, selectedTrackChannel.mSends.getByIndex(idx).mPrePost).setTypeToggle().setSubPage(subPageSendsQC) + + // The use of bind below assures the idx is the correct value for the onTitleChange function + const qcOnTitleChange = { + idx: idx, + onTitleChange: function(activeDevice,activeMapping,objectTitle, valueTitle) { + var activePage = activeDevice.getState("activePage") + var activeSubPage = activeDevice.getState("activeSubPage") + var faderValueTitles = activeDevice.getState(activePage + ' - Fader - ValueTitles') + // console.log("QC Title Changed:" +this.idx+":" + objectTitle + ":" + valueTitle) + switch (activePage) { + case "SelectedTrack": + switch (activeSubPage) { + case "SendsQC": + var title = valueTitle + if (title.length === 0) { + title = "None" + } + activeDevice.setState(activePage + ' - Fader - ValueTitles', setTextOfColumn(this.idx, makeLabel(title, 6), faderValueTitles)) + Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) + break; + } + break; + } + } + } + quickControlValue.mOnTitleChange = qcOnTitleChange.onTitleChange.bind(qcOnTitleChange) + } // Handy controls for easy access @@ -471,6 +499,19 @@ function makePageChannelStrip() { page.makeActionBinding(surfaceElements.channelControls[3].sel_button.mSurfaceValue, saturatorPage.mAction.mActivate) page.makeActionBinding(surfaceElements.channelControls[4].sel_button.mSurfaceValue, limiterPage.mAction.mActivate) +// page.mOnIdle = function(activeDevice, activeMapping) { +// var now = Date.now() +// var lastTime = Number(activeDevice.getState('lastTime')) +// if ((now-lastTime) >= 5000) { +// activeDevice.setState('lastTime', now.toString()) +// console.log('PAGE Default ON IDLE A') +// } else { +// // WIP Okay so need to decide what to do here. +// // WIP And what about making MIXER a SHIFT key? +// } +// // Your custom idle-time tasks here +// } + return page } @@ -564,19 +605,19 @@ function clearChannelState(/** @type {MR_ActiveDevice} */activeDevice) { activeDevice.setState("displayType", "Fader") } mixerPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDevice) { - console.log('from script: Platform M+ page "Mixer" activated') + // console.log('from script: Platform M+ page "Mixer" activated') activeDevice.setState("activePage", "Mixer") clearAllLeds(activeDevice, midiOutput) clearChannelState(activeDevice) }).bind({ midiOutput }) selectedTrackPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDevice) { - console.log('from script: Platform M+ page "Selected Track" activated') + // console.log('from script: Platform M+ page "Selected Track" activated') activeDevice.setState("activePage", "SelectedTrack") + activeDevice.setState("activeSubPage", "SendsQC") clearAllLeds(activeDevice, midiOutput) clearChannelState(activeDevice) // Set the Rec leds which correspond to the different subages to their starting state - activeDevice.setState("activeSubPage", "SendsQC") midiOutput.sendMidi(activeDevice, [0x90, 0, 127]) midiOutput.sendMidi(activeDevice, [0x90, 1, 0]) midiOutput.sendMidi(activeDevice, [0x90, 2, 0]) @@ -584,7 +625,7 @@ selectedTrackPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeD }).bind({ midiOutput }) channelStripPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDevice) { - console.log('from script: Platform M+ page "Channel Strip" activated') + // console.log('from script: Platform M+ page "Channel Strip" activated') activeDevice.setState("activePage", "ChannelStrip") activeDevice.setState("activeSubPage", "Gate") clearAllLeds(activeDevice, midiOutput) @@ -597,14 +638,14 @@ channelStripPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDe }).bind({ midiOutput }) controlRoomPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDevice) { - console.log('from script: Platform M+ page "ControlRoom" activated') + // console.log('from script: Platform M+ page "ControlRoom" activated') activeDevice.setState("activePage", "ControlRoom") clearAllLeds(activeDevice, midiOutput) clearChannelState(activeDevice) }).bind({ midiOutput }) midiPage.mOnActivate = function (/** @type {MR_ActiveDevice} */activeDevice) { - console.log('from script: Platform M+ page "Midi" activated') + // console.log('from script: Platform M+ page "Midi" activated') var activePage = "Midi" activeDevice.setState("activePage", activePage) clearAllLeds(activeDevice, midiOutput) From 785fab2938653cf495b5673f7ce9b6bccf9b7b54 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Fri, 8 Dec 2023 11:24:41 +1100 Subject: [PATCH 63/65] This appears to fix the autodetection --- icon/platformmplus/icon_platformmplus.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 156eafa..aa46f97 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -28,8 +28,8 @@ var deviceDriver = midiremote_api.makeDeviceDriver('Icon', 'Platform Mplus', 'Bi // create objects representing the hardware's MIDI ports var midiInput = deviceDriver.mPorts.makeMidiInput('Platform M+') var midiOutput = deviceDriver.mPorts.makeMidiOutput('Platform M+') -// var midiPageInput = deviceDriver.mPorts.makeMidiInput('Icon - CC - In') -var midiPageOutput = deviceDriver.mPorts.makeMidiOutput('Icon - CC - Out') +var midiPageInput = deviceDriver.mPorts.makeMidiInput('Icon CC') +var midiPageOutput = deviceDriver.mPorts.makeMidiOutput('Icon CC') deviceDriver.mOnActivate = function (activeDevice) { console.log('Icon Platform M+ Activated'); @@ -46,9 +46,8 @@ deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput) .expectInputNameContains('Platform M+') .expectOutputNameContains('Platform M+') -// deviceDriver.makeDetectionUnit().detectPortPair(midiPageInput, midiPageOutput) -// .expectInputNameEquals('Icon - CC - In') -// .expectOutputNameEquals('Icon - CC - Out') +deviceDriver.makeDetectionUnit().detectPortPair(midiPageInput, midiPageOutput) + .expectOutputNameEquals('Icon CC') var surface = deviceDriver.mSurface From fdb253f9b1ba44ea06ecda4c74e0a1e040a06b20 Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sat, 9 Dec 2023 16:25:32 +1100 Subject: [PATCH 64/65] Display fixes - still a few gremlins. Tried some new things for understanding. --- icon/platformmplus/icon_elements.js | 104 ++++----- icon/platformmplus/icon_platformmplus.js | 263 +++++++++++++---------- 2 files changed, 198 insertions(+), 169 deletions(-) diff --git a/icon/platformmplus/icon_elements.js b/icon/platformmplus/icon_elements.js index db6515c..bf7b3dc 100644 --- a/icon/platformmplus/icon_elements.js +++ b/icon/platformmplus/icon_elements.js @@ -18,18 +18,19 @@ function _sendDisplayData(row, text, activeDevice, midiOutput) { } function Helper_updateDisplay(/** @type {string} */idRow1, /** @type {string} */idRow2, /** @type {string} */idAltRow1, /** @type {string} */idAltRow2,/** @type {MR_ActiveDevice} */activeDevice, /** @type {MR_DeviceMidiOutput} */midiOutput) { + // console.log("Helper Update Display") // Display ids activeDevice.setState('Display - idRow1', idRow1) activeDevice.setState('Display - idRow2', idRow2) activeDevice.setState('Display - idAltRow1', idAltRow1) activeDevice.setState('Display - idAltRow2', idAltRow2) - + // console.log("Display ids update: " + idRow1+"::"+idRow2) + // console.log("Display ids update: " + idAltRow1+"::"+idAltRow2) // New display values var newRow1 = activeDevice.getState(idRow1) var newRow2 = activeDevice.getState(idRow2) var newAltRow1 = activeDevice.getState(idAltRow1) var newAltRow2 = activeDevice.getState(idAltRow2) - // console.log("Helper Update Display...") // Previous values var prevRow1 = activeDevice.getState('Row1') var prevRow2 = activeDevice.getState('Row2') @@ -42,15 +43,16 @@ function Helper_updateDisplay(/** @type {string} */idRow1, /** @type {string} */ if (displayType === "Pan") { // Update display if it has changed if ((newAltRow1 !== prevAltRow1) || (newAltRow2 !== prevAltRow2) || (activeDisplayType !== displayType)) { - // console.log("AltRows Display update: " + newAltRow1+"::"+newAltRow2) + // console.log("AltRows Display prev: " + prevAltRow1+"::"+prevAltRow2) + // console.log("AltRows Display new: " + newAltRow1+"::"+newAltRow2) _sendDisplayData(1, newAltRow1, activeDevice, midiOutput) _sendDisplayData(0, newAltRow2, activeDevice, midiOutput) } } else { // Update display if it has changed if ((newRow1 !== prevRow1) || (newRow2 !== prevRow2) || (activeDisplayType !== displayType)) { - // console.log("Rows Display update" + idRow1+"::"+idRow2) - // console.log("Rows Display update" + newRow1+"::"+newRow2) + // console.log("Rows Display prev" + prevRow1+"::"+prevRow2) + // console.log("Rows Display new" + newRow1+"::"+newRow2) _sendDisplayData(1, newRow1, activeDevice, midiOutput) _sendDisplayData(0, newRow2, activeDevice, midiOutput) } @@ -100,17 +102,15 @@ function Helper_updateDisplay(/** @type {string} */idRow1, /** @type {string} */ */ function makeLedButton(surface, midiInput, midiOutput, note, x, y, w, h, circle) { var button = surface.makeButton(x, y, w, h) - button.mSurfaceValue.mMidiBinding.setInputPort(midiInput).bindToNote(0, note) + button.mSurfaceValue.mMidiBinding.setIsConsuming(true).setInputPort(midiInput).bindToNote(0, note) if (circle) { button.setShapeCircle() } button.mSurfaceValue.mOnProcessValueChange = (function (/** @type {MR_ActiveDevice} */activeDevice) { // console.log("LedButton ProcessValue Change:"+button.mSurfaceValue.getProcessValue(activeDevice)) - if (button.mSurfaceValue.getProcessValue(activeDevice) > 0) - this.midiOutput.sendMidi(activeDevice, [0x90, note, 127]) - else { - this.midiOutput.sendMidi(activeDevice, [0x90, note, 0]) - } + var value = button.mSurfaceValue.getProcessValue(activeDevice) + this.midiOutput.sendMidi(activeDevice, [0x90, note, value]) + }).bind({ midiOutput }) return button } @@ -190,7 +190,7 @@ function repeatCommand(activeDevice, command, repeats) { function bindCommandKnob(pushEncoder, commandIncrease, commandDecrease) { // console.log('from script: createCommandKnob') pushEncoder.mOnProcessValueChange = function (activeDevice, value) { - console.log('value changed: ' + value) + // console.log('value changed: ' + value) if (value < 0.5) { var jump_rate = Math.floor(value * 127) repeatCommand(activeDevice, commandIncrease, jump_rate) @@ -248,34 +248,36 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf var channelIndex = channelControl.instance channelControl.fader.mSurfaceValue.mOnTitleChange = (function (activeDevice, objectTitle, valueTitle) { - // console.log("Fader Title Change: " + channelIndex + "::" + objectTitle + ":" + valueTitle) + // console.log("Fader Title Change: " + this.channelIndex + "::" + objectTitle + ":" + valueTitle) var activePage = activeDevice.getState("activePage") - var faderTitles = activeDevice.getState(activePage + ' - Fader - Title') - var faderValueTitles = activeDevice.getState(activePage + ' - Fader - ValueTitles') - + var activeSubPage = activeDevice.getState("activeSubPage") + var faderTitles = activeDevice.getState(activePage + "- " + activeSubPage + ' - Fader - Title') + var faderValueTitles = activeDevice.getState(activePage + "- " + activeSubPage + ' - Fader - ValueTitles') + // console.log("Fader Title Change Page: " + activePage + "::" + activeSubPage) switch (activePage) { case "Midi": // MIDI Page is special since it uses a separate midi port and completely separate display and MIDI routing setup // This update of the display is simply to ensure that should this event be received (which it is during init for example) then // the Midi display state values won't be overwritten as they are handed by the custom onValueChange call in the page - Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) + Helper_updateDisplay(activePage + "- " + activeSubPage + ' - Fader - ValueTitles', activePage + "- " + activeSubPage + ' - Fader - Values', activePage + "- " + activeSubPage + ' - Pan - ValueTitles', activePage + "- " + activeSubPage + ' - Pan - Values', activeDevice, this.midiOutput) break; case "ChannelStrip": case "SelectedTrack": - activeDevice.setState(activePage + ' - Fader - ValueTitles', setTextOfColumn(channelIndex, makeLabel(valueTitle, 6), faderValueTitles)) - Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) + activeDevice.setState(activePage + "- " + activeSubPage + ' - Fader - ValueTitles', setTextOfColumn(this.channelIndex, makeLabel(valueTitle, 6), faderValueTitles)) + Helper_updateDisplay(activePage + "- " + activeSubPage + ' - Fader - ValueTitles', activePage + "- " + activeSubPage + ' - Fader - Values', activePage + "- " + activeSubPage + ' - Pan - ValueTitles', activePage + "- " + activeSubPage + ' - Pan - Values', activeDevice, this.midiOutput) break; default: - activeDevice.setState(activePage + ' - Fader - Title', setTextOfColumn(channelIndex, makeLabel(objectTitle, 6), faderTitles)) - activeDevice.setState(activePage + ' - Fader - ValueTitles', setTextOfColumn(channelIndex, makeLabel(valueTitle, 6), faderValueTitles)) - Helper_updateDisplay(activePage + ' - Fader - Title', activePage + ' - Fader - Values', activePage + ' - Pan - Title', activePage + ' - Pan - Values', activeDevice, midiOutput) + activeDevice.setState(activePage + "- " + activeSubPage + ' - Fader - Title', setTextOfColumn(this.channelIndex, makeLabel(objectTitle, 6), faderTitles)) + activeDevice.setState(activePage + "- " + activeSubPage + ' - Fader - ValueTitles', setTextOfColumn(this.channelIndex, makeLabel(valueTitle, 6), faderValueTitles)) + Helper_updateDisplay(activePage + "- " + activeSubPage + ' - Fader - Title', activePage + "- " + activeSubPage + ' - Fader - Values', activePage + "- " + activeSubPage + ' - Pan - Title', activePage + "- " + activeSubPage + ' - Pan - Values', activeDevice, this.midiOutput) break; } - }).bind({ midiOutput }) + }).bind({ channelIndex, midiOutput }) channelControl.fader.mSurfaceValue.mOnDisplayValueChange = (function (activeDevice, value, units) { var activePage = activeDevice.getState("activePage") - var faderValues = activeDevice.getState(activePage + ' - Fader - Values') + var activeSubPage = activeDevice.getState("activeSubPage") + var faderValues = activeDevice.getState(activePage + "- " + activeSubPage + ' - Fader - Values') // console.log("Fader Display Value Change: " + value + ":" + activePage) @@ -287,8 +289,8 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf case "Midi": break; default: - activeDevice.setState(activePage + ' - Fader - Values', setTextOfColumn(channelIndex, makeLabel(value, 6), faderValues)) - Helper_updateDisplay(activeDevice.getState('Display - idRow1'), activePage + ' - Fader - Values', activeDevice.getState('Display - idAltRow1'), activeDevice.getState('Display - idAltRow2'), activeDevice, midiOutput) + activeDevice.setState(activePage + "- " + activeSubPage + ' - Fader - Values', setTextOfColumn(channelIndex, makeLabel(value, 6), faderValues)) + Helper_updateDisplay(activeDevice.getState('Display - idRow1'), activePage + "- " + activeSubPage + ' - Fader - Values', activeDevice.getState('Display - idAltRow1'), activeDevice.getState('Display - idAltRow2'), activeDevice, midiOutput) break; } } @@ -299,16 +301,17 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf // console.log("Pan Title Changed:" + objectTitle + ":" + valueTitle) var activePage = activeDevice.getState("activePage") var activeSubPage = activeDevice.getState("activeSubPage") - var panTitles = activeDevice.getState(activePage + ' - Pan - Title') - var panValueTitles = activeDevice.getState(activePage + ' - Pan - ValueTitles') - + var panTitles = activeDevice.getState(activePage + "- " + activeSubPage + ' - Pan - Title') + var panValueTitles = activeDevice.getState(activePage + "- " + activeSubPage + ' - Pan - ValueTitles') + // WIP This switch logic needs refactoring - it is repeated (and thus error prone) for pushEncoder and fader mOnTileChange switch (activePage) { case "Midi": // MIDI Page is special since it uses a separate midi port and completely separate display and MIDI routing setup // This update of the display is simply to ensure that should this event be received (which it is during init for example) then // the Midi display state values won't be overwritten as they are handed by the custom onValueChange call in the page - Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) + Helper_updateDisplay(activePage + "- " + activeSubPage + ' - Fader - ValueTitles', activePage + "- " + activeSubPage + ' - Fader - Values', activePage + "- " + activeSubPage + ' - Pan - ValueTitles', activePage + "- " + activeSubPage + ' - Pan - Values', activeDevice, midiOutput) break; + case "ChannelStrip": case "SelectedTrack": switch (activeSubPage) { case "SendsQC": @@ -316,23 +319,23 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf if (title.length === 0) { title = "None" } - activeDevice.setState(activePage + ' - Pan - ValueTitles', setTextOfColumn(channelIndex, makeLabel(title, 6), panValueTitles)) - Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) + activeDevice.setState(activePage + "- " + activeSubPage + ' - Pan - ValueTitles', setTextOfColumn(channelIndex, makeLabel(title, 6), panValueTitles)) + Helper_updateDisplay(activePage + "- " + activeSubPage + ' - Fader - ValueTitles', activePage + "- " + activeSubPage + ' - Fader - Values', activePage + "- " + activeSubPage + ' - Pan - ValueTitles', activePage + "- " + activeSubPage + ' - Pan - Values', activeDevice, midiOutput) break; default: var title = valueTitle if (title.length === 0) { title = "None" } - activeDevice.setState(activePage + ' - Pan - ValueTitles', setTextOfColumn(channelIndex, makeLabel(title, 6), panValueTitles)) - Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) + activeDevice.setState(activePage + "- " + activeSubPage + ' - Pan - ValueTitles', setTextOfColumn(channelIndex, makeLabel(title, 6), panValueTitles)) + Helper_updateDisplay(activePage + "- " + activeSubPage + ' - Fader - ValueTitles', activePage + "- " + activeSubPage + ' - Fader - Values', activePage + "- " + activeSubPage + ' - Pan - ValueTitles', activePage + "- " + activeSubPage + ' - Pan - Values', activeDevice, midiOutput) break; } break; default: - activeDevice.setState(activePage + ' - Pan - Title', setTextOfColumn(channelIndex, makeLabel(objectTitle, 6), panTitles)) - activeDevice.setState(activePage + ' - Pan - ValueTitles', setTextOfColumn(channelIndex, makeLabel(valueTitle, 6), panValueTitles)) - Helper_updateDisplay(activePage + ' - Fader - Title', activePage + ' - Fader - Values', activePage + ' - Pan - Title', activePage + ' - Pan - Values', activeDevice, midiOutput) + activeDevice.setState(activePage + "- " + activeSubPage + ' - Pan - Title', setTextOfColumn(channelIndex, makeLabel(objectTitle, 6), panTitles)) + activeDevice.setState(activePage + "- " + activeSubPage + ' - Pan - ValueTitles', setTextOfColumn(channelIndex, makeLabel(valueTitle, 6), panValueTitles)) + Helper_updateDisplay(activePage + "- " + activeSubPage + ' - Fader - Title', activePage + "- " + activeSubPage + ' - Fader - Values', activePage + "- " + activeSubPage + ' - Pan - Title', activePage + "- " + activeSubPage + ' - Pan - Values', activeDevice, midiOutput) break; } @@ -341,10 +344,11 @@ function makeChannelControl(surface, midiInput, midiOutput, x, y, instance, surf channelControl.pushEncoder.mEncoderValue.mOnDisplayValueChange = (function (activeDevice, value, units) { // console.log("Pan Value Change: " + value + ":" + units) var activePage = activeDevice.getState("activePage") - var panValues = activeDevice.getState(activePage + ' - Pan - Values') + var activeSubPage = activeDevice.getState("activeSubPage") + var panValues = activeDevice.getState(activePage + "- " + activeSubPage + ' - Pan - Values') - activeDevice.setState(activePage + ' - Pan - Values', setTextOfColumn(channelIndex, makeLabel(value, 6), panValues)) - Helper_updateDisplay(activeDevice.getState('Display - idRow1'), activeDevice.getState('Display - idRow2'), activeDevice.getState('Display - idAltRow1'), activePage + ' - Pan - Values', activeDevice, midiOutput) + activeDevice.setState(activePage + "- " + activeSubPage + ' - Pan - Values', setTextOfColumn(channelIndex, makeLabel(value, 6), panValues)) + Helper_updateDisplay(activeDevice.getState('Display - idRow1'), activeDevice.getState('Display - idRow2'), activeDevice.getState('Display - idAltRow1'), activePage + "- " + activeSubPage + ' - Pan - Values', activeDevice, midiOutput) }).bind({ midiOutput, channelIndex }) @@ -424,26 +428,6 @@ function makeMasterControl(surface, midiInput, midiOutput, x, y, instance, surfa masterControl.mixer_button = makeLedButton(surface, midiInput, midiOutput, 84, fader_x + 3, fader_y + 6, 3, 3, false) masterControl.read_button = makeLedButton(surface, midiInput, midiOutput, 74, fader_x + 3, fader_y + 9, 3, 3, false) masterControl.write_button = makeLedButton(surface, midiInput, midiOutput, 75, fader_x + 3, fader_y + 12, 3, 3, false) - masterControl.mixer_button.mSurfaceValue.mOnProcessValueChange = function (activeDevice) { - var value = masterControl.mixer_button.mSurfaceValue.getProcessValue(activeDevice) - if (value == 1) { - var displayType = activeDevice.getState("displayType") - if (displayType === "Fader") { - displayType = "Pan" - } else { - displayType = "Fader" - } - activeDevice.setState("displayType", displayType) - - if (displayType === "Pan") - midiOutput.sendMidi(activeDevice, [0x90, 84, 127]) - else { - midiOutput.sendMidi(activeDevice, [0x90, 84, 0]) - } - Helper_updateDisplay(activeDevice.getState('Display - idRow1'), activeDevice.getState('Display - idRow2'), activeDevice.getState('Display - idAltRow1'), activeDevice.getState('Display - idAltRow2'), activeDevice, midiOutput) - } - } - return masterControl } diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index aa46f97..8ad8048 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -96,102 +96,124 @@ function makeSubPage(subPageArea, name) { var msgText = 'sub page ' + name + ' activated' subPage.mOnActivate = (function (/** @type {MR_ActiveDevice} **/activeDevice) { // console.log(msgText) - activeDevice.setState("activeSubPage", name) - var data = [0xf0, 0x00, 0x00, 0x66, 0x14, 0x12, - ] - switch (name) { - case "Scrub": - activeDevice.setState("indicator2", "S") - break; - case "Nudge": - activeDevice.setState("indicator2", "N") - break; - case "Nav": - activeDevice.setState("indicator1", "N") - break; - case "Zoom": - activeDevice.setState("indicator1", "Z") - break; - case "SendsQC": - // An action binding cannot be set to ta Toggle type button so manually adjust the rec button lights - // based on the subpage selection. - midiOutput.sendMidi(activeDevice, [0x90, 0, 127]) - midiOutput.sendMidi(activeDevice, [0x90, 1, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 2, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 3, 0]) - break; - case "EQ": - // An action binding cannot be set to ta Toggle type button so manually adjust the rec button lights - // based on the subpage selection. - midiOutput.sendMidi(activeDevice, [0x90, 0, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 1, 127]) - midiOutput.sendMidi(activeDevice, [0x90, 2, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 3, 0]) - break; - case "PreFilter": - // An action binding cannot be set to ta Toggle type button so manually adjust the rec button lights - // based on the subpage selection. - midiOutput.sendMidi(activeDevice, [0x90, 0, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 1, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 2, 127]) - midiOutput.sendMidi(activeDevice, [0x90, 3, 0]) - break; - case "CueSends": - // An action binding cannot be set to ta Toggle type button so manually adjust the rec button lights - // based on the subpage selection. - midiOutput.sendMidi(activeDevice, [0x90, 0, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 1, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 2, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 3, 127]) - break; - case "Gate": - // An action binding cannot be set to ta Toggle type button so manually adjust the sel button lights - // based on the subpage selection. - midiOutput.sendMidi(activeDevice, [0x90, 24, 127]) - midiOutput.sendMidi(activeDevice, [0x90, 25, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 26, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 27, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 28, 0]) - break; - case "Compressor": - // An action binding cannot be set to ta Toggle type button so manually adjust the sel button lights - // based on the subpage selection. - midiOutput.sendMidi(activeDevice, [0x90, 24, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 25, 127]) - midiOutput.sendMidi(activeDevice, [0x90, 26, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 27, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 28, 0]) - break; - case "Tools": - // An action binding cannot be set to ta Toggle type button so manually adjust the sel button lights - // based on the subpage selection. - midiOutput.sendMidi(activeDevice, [0x90, 24, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 25, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 26, 127]) - midiOutput.sendMidi(activeDevice, [0x90, 27, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 28, 0]) - break; - case "Saturator": - // An action binding cannot be set to ta Toggle type button so manually adjust the sel button lights - // based on the subpage selection. - midiOutput.sendMidi(activeDevice, [0x90, 24, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 25, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 26, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 27, 127]) - midiOutput.sendMidi(activeDevice, [0x90, 28, 0]) + var activePage = activeDevice.getState("activePage") + var activeSubPage = this.name + switch(activePage) { + case "SelectedTrack": + switch (activeSubPage) { + case "SendsQC": + // An action binding cannot be set to a Toggle type button so manually adjust the rec button lights + // based on the subpage selection. + midiOutput.sendMidi(activeDevice, [0x90, 0, 127]) + midiOutput.sendMidi(activeDevice, [0x90, 1, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 2, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 3, 0]) + activeDevice.setState("activeSubPage", activeSubPage) + break; + case "EQ": + // An action binding cannot be set to a Toggle type button so manually adjust the rec button lights + // based on the subpage selection. + midiOutput.sendMidi(activeDevice, [0x90, 0, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 1, 127]) + midiOutput.sendMidi(activeDevice, [0x90, 2, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 3, 0]) + activeDevice.setState("activeSubPage", activeSubPage) + break; + case "PreFilter": + // An action binding cannot be set to a Toggle type button so manually adjust the rec button lights + // based on the subpage selection. + midiOutput.sendMidi(activeDevice, [0x90, 0, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 1, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 2, 127]) + midiOutput.sendMidi(activeDevice, [0x90, 3, 0]) + activeDevice.setState("activeSubPage", activeSubPage) + break; + case "CueSends": + // An action binding cannot be set to a Toggle type button so manually adjust the rec button lights + // based on the subpage selection. + midiOutput.sendMidi(activeDevice, [0x90, 0, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 1, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 2, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 3, 127]) + activeDevice.setState("activeSubPage", activeSubPage) + break; + } break; - case "Limiter": - // An action binding cannot be set to ta Toggle type button so manually adjust the sel button lights - // based on the subpage selection. - midiOutput.sendMidi(activeDevice, [0x90, 24, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 25, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 26, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 27, 0]) - midiOutput.sendMidi(activeDevice, [0x90, 28, 127]) + case "ChannelStrip": + switch (activeSubPage) { + case "Gate": + // An action binding cannot be set to a Toggle type button so manually adjust the sel button lights + // based on the subpage selection. + midiOutput.sendMidi(activeDevice, [0x90, 24, 127]) + midiOutput.sendMidi(activeDevice, [0x90, 25, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 26, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 27, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 28, 0]) + activeDevice.setState("activeSubPage", activeSubPage) + break; + case "Compressor": + // An action binding cannot be set to a Toggle type button so manually adjust the sel button lights + // based on the subpage selection. + midiOutput.sendMidi(activeDevice, [0x90, 24, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 25, 127]) + midiOutput.sendMidi(activeDevice, [0x90, 26, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 27, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 28, 0]) + activeDevice.setState("activeSubPage", activeSubPage) + break; + case "Tools": + // An action binding cannot be set to a Toggle type button so manually adjust the sel button lights + // based on the subpage selection. + midiOutput.sendMidi(activeDevice, [0x90, 24, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 25, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 26, 127]) + midiOutput.sendMidi(activeDevice, [0x90, 27, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 28, 0]) + activeDevice.setState("activeSubPage", activeSubPage) + break; + case "Saturator": + // An action binding cannot be set to a Toggle type button so manually adjust the sel button lights + // based on the subpage selection. + midiOutput.sendMidi(activeDevice, [0x90, 24, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 25, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 26, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 27, 127]) + midiOutput.sendMidi(activeDevice, [0x90, 28, 0]) + activeDevice.setState("activeSubPage", activeSubPage) + break; + case "Limiter": + // An action binding cannot be set to a Toggle type button so manually adjust the sel button lights + // based on the subpage selection. + midiOutput.sendMidi(activeDevice, [0x90, 24, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 25, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 26, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 27, 0]) + midiOutput.sendMidi(activeDevice, [0x90, 28, 127]) + activeDevice.setState("activeSubPage", activeSubPage) + break; + } break; + default: + // WIP activeSubPage for these is non-sensical as they are global + switch (activeSubPage) { + case "Scrub": + activeDevice.setState("indicator2", "S") + break; + case "Nudge": + activeDevice.setState("indicator2", "N") + break; + case "Nav": + activeDevice.setState("indicator1", "N") + break; + case "Zoom": + activeDevice.setState("indicator1", "Z") + break; + } + // ! Do not set activeSubPage for these + break; } Helper_updateDisplay('Row1', 'Row2', 'AltRow1', 'AltRow2', activeDevice, midiOutput) - }).bind({ subPage, name }) + }).bind({ name }) return subPage } /** @@ -255,6 +277,20 @@ function makePageWithDefaults(name) { page.makeValueBinding(surfaceElements.faderMaster.read_button.mSurfaceValue, selectedTrackChannel.mValue.mAutomationRead).setTypeToggle() page.makeValueBinding(surfaceElements.faderMaster.write_button.mSurfaceValue, selectedTrackChannel.mValue.mAutomationWrite).setTypeToggle() + // Mixer Button + var display_type = page.mCustom.makeHostValueVariable("Mixer - display type") + page.makeValueBinding(surfaceElements.faderMaster.mixer_button.mSurfaceValue, display_type).setTypeToggle().mOnValueChange = function (activeDevice, mapping, value, value2) { + // console.log("display_type OnValueChange:"+value+":"+value2) + if(value===0) + { + activeDevice.setState("displayType", "Fader") + } else { + activeDevice.setState("displayType", "Pan") + } + // Update controller + Helper_updateDisplay(activeDevice.getState('Display - idRow1'), activeDevice.getState('Display - idRow2'), activeDevice.getState('Display - idAltRow1'), activeDevice.getState('Display - idAltRow2'), activeDevice, midiOutput) + } + return page } @@ -338,7 +374,7 @@ function makePageSelectedTrack() { onTitleChange: function(activeDevice,activeMapping,objectTitle, valueTitle) { var activePage = activeDevice.getState("activePage") var activeSubPage = activeDevice.getState("activeSubPage") - var faderValueTitles = activeDevice.getState(activePage + ' - Fader - ValueTitles') + var faderValueTitles = activeDevice.getState(activePage + "- " + activeSubPage + ' - Fader - ValueTitles') // console.log("QC Title Changed:" +this.idx+":" + objectTitle + ":" + valueTitle) switch (activePage) { case "SelectedTrack": @@ -348,8 +384,8 @@ function makePageSelectedTrack() { if (title.length === 0) { title = "None" } - activeDevice.setState(activePage + ' - Fader - ValueTitles', setTextOfColumn(this.idx, makeLabel(title, 6), faderValueTitles)) - Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) + activeDevice.setState(activePage + "- " + activeSubPage + ' - Fader - ValueTitles', setTextOfColumn(this.idx, makeLabel(title, 6), faderValueTitles)) + Helper_updateDisplay(activePage + "- " + activeSubPage + ' - Fader - ValueTitles', activePage + "- " + activeSubPage + ' - Fader - Values', activePage + "- " + activeSubPage + ' - Pan - ValueTitles', activePage + "- " + activeSubPage + ' - Pan - Values', activeDevice, midiOutput) break; } break; @@ -554,8 +590,10 @@ function makePageMidi() { .mOnValueChange = function (activeDevice, mapping, value, value2) { // console.log(displayName + ":" + mapping + "::" + value + "::" + value2) var activePage = activeDevice.getState("activePage") - var faderValueTitles = activeDevice.getState(activePage + ' - Fader - ValueTitles') - var faderValues = activeDevice.getState(activePage + ' - Fader - Values') + var activeSubPage = activeDevice.getState("activeSubPage") + + var faderValueTitles = activeDevice.getState(activePage + "- " + activeSubPage + ' - Fader - ValueTitles') + var faderValues = activeDevice.getState(activePage + "- " + activeSubPage + ' - Fader - Values') var ccValue = Math.ceil(value * 127) var pitchBendValue = Math.ceil(value * 16383) @@ -567,9 +605,9 @@ function makePageMidi() { // this is the value going back to Cubendo midiPageOutput.sendMidi(activeDevice, [0xB0, cc, ccValue]) // and this updates the D2 Display - activeDevice.setState(activePage + ' - Fader - ValueTitles', setTextOfColumn(fader, makeLabel(displayName, 6), faderValueTitles)) - activeDevice.setState(activePage + ' - Fader - Values', setTextOfColumn(fader, makeLabel(ccValue.toString(), 6), faderValues)) - Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) + activeDevice.setState(activePage + "- " + activeSubPage + ' - Fader - ValueTitles', setTextOfColumn(fader, makeLabel(displayName, 6), faderValueTitles)) + activeDevice.setState(activePage + "- " + activeSubPage + ' - Fader - Values', setTextOfColumn(fader, makeLabel(ccValue.toString(), 6), faderValues)) + Helper_updateDisplay(activePage + "- " + activeSubPage + ' - Fader - ValueTitles', activePage + "- " + activeSubPage + ' - Fader - Values', activePage + "- " + activeSubPage + ' - Pan - ValueTitles', activePage + "- " + activeSubPage + ' - Pan - Values', activeDevice, midiOutput) } } @@ -592,20 +630,22 @@ var midiPage = makePageMidi() // in the state. By clearing state on the page activation it will update all that are changing. function clearChannelState(/** @type {MR_ActiveDevice} */activeDevice) { var activePage = activeDevice.getState("activePage") + var activeSubPage = activeDevice.getState("activeSubPage") // console.log('from script: clearChannelState'+activePage) - activeDevice.setState(activePage + ' - Fader - Title', "") - activeDevice.setState(activePage + ' - Fader - ValueTitles', "") - activeDevice.setState(activePage + ' - Fader - Values', "") - activeDevice.setState(activePage + ' - Pan - Title', "") - activeDevice.setState(activePage + ' - Pan - ValueTitles', "") - activeDevice.setState(activePage + ' - Pan - Values', "") + activeDevice.setState(activePage + "- " + activeSubPage + ' - Fader - Title', "") + activeDevice.setState(activePage + "- " + activeSubPage + ' - Fader - ValueTitles', "") + activeDevice.setState(activePage + "- " + activeSubPage + ' - Fader - Values', "") + activeDevice.setState(activePage + "- " + activeSubPage + ' - Pan - Title', "") + activeDevice.setState(activePage + "- " + activeSubPage + ' - Pan - ValueTitles', "") + activeDevice.setState(activePage + "- " + activeSubPage + ' - Pan - Values', "") activeDevice.setState("displayType", "Fader") } mixerPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDevice) { // console.log('from script: Platform M+ page "Mixer" activated') activeDevice.setState("activePage", "Mixer") + activeDevice.setState("activeSubPage", "Default") clearAllLeds(activeDevice, midiOutput) clearChannelState(activeDevice) }).bind({ midiOutput }) @@ -634,11 +674,13 @@ channelStripPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDe midiOutput.sendMidi(activeDevice, [0x90, 26, 0]) midiOutput.sendMidi(activeDevice, [0x90, 27, 0]) midiOutput.sendMidi(activeDevice, [0x90, 28, 0]) + // Helper_updateDisplay("ChannelStrip" + "- " + "Gate" + ' - Fader - ValueTitles', "ChannelStrip" + "- " + "Gate" + ' - Fader - Values', "ChannelStrip" + "- " + "Gate" + ' - Pan - ValueTitles', "ChannelStrip" + "- " + "Gate" + ' - Pan - Values', activeDevice, midiOutput) }).bind({ midiOutput }) controlRoomPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDevice) { // console.log('from script: Platform M+ page "ControlRoom" activated') activeDevice.setState("activePage", "ControlRoom") + activeDevice.setState("activeSubPage", "Default") clearAllLeds(activeDevice, midiOutput) clearChannelState(activeDevice) }).bind({ midiOutput }) @@ -646,13 +688,16 @@ controlRoomPage.mOnActivate = (function (/** @type {MR_ActiveDevice} */activeDev midiPage.mOnActivate = function (/** @type {MR_ActiveDevice} */activeDevice) { // console.log('from script: Platform M+ page "Midi" activated') var activePage = "Midi" + var activeSubPage = "Default" activeDevice.setState("activePage", activePage) + activeDevice.setState("activeSubPage", activeSubPage) clearAllLeds(activeDevice, midiOutput) + clearChannelState(activeDevice) // ! This init must match the CC bindings create in the makeMidiPage function - it's annoying and needs a refactor // WIP Refactor me - var faderValueTitles = activeDevice.getState(activePage + ' - Fader - ValueTitles') + var faderValueTitles = activeDevice.getState(activePage + "- " + activeSubPage + ' - Fader - ValueTitles') faderValueTitles = setTextOfColumn(0, makeLabel("CC1", 6), faderValueTitles) faderValueTitles = setTextOfColumn(1, makeLabel("CC11", 6), faderValueTitles) - activeDevice.setState(activePage + ' - Fader - ValueTitles', setTextOfLine(faderValueTitles)) - Helper_updateDisplay(activePage + ' - Fader - ValueTitles', activePage + ' - Fader - Values', activePage + ' - Pan - ValueTitles', activePage + ' - Pan - Values', activeDevice, midiOutput) + activeDevice.setState(activePage + "- " + activeSubPage + ' - Fader - ValueTitles', setTextOfLine(faderValueTitles)) + Helper_updateDisplay(activePage + "- " + activeSubPage + ' - Fader - ValueTitles', activePage + "- " + activeSubPage + ' - Fader - Values', activePage + "- " + activeSubPage + ' - Pan - ValueTitles', activePage + "- " + activeSubPage + ' - Pan - Values', activeDevice, midiOutput) } \ No newline at end of file From c235498a217c686e6eaef27b41c4cb083f35589c Mon Sep 17 00:00:00 2001 From: Robert Woodcock Date: Sun, 10 Dec 2023 13:34:12 +1100 Subject: [PATCH 65/65] Use all tracks in Mixer Bank --- icon/platformmplus/icon_platformmplus.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/icon/platformmplus/icon_platformmplus.js b/icon/platformmplus/icon_platformmplus.js index 8ad8048..5823cf2 100644 --- a/icon/platformmplus/icon_platformmplus.js +++ b/icon/platformmplus/icon_platformmplus.js @@ -304,8 +304,6 @@ function makePageMixer() { var subPageButtonDefaultSet = makeSubPage(ButtonSubPageArea, 'DefaultSet') var hostMixerBankZone = page.mHostAccess.mMixConsole.makeMixerBankZone("AudioInstrBanks") - .includeAudioChannels() - .includeInstrumentChannels() .setFollowVisibility(true) for (var channelIndex = 0; channelIndex < surfaceElements.numStrips; ++channelIndex) {