first time scripting

RELATED
PRODUCTS

Post

Hi guys, i've got myself an Akai MPD226 and love it - works nice with Bitwig as well, thanks to the Akai script that came with it, however as usual i feel it's not 'quite' perfect for me and i've plucked up the courage to start hacking at the script to try to make it work how i would like it.

Please understand that i have no scripting experience at all and don't know Java script etc so i'm throwing myself in at the deep end. I also have a very limited amount of time , so becoming a jedi master scripter isn't an option right now - for the time being i just need to learn some basics and 'wing it' as best as i can lol.

Hopefully i can figure it out myself but i just wondered if anybody would mind , if i got stuck , if I ask for a bit of a hand-hold here - just some general pointers in right direction etc. I'll keep it all within this thread.

My aims are very simple

1) to make the Record button on the controller activate Overdub instead of Record.
2) to make the metronome come on whenever overdub is on and bitwig playing.
3) to make one of the buttons into an undo button.
4) to make one of the buttons into a quantise button

thats it :-)

Regarding 3 and 4, i would want these to work whilst in the recording flow. So for example the quantise button should stop recording (if currently recording), select the notes, quantise them, then continue recording (if previously recording).. so it seems like it's seemless from the users perspective.

My first question is, is all the above possible and should it be straight forward?

thank you very much in advance !
:pray:

ps. i realise some of this can be mapped manually in the midi-mapping and keyboard mapping options but i do not want to go this route.

Post

1 - 3 is possible.

1) Simply call the according function (see the scripting API in the help menu)
2) Register observers for both. When both are true activate the metronome
3) Simply call undo function (see API)
4) There is currently no dedicated quantize function (please bug Bitwig with that wish, mine seems not enough :-)). I did a workaround with calling the menu entry but that requires to have the focus on the midi notes which is pretty bad...

Post

moss wrote:I did a workaround with calling the menu entry but that requires to have the focus on the midi notes which is pretty bad...
There seem to be a lot of problems regarding focus with Bitwig scripts - like having to select devices via the mouse before i can use my controller to move the assigned knobs instead of having them available at all times like with Push/Ableton.

You seem to work pretty close with the Bitwig team, do you think they can fix this in the future? I would bug them myself but lack the proper terminology as i'm entirely clueless about anything remotely related to coding... :wink: :ud:

I use your fantastic Push script by the way - thank you so much for your work on it!

Post

thanks so far. I have a lot to learn! lol

Regarding 3, the Undo... in another thread it was discussed that you have to disable recording before it can undo. Hopefully it will be possible with a script to make bitwig stop recording, undo, and then re-engage recording, without any obvious break in the flow?

Can you literally call one command after another instantly, or do you need to put a pause between them so that bitwig can catch up and not be overloaded?

Post

OP - if you're interested, the KMI tutorials (1-7) are pretty good for someone that doesn't know much about coding.

http://www.keithmcmillen.com/blog/contr ... io-part-1/

It also shows how to make a transport, which can be indirectly applied to the things you want to do.

Post

thanks dplduffy yes those are written a bit more in my newbie language! must admit i'm struggling so far. At least i've made it overdub instead of record haha :party:

Post

could somebody just give me a point in the right direction regarding this issue...

Code: Select all

  
				{
                    /* MODE SWITCH BUTTON 4 */
                    println("MODE BUTTON 4");
                    transport.stop();
                    application.undo();
                    transport.play();

                }
I am expecting it to stop playing, undo, then restart playing, all in one fluid action... however what is happening is that it stops playing but then does nothing till i press the button for a 2nd time which it it happily undos and starts playing...

please let me know why it's stopping and what i need to do to get it working as i hope.
thank you
Dale

Post

Code: Select all

var yourBestWorkingDelayTime=15;

transport.stop();
 Application.undo();
 host.scheduleTask(function()
{ transport.play();}
,null,yourBestWorkingDelayTime);}
Kind of workaround, probably not ideal.

Post

Thanks Kreczek will give that a try!

Can you please explain to me why my original code doesn't work as i expected it to work? (just trying to learn)

thank you
Dale

Post

One thing to note: I don't know this for a fact but I think Bitwig's API is asynchronous. Which means although it looks like your code is being called synchronous in javascript it is actually being batched in the core of Bitwig.

Moss and I have had problems with timing of method calls I am guessing this is the cause.

So the workaround above seems likely to solve your problems because you are putting each call in a different queue to run inside Bitwig's interpreter.

Mike
Michael Schmalle
http://www.teotigraphix.com
Surfing on sine waves

Maschine4Bitwig - Studio, MK2, MikroMK2, MK1
http://www.teotigraphix.com/bitwig/maschine

Post

Thanks TeotiGraphix and everybody who's helped so far.

