Skip to content

Commit

Permalink
Version 1.2:
Browse files Browse the repository at this point in the history
- changed behaviour for various elements
- fixed track focus and selection
- tested with Bitwig 4.0.8
  • Loading branch information
Mirco Lukas committed May 30, 2022
1 parent e0863c6 commit 2451a00
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 95 deletions.
12 changes: 6 additions & 6 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ When using Linux, the script should automaticly find and subscribe the controlle
There is an explanation what each knob and button does (assignment.pdf).

Changelog:
Version 1.2:
- changed behaviour for various elements
- fixed track focus and selection
- tested with Bitwig 4.0.8

Version 1.1:
- fixed float to int conversion for volumeValue, causing script to cease working in bitwig 3.3

Known issues:

When changing a device parameter on parameter page 1, the LEDs of the parameter buttons (parameters 5-8 on page 2) light up like the parameters 5-8 on page 1. This seems inevitable with the current API due to the face that one can only set a callback for a parameter of the parameter view. When the view changes its page, the callback is activated. Moveover, increasing the amount of parameters per page seems not to work for values greater than 8, so that page scrolling is necessary.
However, the button function itself works fine - it is only the LEDs.

About:

Author: Philipp Winniewski
Date: 18/12/2020
Date: 28/05/2022
49 changes: 28 additions & 21 deletions SteinbergCC121.channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,62 +3,54 @@ var JOGFACTOR_PANNING = 4;

