MMA supports primitive subroutines as part of its language. The format and usage is deliberately simple and limited ...we're really not trying to make MMA into a functional programming language.22.1
Before you can use a subroutine you need to create it. Pretty simple to do. First, here is a subroutine which does not have any parameters:
defCall MyCopyright
print Adding copyright to song MidiCopyright (C) Bob van der Poel 2014 endDefCall |
Note that the subroutine definition starts with DEFCALL and is terminated by ENDDEFCALL or DEFCALLEND. The name of the subroutine and any parameters must be on the same line as DEFCALL and ENDDEFCALL must be on a line by itself. The body of the subroutine can contain any valid MMA command or chord data (including other DEFCALL and CALL commands).
Subroutines must be defined before they can be used. This can be done in the main song file, or in a different file you have included (including library files).
So, now you can insert a copyright message into your midi file just by calling the subroutine:
Call MyCopyright |
Of course, you'll be using the same message every time ... so, let's make it a bit more useful be including a parameter:
defCall Copyright Name
print Adding copyright to song: $Name MidiCopyright $Name endDefCall |
Note that we have a parameter to the subroutine with the name ``Name''. In the body of the subroutine we reference this using the name $Name. In this case, to assign copyright to ``Treble Music'' we'd use:
Copyright (c) 2020 Treble Music |
If you need to pass more than one parameter, separate each one using a single comma. Let's assume that you find that you have a large number of 2 measure chord repetitions in your song and you are tired of typing:
Am / Gm
Edim / Gm Am / Gm Edim / Gm ... |
You could define a subroutine for this:
DefCall 2Bars C1 , C2 , Count
Repeat $C1 $C2 RepeatEnd $Count |
And call it with:
Call 2bars Am / Gm , Edim / Gm , 7 |
to generate a total of 14 bars of music.22.2 If you doubt that this is working, call MMA with the -r option (see here).
Some points to remember:
As discussed above, you execute a defined SUBROUTINE via the CALL command. There are three parts to this command:
If you wish to have a literal comma in a parameter you must escape it by prefacing it with a single backslash. So,
Call Prt My, what a nice song |
will pass two parameters (``My'' and ``what a nice song'') to the subroutine ``Prt''.
On the other hand:
Call Prt My what a nice song |
passes only one parameter (``My, what a nice song'').
Notes: