Latest News: Bitwig updates Bitwig Studio to v5.1
Soft-Takeover on Parameters in Controller Script
-
- KVRist
- Topic Starter
- 198 posts since 8 Mar, 2004
Hi Everyone!
Is there maybe anyone out there who has already integrated a self-scripted "Soft Takeover" for (automation) parameters?
Because I am stuck getting an observer reading the current values, comparing them to the values currently on the controller, and only changing them in Bitwig when they are within a range.
Maybe someone can help me out? (First things first: setting up an observer, reading 8 macro controller knob values...)
Is there maybe anyone out there who has already integrated a self-scripted "Soft Takeover" for (automation) parameters?
Because I am stuck getting an observer reading the current values, comparing them to the values currently on the controller, and only changing them in Bitwig when they are within a range.
Maybe someone can help me out? (First things first: setting up an observer, reading 8 macro controller knob values...)
- KVRAF
- 6305 posts since 9 Dec, 2008 from Berlin
http://blog.thomashelzle.de/2014/06/bit ... observers/
Many controller scripts do this, so you may want to check some of them out.
One example is my TouchOSC script:
https://github.com/ThomasHelzle/TouchOSC-Bitwig
It does a lot but has a rather simple structure.
The Arturia KeyLab script in the factory location is a bit more current but also a bit more complex.
Cheers,
Tom
Many controller scripts do this, so you may want to check some of them out.
One example is my TouchOSC script:
https://github.com/ThomasHelzle/TouchOSC-Bitwig
It does a lot but has a rather simple structure.
The Arturia KeyLab script in the factory location is a bit more current but also a bit more complex.
Cheers,
Tom
"Out beyond the ideas of wrongdoing and rightdoing, there is a field. I’ll meet you there." - Rumi
ScreenDream Instagram Mastodon
ScreenDream Instagram Mastodon
-
- KVRist
- Topic Starter
- 198 posts since 8 Mar, 2004
Thanks for your answer,
but now I am stuck,....
Here is my work in progress script,
I am now stuck at comparing a dB value to an midi data...
-37.4 dB and 74
of course they will not be the same in any way - so I need to convert one to the other - but how?
Can you help? Thanks!
but now I am stuck,....
Here is my work in progress script,
Code: Select all
loadAPI(1);
// original oxygen 29 script
host.defineController("M-Audio", "Oxygen 49", "1.0", "2B6AB540-B75A-11E3-A5E2-0300200C9A66");
host.defineMidiPorts(1, 1);
host.addDeviceNameBasedDiscoveryPair(["Oxygen 49"], ["Oxygen 49"]);
// Main variable:
var tOSC;
var DEVICE_START_CC = 102;
var DEVICE_END_CC = 109;
function TouchOSC() {
tOSC = this;
this.cMacro = [];
this.currentVolume = 0;
this.FADERS = 118; // Start of Fader Range - 8 x track volume + 1 x master volume
this.MACROS = 102; // Start of Device Macro Range - 8 macro knobs on the cursor device
this.trackVolume = [];
this.trackVolumeHasChanged = [];
// Macros:
this.deviceMacro = [];
this.deviceMacroHasChanged = [];
// Initializations:
for (var i=0; i<8; i++) {
this.trackVolume[i] = 0;
this.trackVolumeHasChanged[i] = false;
this.deviceMacro[i] = 0;
this.deviceMacroHasChanged[i] = false;
this.cTrack = host.createCursorTrack(1, 0);
this.cDevice = tOSC.cTrack.getPrimaryDevice();
}
this.tracks = host.createMainTrackBank(8, 0, 0);
this.cTrack.getVolume().addValueDisplayObserver(8, "None", function(value) {
this.currentVolume = value;
if(this.trackVolumeHasChanged) {
// do something
}
})
}
// Search after different naming-schemes for autodetection
for ( var i = 1; i < 9; i++)
{
var name = i.toString() + "- Oxygen 49";
host.addDeviceNameBasedDiscoveryPair([name], [name]);
host.addDeviceNameBasedDiscoveryPair(["Oxygen 49 MIDI " + i.toString()], ["Oxygen 49 MIDI " + i.toString()]);
}
var CC =
{
PREV_PRESET : 57,
NEXT_PRESET : 58,
PREV_TRACK : 59,
NEXT_TRACK : 60,
LOOP : 20,
REWIND : 21,
FORWARD : 22,
STOP : 23,
PLAY : 24,
RECORD : 25,
SLIDER : 118,
};
var LOWEST_CC = 2;
var HIGHEST_CC = 101;
function isInDeviceParametersRange(cc)
{
return cc >= DEVICE_START_CC && cc <= 105;
}
function isInDeviceParametersRange2(cc)
{
return cc >= 106 && cc <= DEVICE_END_CC;
}
function init()
{
// instantiate a new TouchOSC Object:
new TouchOSC()
// Creating Observers, indications etc.:
for (var i=0; i<8; i++) {
// Volume
tOSC.tracks.getTrack(i).getVolume().setIndication(true);
tOSC.tracks.getTrack(i).getVolume().addValueObserver(127, getTrackValueFunc(i, tOSC.trackVolume, tOSC.trackVolumeHasChanged));
// Macro
tOSC.cMacro[i] = tOSC.cDevice.getMacro(i);
tOSC.cMacro[i].getAmount().setIndication(true);
tOSC.cMacro[i].getAmount().addValueObserver(127, getTrackValueFunc(i, tOSC.deviceMacro, tOSC.deviceMacroHasChanged));
}
cursorTrack2 = host.createCursorTrackSection(3, 0);
device = host.createCursorDevice();
transport = host.createTransport();
primaryInstrument = cursorTrack2.getPrimaryInstrument();
for ( var i = 0; i < 8; i++)
{
var p = primaryInstrument.getMacro(i).getAmount();
p.setIndication(true);
}
// Register callbacks for midi- and sysex-events
host.getMidiInPort(0).setMidiCallback(onMidi);
noteIn = host.getMidiInPort(0).createNoteInput("Oxygen 25 Keyboard");
// Make CCs 0-109 freely mappable
userControls = host.createUserControls(HIGHEST_CC);
for(var i=LOWEST_CC; i<=HIGHEST_CC; i++)
{
userControls.getControl(i - LOWEST_CC).setLabel("CC" + i);
}
// The cursor track view follows the track selection in the application GUI
cursorTrack = host.createCursorTrack(4, 4);
}
function onMidi(status, data1, data2)
{
//printMidi(status, data1, data2);
if (isChannelController(status))
{
// Handle transport-buttons and trackselection
if ((data1 >= 20 && data1 <= 60 && data1 != 112) && data2 >= 0)
{
switch(data1) {
case CC.PREV_TRACK:
cursorTrack.selectPrevious();
break;
case CC.PREV_PRESET:
device.switchToPreviousPreset();
break;
case CC.NEXT_PRESET:
{
device.switchToNextPreset();
}
break;
case CC.NEXT_TRACK:
cursorTrack.selectNext();
break;
case CC.LOOP:
transport.toggleLoop();
break;
case CC.REWIND:
transport.rewind();
break;
case CC.FORWARD:
transport.fastForward();
break;
case CC.STOP:
transport.stop();
break;
case CC.PLAY:
transport.play();
break;
case CC.RECORD:
cursorTrack.getArm().toggle();
transport.record();
break;
}
}
else
{
if (isInDeviceParametersRange(data1))
{
var index = data1 - DEVICE_START_CC;
if (index == 0) index = 4;
if (index == 1) index = 5;
if (index == 2) index = 6;
if (index == 3) index = 7;
primaryInstrument.getMacro(index).getAmount().set(data2, 128);
}
if (isInDeviceParametersRange2(data1))
{
var index = data1 - DEVICE_START_CC;
if (index == 4) index = 0;
if (index == 5) index = 1;
if (index == 6) index = 2;
if (index == 7) index = 3;
primaryInstrument.getMacro(index).getAmount().set(data2, 128);
}
// Handle slider for trackvolume
if (data1 == CC.SLIDER)
{
var oldVolVal = this.currentVolume;
var newVolVal = tOSC.trackVolume[0];
// printMidi(oldVolVal,newVolVal);
var ok = false;
if (newVolVal != oldVolVal) ok = true;
if (ok == true) {
cursorTrack.getVolume().set(data2, 128);
}
}
else
{
// Handle CC 02 - 109
if (data1 >= LOWEST_CC && data1 <= HIGHEST_CC)
{
var index = data1 - LOWEST_CC;
userControls.getControl(index).set(data2, 128);
}
}
}
}
}
function flush()
{
// Check if transport has changed and if yes, update all of the controlls:
// Go through an 8-step Loop to check for all the stuff that could have changed:
for (var k=0; k<8; k++) {
var oldVolVal = this.currentVolume;
var newVolVal = tOSC.trackVolume[k];
var ok = false;
if (newVolVal == oldVolVal) ok = true;
if (tOSC.trackVolumeHasChanged[k] && ok == true) {
sendChannelController(0, tOSC.FADERS + k, tOSC.trackVolume[k]);
tOSC.trackVolumeHasChanged[k] = false;
}
if (tOSC.deviceMacroHasChanged[k]) {
sendChannelController(0, tOSC.MACROS + k, tOSC.deviceMacro[k]);
tOSC.deviceMacroHasChanged[k] = false;
}
}
}
function exit()
{
}
// different functions from other script, maybe dont need
function onSysex(data)
{
//printSysex(data);
}
// A function to create an indexed function for the Observers
function getValueObserverFunc(index, varToStore)
{
return function(value)
{
varToStore[index] = value;
}
}
// A function to create an indexed function for the Observers with an added state variable:
function getTrackValueFunc(index, varToStore, varToSet)
{
return function(value)
{
varToStore[index] = value;
varToSet[index] = true;
}
}
// A function to create an indexed function for the Observers for Clips including a Color-Update:
function getClipValueFunc(slot, varToStore)
{
return function(index, value)
{
varToStore[slot+index*4] = value;
}
}
-37.4 dB and 74
of course they will not be the same in any way - so I need to convert one to the other - but how?
Can you help? Thanks!
- KVRian
- 1372 posts since 28 Dec, 2012 from Meredith NH
I am actually working on a soft take over implementation for a script I am writing. If you are still around next week, I will post some code that might be able to help you.
Mike
Mike
Michael Schmalle
http://www.teotigraphix.com
Surfing on sine waves
Maschine4Bitwig - Studio, MK2, MikroMK2, MK1
http://www.teotigraphix.com/bitwig/maschine
http://www.teotigraphix.com
Surfing on sine waves
Maschine4Bitwig - Studio, MK2, MikroMK2, MK1
http://www.teotigraphix.com/bitwig/maschine
- KVRAF
- 6305 posts since 9 Dec, 2008 from Berlin
You can observe either the scaled value with addValueObserver, then you give it an integer range to which the value is scaled (for instance 128 for the typical Midi controller), or you can observe the raw internal value (the value that Bitwig Studio uses internally to represent the value) with addRawValueObserver, check what you get and do your own scaling.
The same is true for set/setRaw and inc/incRaw.
Does that make sense?
I personally will wait for the BWS-native takeover implementation, but there is no date for that yet.
Cheers,
Tom
The same is true for set/setRaw and inc/incRaw.
Does that make sense?
I personally will wait for the BWS-native takeover implementation, but there is no date for that yet.
Cheers,
Tom
"Out beyond the ideas of wrongdoing and rightdoing, there is a field. I’ll meet you there." - Rumi
ScreenDream Instagram Mastodon
ScreenDream Instagram Mastodon
- KVRian
- 1372 posts since 28 Dec, 2012 from Meredith NH
You say this but are we talking 1.2, or "have no idea". I would love to use the native impl and not waste time doing it right now.ThomasHelzle wrote:You can observe either the scaled value with addValueObserver, then you give it an integer range to which the value is scaled (for instance 128 for the typical Midi controller), or you can observe the raw internal value (the value that Bitwig Studio uses internally to represent the value) with addRawValueObserver, check what you get and do your own scaling.
The same is true for set/setRaw and inc/incRaw.
Does that make sense?
I personally will wait for the BWS-native takeover implementation, but there is no date for that yet.
Cheers,
Tom
Mike
Michael Schmalle
http://www.teotigraphix.com
Surfing on sine waves
Maschine4Bitwig - Studio, MK2, MikroMK2, MK1
http://www.teotigraphix.com/bitwig/maschine
http://www.teotigraphix.com
Surfing on sine waves
Maschine4Bitwig - Studio, MK2, MikroMK2, MK1
http://www.teotigraphix.com/bitwig/maschine
- KVRAF
- 6305 posts since 9 Dec, 2008 from Berlin
My hope is that it's 1.1.x, but no, I have no idea yet, since it involves several areas of the application.
Cheers,
Tom
Cheers,
Tom
"Out beyond the ideas of wrongdoing and rightdoing, there is a field. I’ll meet you there." - Rumi
ScreenDream Instagram Mastodon
ScreenDream Instagram Mastodon