When i paste that code in above, my controller stops working and i get a syntax error. It's probably something really simple but i just don't have the skills to fix it. :-(

To be honest, i'm feeling quite despondent as i just can't seem to get my head around this whole javascript programming thing. (I learnt B.A.S.I.C when i was younger and loved that! it made sense lol) I'm also spending a lot of time on this and not actually making any music - which is what it's really about for me! :scared:

I would love to know how to program and i'm still going to learn - but i think it's going to take me months not days. And my needs with this controller are so simple, i just feel maybe i should swallow my pride and ask an expert to help.

Would anybody be willing to modify this Akai MPD226 script for me? and maybe talk me through what you did to it. I'm willing to pay. I just wanna be making some music :-)

Let me know, DM is fine too.

Thank you again

Post

Code: Select all

var yourBestWorkingDelayTime=15; //declare your global variable befor function init() 

funciton init(){

transport = host.createTransport();  //just paste in function init
application=host.createApplication();  

}

function onMidi(){ 

 //this belongs to onMidi function

if(data1==="your button CC" && data2===127){ //change "your buton CC"for actual buton CC WITHOUT quotes
transport.stop(); 
 Application.undo();
 host.scheduleTask(function()
{ transport.play();}
,null,yourBestWorkingDelayTime);}
                }
}

Regardless of your struggle I came with better solution
(after watching this video )

Code: Select all

var isTrigged =false; //global var

    application=host.createApplication(); //again in init function
    transport = host.createTransport(); 
    transport.addIsPlayingObserver(function(val){        
        if(!val && trigged){
            transport.play();
            isTrigged=false;
        }
    });

// below code paste in onMidi function
if(data1===CC&&data2===127){    // again change CC for zour button CC#
transport.stop();
application.undo();
isTrigged=true;}


Post

Kreczek wrote:

Code: Select all

var yourBestWorkingDelayTime=15; //declare your global variable befor function init() 

funciton init(){

transport = host.createTransport();  //just paste in function init
application=host.createApplication();  

}

function onMidi(){ 

 //this belongs to onMidi function

if(data1==="your button CC" && data2===127){ //change "your buton CC"for actual buton CC WITHOUT quotes
transport.stop(); 
 Application.undo();
 host.scheduleTask(function()
{ transport.play();}
,null,yourBestWorkingDelayTime);}
                }
}

Regardless of your struggle I came with better solution
(after watching this video )

Code: Select all

var isTrigged =false; //global var

    application=host.createApplication(); //again in init function
    transport = host.createTransport(); 
    transport.addIsPlayingObserver(function(val){        
        if(!val && trigged){
            transport.play();
            isTrigged=false;
        }
    });

// below code paste in onMidi function
if(data1===CC&&data2===127){    // again change CC for zour button CC#
transport.stop();
application.undo();
isTrigged=true;}

This just proves my async comment. :) Which is the way you do it in event based programming.

I think the scheduled task works fine for the simple use case, you start mixing flags like that all around, things get messy really quick.

Mike
Michael Schmalle
http://www.teotigraphix.com
Surfing on sine waves

Maschine4Bitwig - Studio, MK2, MikroMK2, MK1
http://www.teotigraphix.com/bitwig/maschine

Post

Cheers TeotoGraphix - i'll give that a try. One thing i need to ask before i do so, can you please explain how that "trigged" statement fits in? I mean, i'm just trying to follow the code and make sense of it in my small brain. I can see that there is a variable called "IsTrigged" but i can't see any other reference to "trigged" other than in your line "if(!val && trigged){" so it's throwing me off a little.

Also can you please explain what the ! symbol means before the val? and why two & symbols not just one?

I feel i'm on the verge of understanding this mad programming world but it's little things like this holding me back. but i will persevere :-)

Cheers!
Dale

Post

Code: Select all

if(!val && trigged)
Means if the value is FALSE(sequencer stopped) and the pad was pressed(to stop the sequencer), play the sequencer now.

Basically it's saying only play the sequencer when the pad was actually pressed. The reason for this is that Bitwig will send a false value when you press the play button in the DAW to stop the sequencer. So he is guarding against the fact that a false value can come from other events besides you pressing the pad to call stop().

! means NOT, so it will be true if value is NOT false, long hand would be (value != false).

&& Means logical AND, means BOTH statements to the right AND left must equal TRUE for the block below to execute. Long hand;

Code: Select all

if (value != false)
{
    if (isTriggered == true)
    {
        ... do this now
    }
}
PS He has a typo, triggered is supposed to be isTriggered, he didn't run this code. :)

Mike
Michael Schmalle
http://www.teotigraphix.com
Surfing on sine waves

Maschine4Bitwig - Studio, MK2, MikroMK2, MK1
http://www.teotigraphix.com/bitwig/maschine

Post Reply

Return to “Controller Scripting”