function initChannel() {
// Creating views
trackBank = host.createMainTrackBank(1, 1, 1);
arrangerCursorTrack = host.createArrangerCursorTrack(1, 1);
trackBank.followCursorTrack(arrangerCursorTrack);
trackBank = host.createTrackBank(1, 0, 0, true);
cursorTrack = host.createCursorTrack("CC121_TRACK", "Cursor Track", 1, 1, true);
trackBank.followCursorTrack(cursorTrack);
transport = host.createTransport();
application = host.createApplication();

// Publishing observers
trackBank.getChannel(0).mute().addValueObserver(function(isMuted) {
trackBank.getChannel(0).mute().addValueObserver(function (isMuted) {
if (isMuted) {
sendMidi(144, NOTE.MUTE, LIGHT_ON);
} else {
sendMidi(144, NOTE.MUTE, LIGHT_OFF);
}
});

trackBank.getChannel(0).solo().addValueObserver(function(isSolo) {
trackBank.getChannel(0).solo().addValueObserver(function (isSolo) {
if (isSolo) {
sendMidi(144, NOTE.SOLO, LIGHT_ON);
} else {
sendMidi(144, NOTE.SOLO, LIGHT_OFF);
}
});

transport.isArrangerAutomationWriteEnabled().addValueObserver(function(isAutomationWrite) {
transport.isArrangerAutomationWriteEnabled().addValueObserver(function (isAutomationWrite) {
if (isAutomationWrite) {
sendMidi(144, NOTE.AUTOMATIONWRITE, LIGHT_ON);
} else {
sendMidi(144, NOTE.AUTOMATIONWRITE, LIGHT_OFF);
}
});

transport.isAutomationOverrideActive().addValueObserver(function(isAutomationOverride) {
if (isAutomationOverride) {
sendMidi(144, NOTE.AUTOMATIONREAD, LIGHT_ON);
} else {
sendMidi(144, NOTE.AUTOMATIONREAD, LIGHT_OFF);
}
});

trackBank.getTrack(0).arm().addValueObserver(function(isArmed) {
trackBank.getTrack(0).arm().addValueObserver(function (isArmed) {
if (isArmed) {
sendMidi(144, NOTE.RECORDARM, LIGHT_ON);
} else {
sendMidi(144, NOTE.RECORDARM, LIGHT_OFF);
}
});

trackBank.getTrack(0).monitor().addValueObserver(function(isMonitored) {
if (isMonitored) {
trackBank.getTrack(0).monitorMode().addValueObserver(function (value) {
if (value.toUpperCase() === MONITORMODE.AUTO || value.toUpperCase() === MONITORMODE.ON) {
sendMidi(144, NOTE.INPUTMONITOR, LIGHT_ON);
} else {
sendMidi(144, NOTE.INPUTMONITOR, LIGHT_OFF);
}
});

trackBank.getChannel(0).volume().value().addValueObserver(function(volumeValue) {
trackBank.getChannel(0).volume().value().addValueObserver(function (volumeValue) {
var LSB = parseInt((volumeValue * 16383) % 128);
var MSB = parseInt((volumeValue * 16383) / 128);
sendMidi(224, LSB, MSB);
Expand All @@ -81,10 +73,10 @@ function onMidiChannel(status, data1, data2) {
} else if (isNoteOn(status) && data2 > 0) {
switch (data1) {
case NOTE.CHANNELSELECTRIGHT:
arrangerCursorTrack.selectNext();
cursorTrack.selectNext();
break;
case NOTE.CHANNELSELECTLEFT:
arrangerCursorTrack.selectPrevious();
cursorTrack.selectPrevious();
break;
case NOTE.MUTE:
trackBank.getChannel(0).mute().toggle();
Expand All @@ -102,7 +94,7 @@ function onMidiChannel(status, data1, data2) {
trackBank.getTrack(0).arm().toggle();
break;
case NOTE.INPUTMONITOR:
trackBank.getTrack(0).monitor().toggle();
toggleMonitorMode();
break;
case NOTE.EBUTTON:
application.toggleInspector();
Expand All @@ -115,3 +107,18 @@ function onMidiChannel(status, data1, data2) {
trackBank.getChannel(0).volume().value().set(data2 * 128 + data1, 16383);
}
}

function toggleMonitorMode() {
var currentValue = trackBank.getTrack(0).monitorMode().get();
switch (currentValue.toUpperCase()) {
case MONITORMODE.AUTO:
trackBank.getTrack(0).monitorMode().set(MONITORMODE.ON);
break;
case MONITORMODE.ON:
trackBank.getTrack(0).monitorMode().set(MONITORMODE.OFF);
break;
case MONITORMODE.OFF:
trackBank.getTrack(0).monitorMode().set(MONITORMODE.AUTO);
break;
}
}
20 changes: 18 additions & 2 deletions SteinbergCC121.control.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Note: blinking "READY LED" can not be avoided, CC121 needs F043103E150001F7 every second...
loadAPI(5);
loadAPI(14);
load("SteinbergCC121.transport.js");
load("SteinbergCC121.function.js");
load("SteinbergCC121.ai.js");
Expand Down Expand Up @@ -76,14 +76,28 @@ var CC = {
AIKNOB: 0x3C
}

var MONITORMODE = {
AUTO: 'AUTO',
ON: 'ON',
OFF: 'OFF'
}

var PREROLLMODE = {
NONE: 'none',
TWO_BARS: 'two_bars'
}

// Array of midi listeners
var midiListeners;

// Job button is for parameter acceleration;
var isJogActive = false;

// Either main or effect track bank
var trackBank;

// Company, product, script version, UUID, author
host.defineController("Steinberg", "CC121", "1.1", "A1068940-6B61-11E8-B566-0800200C9A66", "Philipp Winniewski");
host.defineController("Steinberg", "CC121", "1.2", "a32cae8c-de14-11ec-9d64-0242ac120002", "Philipp Winniewski");
host.defineMidiPorts(1, 1);
// For Windows
host.addDeviceNameBasedDiscoveryPair(["Steinberg CC121-1"], ["Steinberg CC121-1"]);
Expand All @@ -102,6 +116,8 @@ function init() {
initChannel(),
initDevice()
];

println("Steinberg CC121 initialized!");
}

function exit() {
Expand Down
63 changes: 1 addition & 62 deletions SteinbergCC121.device.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function initDevice() {
// Creating views
arrangerCursorDevice = host.createEditorCursorDevice();

arrangerCursorDevice.isEnabled().addValueObserver(function(deviceEnabled) {
arrangerCursorDevice.isEnabled().addValueObserver(function (deviceEnabled) {
if (deviceEnabled) {
sendMidi(144, NOTE.ALLBYPASS, LIGHT_ON);
} else {
Expand All @@ -30,47 +30,6 @@ function initDevice() {

parameterBank = arrangerCursorDevice.createCursorRemoteControlsPage(8);

// Problem: callback (LEDs) does not work proper when page 1 selected and event on page 2
parameterBank.getParameter(4).addValueObserver(function(parameter_4_Enabled) {
if (parameter_4_Enabled) {
sendMidi(144, NOTE.EQENABLE1, LIGHT_ON);
LOW_LOCKED = 127;
} else {
sendMidi(144, NOTE.EQENABLE1, LIGHT_OFF);
LOW_LOCKED = 0;
}
});

parameterBank.getParameter(5).addValueObserver(function(parameter_5_Enabled) {
if (parameter_5_Enabled) {
sendMidi(144, NOTE.EQENABLE2, LIGHT_ON);
LOWMID_LOCKED = 127;
} else {
sendMidi(144, NOTE.EQENABLE2, LIGHT_OFF);
LOWMID_LOCKED = 0;
}
});

parameterBank.getParameter(6).addValueObserver(function(parameter_6_Enabled) {
if (parameter_6_Enabled) {
sendMidi(144, NOTE.EQENABLE3, LIGHT_ON);
HIGHMID_LOCKED = 127;
} else {
sendMidi(144, NOTE.EQENABLE3, LIGHT_OFF);
HIGHMID_LOCKED = 0;
}
});

parameterBank.getParameter(7).addValueObserver(function(parameter_7_Enabled) {
if (parameter_7_Enabled) {
sendMidi(144, NOTE.EQENABLE4, LIGHT_ON);
HIGH_LOCKED = 127;
} else {
sendMidi(144, NOTE.EQENABLE4, LIGHT_OFF);
HIGH_LOCKED = 0;
}
});

return onMidiDevice;
}

Expand Down Expand Up @@ -154,26 +113,6 @@ function onMidiDevice(status, data1, data2) {
arrangerCursorDevice.browseToReplaceDevice();
}
break;
case NOTE.EQENABLE1:
LOW_LOCKED = toggleMidiCCValue(LOW_LOCKED);
parameterBank.selectedPageIndex().set(1);
parameterBank.getParameter(4).inc(LOW_LOCKED, 128);
break;
case NOTE.EQENABLE2:
LOWMID_LOCKED = toggleMidiCCValue(LOWMID_LOCKED);
parameterBank.selectedPageIndex().set(1);
parameterBank.getParameter(5).inc(LOWMID_LOCKED, 128);
break;
case NOTE.EQENABLE3:
HIGHMID_LOCKED = toggleMidiCCValue(HIGHMID_LOCKED);
parameterBank.selectedPageIndex().set(1);
parameterBank.getParameter(6).inc(HIGHMID_LOCKED, 128);
break;
case NOTE.EQENABLE4:
HIGH_LOCKED = toggleMidiCCValue(HIGH_LOCKED);
parameterBank.selectedPageIndex().set(1);
parameterBank.getParameter(7).inc(HIGH_LOCKED, 128);
break;
}
}
}
Expand Down
12 changes: 12 additions & 0 deletions SteinbergCC121.function.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@ function onMidiFunction(status, data1, data2) {
case NOTE.VALUEENCODERBUTTON:
transport.isMetronomeEnabled().toggle();
break;
case NOTE.EQENABLE1:
application.createAudioTrack(-1);
break;
case NOTE.EQENABLE2:
application.createInstrumentTrack(-1);
break;
case NOTE.EQENABLE3:
application.createEffectTrack(-1);
break;
case NOTE.EQENABLE4:
application.rename();
break;
}
}
}
37 changes: 33 additions & 4 deletions SteinbergCC121.transport.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,45 @@
var preRollMode;

function initTransport() {
// Creating views
transport = host.createTransport();
application = host.createApplication();

// Publishing observers
transport.isPlaying().addValueObserver(function(play) {
transport.isPlaying().addValueObserver(function (play) {
if (play) {
sendMidi(144, NOTE.PLAY, LIGHT_ON);
} else {
sendMidi(144, NOTE.PLAY, LIGHT_OFF);
}
});

transport.isArrangerRecordEnabled().addValueObserver(function(record) {
transport.isArrangerRecordEnabled().addValueObserver(function (record) {
if (record) {
sendMidi(144, NOTE.RECORD, LIGHT_ON);
} else {
sendMidi(144, NOTE.RECORD, LIGHT_OFF);
}
})

transport.isArrangerLoopEnabled().addValueObserver(function(loop) {
transport.isArrangerLoopEnabled().addValueObserver(function (loop) {
if (loop) {
sendMidi(144, NOTE.LOOP, LIGHT_ON);
} else {
sendMidi(144, NOTE.LOOP, LIGHT_OFF);
}
})

transport.preRoll().addValueObserver(function (value) {
if (value.toLowerCase() === PREROLLMODE.NONE) {
preRollMode = PREROLLMODE.NONE;
sendMidi(144, NOTE.AUTOMATIONREAD, LIGHT_OFF);
} else {
preRollMode = PREROLLMODE.TWO_BARS;
sendMidi(144, NOTE.AUTOMATIONREAD, LIGHT_ON);
}
});

return onMidiTransport;
}

Expand All @@ -44,7 +56,7 @@ function onMidiTransport(status, data1, data2) {
transport.stop();
break;
case NOTE.RECORD:
transport.record();
toggleRecord();
break;
case NOTE.TOSTART:
transport.rewind();
Expand All @@ -55,6 +67,23 @@ function onMidiTransport(status, data1, data2) {
case NOTE.TOEND:
transport.fastForward();
break;
case NOTE.AUTOMATIONREAD:
togglePreRoll();
break;
}
}
}

function toggleRecord() {
var previousValue = transport.isArrangerAutomationWriteEnabled().get();
transport.record();
transport.isArrangerAutomationWriteEnabled().set(previousValue);
}

function togglePreRoll() {
if (preRollMode === PREROLLMODE.NONE) {
transport.preRoll().set(PREROLLMODE.TWO_BARS);
} else {
transport.preRoll().set(PREROLLMODE.NONE);
}
}
Binary file modified assignment.pdf
Binary file not shown.

0 comments on commit 2451a00

Please sign in to comment.