MidicaPL Tutorial, Chapter 1: Basics

This is the first chapter of the MidicaPL tutorial, teaching the basics of the language. If you did not yet follow the preparation instructions, please do so before you continue reading.

At the end of this chapter you will be able to create melodies with notes, chords and rests using different instruments playing together. Moreover you will learn how to change the tempo of your music.

Whitespaces and Comments

Each line of the source code can either be empty or contains a command or a comment or both. Comments are prefixed by the symbol // and end at the end of the line. Empty lines and comments are ignored. Whitespaces at the beginning or end of a line are also ignored. More than one whitespace has the same effect as one single whitespace.

So the next two source code examples are equivalent.

MidicaPL
// define an instrument
INSTRUMENTS        // open block
	0	2	Piano
END                // close block

// define some chords
CHORD    c_maj     c  e  g
CHORD    d_maj     d  f# a

CHORD    f_maj     f  a  c
// end of chord definitions
MidicaPL
INSTRUMENTS
0 2 Piano
END
CHORD c_maj c e g
CHORD d_maj d f# a
CHORD f_maj f a c

Instrument Definition Block

Before you can play any sounds, you must define the instruments to be used by each channel. Every channel that will be used later must be initialized inside of a block beginning with INSTRUMENTS and ending with END.

The only exception is the percussion channel (channel 9) which may (but does not need to) be defined explicitly.

MidicaPL
INSTRUMENTS
	0	ELECTRIC_GRAND_PIANO	Piano
	1	VIOLIN					Fiddle
	2	32						Bass
	p	STANDARD				Standard Drumkit
END

Each line inside of this block contains 3 columns, separated by one or more whitespaces. The last column may also contain more whitespaces. These are not interpreted as separator but as a part of the content.

1st column

The first column contains the chanel number. Valid values are the numbers 0 - 15 and the symbol p.

p is just an alias for 9 which is the percussion channel number.

2nd column

The second column describes the instrument. It may contain a valid instrument ID or drumkit ID or the accoring MIDI program number.

Valid instrument or drumkit IDs can be found in the info window under Configuration

3rd column

The third column contains a description of the instrument. This will be displayed as a channel comment in the player.

In the above example we use an instrument ID for the channels 0 and 1, a MIDI program number for channel 2, and a drumkit ID for channel 9.

The line defining the percussion channel (p) is optional. If it is omitted, the standard drumkit (MIDI program number 0) is used.

Channel Commands (Compact)

After you have defined some channel instruments, you can use (compact) channel commands in order to play music. The most important things to do with channel commands is playing notes, chords or rests.

A compact channel command is a line beginning with the channel, followed by a :. The rest of the line can consist of notes, chords, rest and so on, being played on the channel.

The following example plays a C Major Scale in Channel 0:

MidicaPL
0: c d e f g a b -
Result (Score)

Instead of the last note, we defined a rest using the symbol -.

As long as we don't define a note length, a quarter note is assumed. This applies for rests as well. But we can add a length definition to a note or rest, separated with a :. This will be the new default length for the channel.

The following example plays the beginning of "Happy Birthday" in channel 0:

MidicaPL
0: c:8 c d:4 c f e:2
Result (Score)

c:8 plays a c with the length of an 8th note. At the same time it switches the default note length to an 8th note. So the next c (without note length) is still an 8th.

This command can also be split into several lines. But in this case every line needs to be opened with the channel number and a colon. Here is the same example, split into three lines:

MidicaPL
0: c:8
0: c d:4 c
0: f e:2
Result (Score)

In the first line we play only one note, and we switched the default note length to an 8th note. This new default is also valid for further lines of the same channel. So for the first note of the second line, we don't need a modifier to play another 8th.

You can add a dot to the note length in order to get a dotted note.

The following example shows a more accurate version of "Happy Birthday":

MidicaPL
0: c:8. c:16 d:4 c f e:2
Result (Score)

Note Names

