I truly hate to admit this, but I just don’t get programming languages. Over a dozen times I’ve tried to explore GP scripting to solve problems that seem easy accomplishable, only to be stymied by my inability to structure them. The scripting manual, well organized as it is, starts to lose me at basic concepts. I stare blankly at code templates in the editor and fear my brain may not be wired for this. The code compiler already knows I’m an idiot. Would anyone good at scripting be willing to help to walk me through a couple of scenarios? Perhaps we could barter for some sound design work, which comes far more easily to me. Thanks in advance!
Hi Baritone, maybe I can help you.
Can you explain, what you want to be coded?
Why do you hate to admit it? Everyone has different strengths. GPScript is an advanced platform mostly intended to allow us to experiment with ideas that may ultimately get implemented directly in GP for musicians who have no interest in programming, which, by the way, is the vast majority of our userbase!
Thanks for your kind offer. What I’d like to do is trigger the Audio File Player with a MIDI key to play the audio in Lane 1 from the beginning. Then with each subsequent key press, I want the player to simultaneously advance to the next lane and play its file from the beginning. Does this sound like a fairly easy script to create?
I hate to admit it because I can clearly see its potential for elevating live performance capabilities and that’s intriguing enough for me to keep coming back to it even though I haven’t been able to grasp it. Count me among your vast majority!
here is a small gig with Audioplayer.
just load your files in the first 4 lanes and press C1 on your Midi Controller.
It is not perfect, quick&dirty - but it should run.
AudioPlayer.gig (10.0 KB)
Here is a better script:
//$<AutoDeclare> // DO NOT EDIT THIS SECTION MANUALLY Var MIN : MidiInBlock LANE1 : Widget LANE2 : Widget LANE3 : Widget LANE4 : Widget PLAY : Widget lane_playing : integer LANE : Widget Array //$</AutoDeclare> initialization lane_playing = 0 LANE = [ LANE1, LANE2, LANE3, LANE4 ] end on NoteOnEvent (m : NoteMessage) matching C1 from MIN SetWidgetValue(LANE[lane_playing],1.0) lane_playing = lane_playing + 1 SetWidgetValue(PLAY, 1.0) if lane_playing == 4 then lane_playing = 0; end end on Activate lane_playing = 0 SetWidgetValue(PLAY, 0.0) end
pianopaul, this is awesome! It’s just what I was trying to accomplish. Thank you very much! Am able to understand that if I want more lanes, I simply add them to the array definition. If so, does the integer in the line “if lane_playing ==4” need to be changed as well?
But you have to add the Widgets also and name it correctly and map it to the lanes.
Actually, you can get rid of the lines
if lane_playing == 4 then lane_playing = 0; end
Instead, just change the earlier line
lane_playing = lane_playing + 1
lane_playing = (lane_playing + 1) % Size(LANE)
Now, all you have to do is add the new LANE number to the array.
This works very well too. Thanks, dhj!
In case you were wondering, that “%” operator means modulo arithmetic, often called clock arithmetic (if you 3 to 10 you get 1 (10 o’clock + 3 hours is 1 o’clock, because there are 12 hours in a clock, hence modulo 12)
So if you have 5 lanes ( i.e, the Size of the LANE is 5) then you will only get values 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4 …which represent the array indices which go from 1 to 4. That’s why it’s not necessary to do the separate test for the lane.
here’s the beginnings of a really simple MIDI note re-assigner I built recently, it re-assigns the notes D3 and E3 to C3 (there’s a reason for this, believe it or not):
// Declare a global variable
var uTonal : MidiInBlock //uTonal is a named block in Gig Performer
//Callback when a note event (on or off) is received
On NoteEvent (m : NoteMessage) matching D3 From uTonal
//SendNow(uTonal, m) // Send the note to the uTonal MidiIn block
SendNow(uTonal, Transpose(m, -2)) // Also send a transposed note
On NoteEvent (m : NoteMessage) matching E3 From uTonal
//SendNow(uTonal, m) // Send the note to the uTonal MidiIn block
SendNow(uTonal, Transpose(m, -4)) // Also send a transposed note
A couple of things—by using NoteMessage, GP will respond to both Note On and Note Off messages from the keys to be reassigned, you don’t need a separate script for ons and offs . The callback reassigns the note by transposition using the function SendNow, this routes the MIDI note back to the MIDI in block (I’ve labelled this uTonal). There’s also a Transpose function invoked, this is nested into the SendNote function, and carries out the appropriate transposition for each note.
@CFB4 Hey, thanks so much for providing this example, it’s really appreciated. I hope you don’t mind my making a suggestion which will also show a little more GPScript technique.
First of all, anybody using this will need to make sure that they have given their MidiIn block a script handle called uTonal to match the declaration.
Second, you can combine those two callbacks into a single callback as follows:\
On NoteEvent (m : NoteMessage) matching D3, E3 From uTonal SendNow(uTonal, MakeNoteMessage(C3, GetVelocity(m))) End
In particular, a note event callback can match several incoming values, so here, we’re matching D3 and E3
Finally, since you always want a C3, you don’t need to do a transpose of the incoming value, you can just hardcode C3 as the note number and then match whatever velocity was used for the incoming note.
Keep 'em coming.
Nice entry in the fabulous world of GP script. No doubt there is a reason for your script, I believe it. But, I am still interested in the use case. A too small hand or a missing thumb to reach the C3 key when playing a tricky chord ?
Thanks DHJ, that’s elegant for sure! This is my first working GP script, though I have experience with Csound and KSP (Native Instruments).
The C3 exams was just a test, the script will remap a bunch of MIDI notes to different note values
It’s for a keyboard that plays Bohlen-Pierce scales—i made 2; one for Delta mode and one for Lambda mode.
At the time, I had no funding, so I hacked a couple of Roland (Bohland) keyboards to create a suitable layout. They’re wonky and a bit wack, but actually work quite well for performance and composition. Since some of the MIDI notes are unused, they need to be reassigned, at the time I was using Pure Data for the reassignment and synthesis.
I decided to switch to a standard soft synth and thought I’d try using GP scripts as the ‘reassigner’ and, perhaps, for the tuning implementation. The latter involves retuning with pitchbend, so that’s another day’s scripting
I’d love to be able to use microtonal and xenharmonic scales with some of my favourite soft synths like the ME80 and the Waldorf NAVE
This is great, CFB4. I can almost follow along and with every example, things get a tiny bit clearer. Djh, thanks for your efficiency tips, GPScript’s plethora of functions is a lot to wade through and this is helpful at finding the right tool for the job.
I didn’t even know that the Bohlen-Pierce scales exist