Sharing Data/Variables/Functions Between scripts?
-
- KVRist
- 74 posts since 12 Dec, 2007 from Fort Bragg, CA
Is it possible to share data either variables or functions between scripts? like one instance of a script calling another? or leaving data between them somehow in some sort of global object?
I'm wanting one controller to affect the state of another.... like one controller to change track selection and another to adjust the parameters.
Is my best bet to make a mega script with all of my controllers in one? Could seem unweildly.
I could also see some hacks/workaround using bomes midi translater to pass certain events thru to the different scripts but this would be dire extremes.
I'm wanting one controller to affect the state of another.... like one controller to change track selection and another to adjust the parameters.
Is my best bet to make a mega script with all of my controllers in one? Could seem unweildly.
I could also see some hacks/workaround using bomes midi translater to pass certain events thru to the different scripts but this would be dire extremes.
---------------------------------------------------------------
http://kirkwoodwest.com/
http://kirkwoodwest.com/
-
- KVRist
- Topic Starter
- 74 posts since 12 Dec, 2007 from Fort Bragg, CA
hydrogxn wrote: Mon Apr 20, 2020 6:30 am Is it possible to share data either variables or functions between scripts? like one instance of a script calling another? or leaving data between them somehow in some sort of global object?
I'm wanting one controller to affect the state of another.... like one controller to change track selection and another to adjust the parameters.
Is my best bet to make a mega script with all of my controllers in one? Could seem unweildly.
I could also see some hacks/workaround using bomes midi translater to pass certain events thru to the different scripts but this would be dire extremes of wanting to use individual scripts...
---------------------------------------------------------------
http://kirkwoodwest.com/
http://kirkwoodwest.com/
- KVRAF
- 4889 posts since 13 May, 2004
Scripts / Extensions are separated but you can use any kind of inter-process communication. Supported by the API you get UDP and OSC. Especially, if you use Java there are plenty of additional options.
-
- KVRist
- Topic Starter
- 74 posts since 12 Dec, 2007 from Fort Bragg, CA
got it. what would you suggest if you went the java route?
I'm currently prototyping a lot of my controller scripts in .js and will migrate to java eventually.
I'm currently prototyping a lot of my controller scripts in .js and will migrate to java eventually.
---------------------------------------------------------------
http://kirkwoodwest.com/
http://kirkwoodwest.com/
- KVRAF
- 4889 posts since 13 May, 2004
This depends on what you are trying to achieve.
-
- KVRist
- Topic Starter
- 74 posts since 12 Dec, 2007 from Fort Bragg, CA
what im wanting is to call a function directly in each script lol.
but i think with the .js includes and some customization ill be able to have some sort of roundabout osc thing so they can all talk to each other...
im gonna attempt something where one script talks to many others to do something.
one thing i cant wrap my head around is how to make each instance of a controller script to use a different port. i think that will be necessary somehow.
im gonna attempt something where one script talks to many others to do something.
one thing i cant wrap my head around is how to make each instance of a controller script to use a different port. i think that will be necessary somehow.
---------------------------------------------------------------
http://kirkwoodwest.com/
http://kirkwoodwest.com/
-
- KVRer
- 15 posts since 21 Apr, 2020
You can use Node.js to set up a local server and each of your scripts can be a client. You should be able to get 2 way communication going. You'll have to download node.js (https://nodejs.org/en/download)
logsrv.node.js - this will be the server. you can run it using "node logsrv.node.js" in the command prompt, or as a windows service
In your controller script, add this in init():
and add these 2 functions:
to send a message to the server, use:
So using this example, as soon as the client (your controller script) sends "Hello server" on port 58000 to the server, the server will reply with "Hello client".
logsrv.node.js - this will be the server. you can run it using "node logsrv.node.js" in the command prompt, or as a windows service
Code: Select all
var net = require('net');
var fs = require('fs');
function str2ab(str) {
var buf = new ArrayBuffer(str.length + 4); // 1 byte for each char
var bufView = new Uint8Array(buf);
bufView[3] = str.length;
for (var i=4, strLen=str.length; i < strLen+4; i++) {
bufView[i] = str.charCodeAt(i-4);
}
return bufView;
}
// Create our socket
var server = net.createServer(
function (socket) {
// Callback when data is received
socket.on('data', function(data)
{
var messagetxt = "";
// Convert bytes to string
for(var i = 0; i < data.length; i++)
{
messagetxt += String.fromCharCode(data[i]);
}
// Print message to console
console.log(messagetxt);
socket.write(Uint8Array.from(str2ab("Hello client")));
socket.pipe(socket);
});
}
);
// Start server
console.log("Listening on 127.0.0.1:58000 ...");
server.listen(58000, '127.0.0.1');
Code: Select all
socket = host.createRemoteConnection("BitwigNodeService", 58000);
host.connectToRemoteHost('127.0.0.1', 58000, function(conn)
{
if (typeof this.remoteConnection === 'undefined')
{
this.remoteConnection = conn;
}
this.remoteConnection.setReceiveCallback(remoteReceiveCallback);
});
Code: Select all
function remoteReceiveCallback( data )
{
println(bin2String(data));
}
function bin2String(array)
{
var result = "";
for (var i = 0; i < array.length; i++)
{
result += String.fromCharCode(array[i]);
}
return result;
}
Code: Select all
var messagetxt = "Hello server";
this.remoteConnection.send(messagetxt.getBytes());
-
- KVRer
- 16 posts since 7 Apr, 2010 from Newcastle, Australia
@vadmired13 That is amazing! Thank you so much for this example! 
- KVRAF
- 2482 posts since 22 Sep, 2016
Hm, just a complete noob to Bitwig Programming but with a solid Java Knowhow...
I think the possibility of Inter-Script communication should be built into the platform itself.
Thinking about simple version of OSGI here. OSGI is the framework for instance eclipse IDE of various application servers are built on top. OSGI is built with the idea of extensibility, it's extensible with plug-ins, yet shields plug-ins which are only exposing API objects to each other.
In OSGI you have extensions that ...
If you think about that, even Bitwig itself could expose it's APIs through this mechanism.
Not saying that it has to be OSGI, but there are other examples like for instance the Android platform which comes with similar mechanismas. Please don't get me wrong - I don't say implement this or that, I'm just giving examples for "platfrom concepts" people/programmers might know and which have proven usefull... Bitwig never need to become a full blown android, but could "borrow" some concepts
Anyway... just 2cents of a old Java Guy.
I think the possibility of Inter-Script communication should be built into the platform itself.
Thinking about simple version of OSGI here. OSGI is the framework for instance eclipse IDE of various application servers are built on top. OSGI is built with the idea of extensibility, it's extensible with plug-ins, yet shields plug-ins which are only exposing API objects to each other.
In OSGI you have extensions that ...
- ...implement and provide interfaces ... just in Pseudo-Code for your intuition Bundle.getContext().publish("myInterface", implObj)
- ...require interface theService = Bundle.getContext().getImpl("myInterface")
If you think about that, even Bitwig itself could expose it's APIs through this mechanism.
Not saying that it has to be OSGI, but there are other examples like for instance the Android platform which comes with similar mechanismas. Please don't get me wrong - I don't say implement this or that, I'm just giving examples for "platfrom concepts" people/programmers might know and which have proven usefull... Bitwig never need to become a full blown android, but could "borrow" some concepts
Anyway... just 2cents of a old Java Guy.
-
- KVRer
- 14 posts since 17 Oct, 2017
I did this between a bitwig controller script and python using Py4j: https://github.com/outterback/bitwig-py ... /README.md
Which I believe works over tcp. I used it to have access to clips, tracks, and notes from a python console just to prototype some stuff. It worked surprisingly well! The code is very simple if you want to take a look at it.
Which I believe works over tcp. I used it to have access to clips, tracks, and notes from a python console just to prototype some stuff. It worked surprisingly well! The code is very simple if you want to take a look at it.
-
- KVRer
- 15 posts since 21 Apr, 2020
Here's an updated version of logsrv.node.js. What I'm doing here is keeping track of the connected clients (in my case, 2 launchcontrolxl controllers), and when one of them sends a message to the server, the server relays that message to the other controller only. It would work the same if you have multiple controllers...the server will relay the message to all controllers aside from the one that sent it. The clients are indexed using their unique client address.
In my controller script, I use the following to send messages to the server
And finally, also in the controller script, I use the following to receive and handle messages from the server
Code: Select all
var net = require('net');
function str2ab(str) {
var buf = new ArrayBuffer(str.length + 4); // 1 byte for each char
var bufView = new Uint8Array(buf);
bufView[3] = str.length;
for (var i=4, strLen=str.length; i < strLen+4; i++) {
bufView[i] = str.charCodeAt(i-4);
}
return bufView;
}
var clients = new Map();
var net = require('net');
var server = net.createServer(function(connection) {
// new connection established
var clientAddress = connection.remotePort;
clients.set(clientAddress, connection);
// callback for end connection
connection.on('end', function() {
if (clients.has(clientAddress))
{
clients.delete(clientAddress);
}
connection.end();
});
// callback for data received from client
connection.on('data', function(data)
{
var messagetxt = "";
// Convert bytes to string
for(var i = 0; i < data.length; i++)
{
messagetxt += String.fromCharCode(data[i]);
}
clients.forEach(function(val, key, map)
{
if (key !== clientAddress)
{
val.write(Uint8Array.from(str2ab(messagetxt)));
}
});
// Print message to console
console.log(messagetxt);
});
});
// Start server
server.listen(58000, function() {
console.log('server is listening');
});
Code: Select all
var messagetxt = "send_down";
remoteConnection.send(messagetxt.getBytes());
Code: Select all
function remoteReceiveCallback( data )
{
msg = bin2String(data);
if (msg === "send_up")
{
// do stuff
}
if (msg === "send_down")
{
// do butt stuff
}
}
- KVRist
- 393 posts since 12 Apr, 2020
This looks bad ass my guy. what kind of stuff have you used this for? did you have something specific you are trying to achieve?outterback wrote: Sat May 23, 2020 4:36 pm I did this between a bitwig controller script and python using Py4j: https://github.com/outterback/bitwig-py ... /README.md
Which I believe works over tcp. I used it to have access to clips, tracks, and notes from a python console just to prototype some stuff. It worked surprisingly well! The code is very simple if you want to take a look at it.
----------------------------------------------------------------------
/CTRL → http://slashctrl.io
Music & mixes → http://soundcloud.com/kirkwoodwest
/CTRL → http://slashctrl.io
Music & mixes → http://soundcloud.com/kirkwoodwest
