Subsections


Subroutines

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


DefCall

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:

Call

As discussed above, you execute a defined SUBROUTINE via the CALL command. There are three parts to this command:

  1. The keyword CALL,
  2. The subroutine name,
  3. A list of parameters to be passed. If there is more than one parameter you must use commas to separate them.

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:



Footnotes

... language.22.1
If you do solve the Towers of Hanoi using MMA subroutines, please let us know.
... music.22.2
In this case we are using the MMA primitive REPEAT/ENDREPEAT, but it could also be accomplished with a counter, LABEL and GOTO ... we'll leave that as an exercise for the reader.
Bob van der Poel 2015-12-15