Which note names are valid, depends on the configured note system, half tone symbol and octave naming. In the standard configuration, lower-cased international note names are used, and the half tone symbols are # for a sharp and b for a flat. Then follows an octave modifier.

The octave beginning with the middle C is not modified.

Higher octaves are modified with +, +2, +3 and so on.

Lower octaves are modified with -, -2, -3 and so on.

The following example shows the first bar of "Through the Never" by "Metallica", played in channel 1.

MidicaPL
1: e-2:8 f#-2 c#- f#-2
1: e-2   f#-2 c#- f#-2
Result (Score)

Double sharps (##) or double flats (bb) are also possible, like these:

  • f## (same as g)
  • f##+ (same as g+)
  • f##+2 (same as g+2)
  • dbb (same as c)
  • dbb+3 (same as c+3)
  • cbb+3 (same as bb+2 or a#+2)

Using multiple channels

Different channels can play notes at the same time. Each channel command appends a note (or something else) to the end of a channel. So the order of channel commands for the same channel is important. But the order of commands for different channels does not matter.

The following examples are equivalent. They play the first two bars of "Jingle Bells".

MidicaPL
0: e e e:2 e:4 e e:2
1: c-:2 g- c- g-
MidicaPL
1: c-:2 g- c- g-
0: e e e:2 e:4 e e:2
MidicaPL
1: c-:2
0: e
0: e e:2
1: g- c-
0: e:4 e e:2
1: g-
Result (Score)

The first example adds all notes to channel 0 before adding all notes to channel 1.

The second example begins with channel 1 and then handles channel 0.

The third example works more or less in the order of appearance of the notes in time. Of cause this is not always possible because some notes are played simultaniously but two channel commands cannot be written into the same line of source code.

In the third example you can also see that a note length switch applies only to the channel where it occurs. The e In the second line is still a 4th because the note switch in the first line applies only for channel 1 but not for channel 0.

Chords

A chord in MidicaPL is an amount of notes to be played at the same time in the same channel, with the same length and velocity. There are 2 types of chords: inline chords and predefined chords.

Inline Chords

An inline chord is a number of notes, separated by a ,. There are no whitespaces allowed between the notes.

The following example shows the beginning of Bob Marley's song "No Woman No Cry".

MidicaPL
1:  c,e,g:1  g-,b-,d     a-,c,e  f-,a-,c
0:  -:2  c+  b:4 c+ b a
Result (Score)

The piano is played in channel 1 using inline chords. The singer's voice is played in Channel 0 without chords.

Predefined Chords

In order to use a predefined chord, the chord must be defined somewhere. Usually a chord definition consists of 3 or more columns, separated by whitespaces.

The first column is the keyword CHORD. The second column is a self-given chord name. The other column(s) contain the notes belonging to that chord, one note by column. The notes can be separated either by , symbols or whitespaces or both.

Between the chord name and the notes, you may optionally add a = instead of (or as well as) whitespaces. The following examples are all similar chord definitions:

  • CHORD c-maj c e g
  • CHORD c-maj c,e,g
  • CHORD c-maj=c,e,g
  • CHORD c-maj = c, e, g
  • CHORD c-maj = c , e , g

Predefined chords can be used like normal notes inside of a channel command. But instead of the note name, the self-given chord name is used.

The following example shows the same notes again but this time with predefined chords instead of inline chords.

MidicaPL
CHORD c-maj c, e, g
CHORD g-maj g-,b-,d
CHORD a-min a- c  e

1:  c-maj:1 g-maj a-min f-maj
0:  -:2 c+  b:4 c+ b a

CHORD f-maj f- a- c
Result (Score)

As you can see in this example, the chord doesn't need to be defined before using it. It can also be defined later, like the f-maj chord here.

Imagine you use the same chord (e.g. C-major) many times in a song. And then you want to modify the chord (e.g. transform it into C-maj-7). With predefined chords you only need to change the chord definition while with inline chords you need to change every appearance.

Global Commands

While channel commands only affect one channel, there are also global commands that affect more than one channel. Most of them even affect all channels. A global command begins with the symbol * in it's first column.

Synchronize

Every global command syncronizes all (or at least some) channels. That means the current channel lengths are made equal to the furthest channel's length. A global command adds an according amount of rests to all other channels. So many that all synchronized channels have the same length as the furthest channel.

This behaviour can be very helpful. So even a global command without any further options can be useful. This empty form of a global command is called synchronize command because it's only purpose is to synchronize all channels.

The following example shows the first 2 measures of "The Black Perl" by "Klaus Badelt" from the film "Pirates of the Carribean: The Curse of the Black Perl".

MidicaPL
1: d-:8
0: d:8 - d eb d eb
*
1: d-
0: d   - d eb d eb
*
Result (Score)

Channel 1 contains a lot of rests but none of them is written with a channel command. The rests are added implicitely by adding a synchronize command at the end of each bar.

Partial Synchronize

If you want to synchronize only a part of the channels, you can use a partial synchronize command. In the second column of a partial synchronzie there is a description which channels should be synchronized.

This description can be a comma-separated list of channel numbers (e.g. 1,2,3) or a range like 1-3) or a mix like 1-3,5,6-8,11. Whitespaces are forbidden inside of the channel description.

You can use the symbol p for channel 9 here as well.

MidicaPL
*	1-3,5,p,12-14

This example synchronizes channels 1, 2, 3, 5, 9, 12, 13 and 14 with each other.

The partial synchronize is the only global command that synchronizes only a part of the channels. All other types of global commands always synchronize all channels.

Set Tempo

Another important global command is a tempo change. The tempo is defined in "beats per minute" (BPM). The second column of the global command contains the symbol tempo and the third column the desired value.

The value is the number of quarter notes that is played in one minute. The default value is 120. It could be changed to 150 using the following command:

MidicaPL
*  tempo  150

Like every other global command, a tempo change synchronizes all channels.

The following global commands ("time signature" and "key signature") are not audible. They only add meta information to the MIDI sequence. If you are only interested in hearable commands, you can continue directly with chapter 2.

Set Time Signature

The time signature can be set with the time command in the second column. The third column contains the desired time definition.

The time definition contains a nominator (number) and a denominator, separated by a /.
The MIDI default is a 4/4 beat.
A 3/4 beat would be defined like this:

MidicaPL
*	time	3/4

The denominator must be a number that can be described as 2n. That means valid denominators are 1, 2, 4, 8, 16, 32, etc.

The time signature does not change the sound of the MIDI sequence at all. However it can make sence to define it anyway. It can be a useful hint for third-party software processing the MIDI file exported by Midica.

Set Key Signature

The key signature can be set with the key command in the second column. The third column contains the desired key definition.

The key definition contains a valid note name and a tonality, separated by a /.
The tonality can be maj for major or min for minor.
The MIDI default is C major, which could also be defined explicitely by the following command:

MidicaPL
*	key   c/maj

What a valid note name is, depends on the configured Note System, Half Tone Symbol and Octave Naming. In the standard configuration a C# minor could be set with one of the following commands.

MidicaPL
*	key   c#/min
MidicaPL
*	key   c#-2/min
MidicaPL
*	key   c#+4/min

Of cause these commands are equal because the octave is irrelevant for the key signature.

Like the time signature, the key signature does not change the sound at all. But it can also be useful for another software processing the produced MIDI sequence.

Internally the key signature is translated into a number of sharps or flats and a flag for major or minor. Midica tries to be as close as possible to the intended key signature. But MIDI has a limitation that allows a maximum of 7 sharps or flats. So in some cases the key signature is converted automatically to something corresponding.

For example a D# major would have 9 sharps which is more than the allowed 7. So it's converted to the corresponding Eb major with 3 flats instead.