Thinking out loud: a scripting language for Cantabile

That’s excellent!!!

One thing I wonder about, since it’s compiling to real C and executing it. If this eventually makes it into Cantabile, will it be possible to protect the Cantabile session from crashes in any way?

2 Likes

One small step for a Brad, one giant leap for Cantabile users, I hope. :slightly_smiling_face:
I know, it’s not a original thought, but I really like this Hello World.

1 Like

Only in so much as the language itself would be “safe”: bounds checking on arrays, no direct pointer references, support for exceptions etc…

1 Like

Maybe a dumb question, but what is this all meant to do? Can anyone please give me an example?

There are no dumb questions, but this requires some background and forward thinking…

The idea behind all of this is to provide the ability to do user scripting in Cantabile - both in the audio engine (eg: MIDI processing) and in general (app level control like load a song, switch states etc…). The whole idea started because support for binding expressions were so well received, but also so limited (only supports expressions, no flow control and can’t run on the audio thread).

I got to thinking about what it would take to add a more capable scripting language but wanted some feedback on whether it would useful and what it would be used for - hence the reason I posted this topic in the first place and you can read back through the replies to see some interesting suggestions.

But before I can add scripting, I need a scripting language. But for it to run on the audio thread, there are some very strict requirements so it can run without stalling and causing glitches. This makes me very wary of using an existing language - either because they use garbage collectors that are known to stall, or because they’re loosely typed which makes them slower, or because they’re just too unknown, or because I just don’t like the language, or because I have “not invented here syndrome”.

So I decided to do a little proof-of-concept for a language that:

  • Has well controlled memory management. In this case it has a garbage collector but is designed to be very incremental so as to not cause stalls. It also supports plugging in a heap allocator so it can use Cantabile’s non-blocking heap to run on the audio thread
  • Strongly typed - for performance reasons
  • Compiled to machine code - again for performance reasons
  • Is strictly single threaded, but only on a per-script basis - for simplicity
  • Is very focused on scripting - ie: designed for small automation and processing tasks, not for building entire applications, has top-level statements and minimal to no “plumbing” code.
  • Is modern and clean - I’m modelling it very closely on C#.

And that’s all this is… a proof-of-concept language to see if the above is possible.

So far it certainly looks possible - I’ve built a tiny language that will meet all of the above but is so far very limited and barely does anything.

It’s also probably too much work to be worth it - but I’m continuing to play with it mostly because I find it interesting but also because it might pay off in the long run. For now, don’t expect this to see the light of day but I might continue to ramble on about it (although I think I’ll shift the discussion from Cantabile forum to the Topten Software blog).

So far, I’ve treated this as a holiday period project but will probably move it to a side project as I don’t want it to interfere with on-going Cantabile development once I switch back into work mode.

Also, in the meantime I hit on the idea of using C for the audio thread scripting - that is much more likely to happen.

3 Likes

Thanks. All good. Just thought it worth asking as I don’t understand the uses for this level of configurability.

For myself… I grew up with BASIC and COBOL. C remains baffling to me, so I doubt I’ll be dabbling! But never say never…

I think that regardless of how straightforward the resulting language is, it is likely to remain something only a small portion of users write scripts for. That would suggest to me another requirement worth considering - ease of sharing of scripts. That way a broader group of people can benefit from the shared work of those who delve into the coding. So the ability to pass small text files around holding scripts, and for them to be as minimally tied to a person’s particular setup as possible, such as keeping them agnostic to things like port names.

6 Likes

Hi @Neil_Durant,

This is a good point. My thoughts here were to not store the script content in the song/rack files directly. But rather have a directory of scripts, that are referenced from the songs. I guess similar to how you add a plugin, you could add a script. Something like that…

It’s a long way off yet, but definitely worth thinking about.

Brad

2 Likes

For those interested in following along with the development of this (it’ll be a side project to Cantabile) I’m moving the discussion to the Topten Software Blog where I’ll be publishing a new article about it each week - second one coming out tomorrow.

Please feel free to comment if so inclined (you’ll need to subscribe to a free member account to leave comments).

2 Likes

Just one thought/question from me. Where in Cantabile will we be able to use this scripting language?

I am asking as it occurred to me it would be good to be able to script your own custom MIDI filters in MIDI routes, but cannot recollect that being discussed as an option

Too early to say all the places where scripting would be available. What I want to avoid if I can is different languages in different places. So I’m focusing on building a language that can be used on the audio thread but is also nice to use for higher level app automation type stuff.

MIDI scripting was discussed in the context of a midi processor script, which is similar to midi filter but not exactly the same. Scripted midi filter definitely makes sense though.

1 Like

Agreed that a consistent language would be good

1 Like

Sounds great!

2 Likes

I have often built racks in Cantabile to handle midi controllers. Largely this has worked well but I have always come across the same issue which is the lack of user variables. If you need to have Cantabile “remember” things it can be difficult. I have used rack states to remember foot switch states for example and more recently I have used rack output gain to remember fader positions. For example, I have a 16 channel mackie controller and use Cantabile to control the midi between that and Cubase. I have built racks in Cantabile to switch between using the faders as track volume or track CC faders. I needed to remember fader positions when switching between these functions. User variables would be a better solution. I would assume a scripting language may offer that?

Hi Alan,

Thanks for the feedback. User variables is something that I’m considering adding regardless of a scripting language.

Brad

2 Likes

Yesssss! This will come in handy in so many scenarios…

1 Like

Yay - so useful, then I can get rid of all the ReaJS stuff. Will there be both local and global variables? E.g. like @x is local just for that expression, #x is global to the song (dies at loading a new song), ##x exists for the duration of the cantabile session.

I was thinking along the lines of:

  • each rack/song could have a set of variables - probably edited in a popup dialog.
  • each would have a name, probably some data type configuration (range, int/float, bool, string etc), a default value, etc…
  • variables would be available as both source and target binding points.
  • variables on a song would also be available as string replacement $(variable).
  • variables on a rack might be available as $(rackname.variable) replacement variables (not sure about this)
  • current values would be saved when the song/rack is saved.
  • global variables could be implemented using the background rack.

Also, I was thinking about binding expression variables. I could probably add:

Useful? Thoughts?

Brad

5 Likes

Sounds promising. I like the idea about defining variables in a pop-up or as part of the property window. Nice with strong typing, and maybe also a default value? Potentially mandatory, to avoid uninitialized variables (would be difficult to debug, I’d expect)

Also being able to use them as source/target as well as in expressions sounds like a very simple yet very flexible and powerful setup.

I’m curious about how the variables would be named. Would they bet set by Cantabile or user namable? Also I assume there would be a means to clear or set rack variables on song unload?