MidicaPL Tutorial, Chapter 5: Tweaking

This is the fifth chapter of the MidicaPL tutorial. Please read chapters 1, 2, 3 and 4 first, if you have not yet done that.

In this chapter you will learn about Meta information and redefining the Programming language itself. Besides that you will learn about further techniques of re-using code like Constants and file includes.

Meta Information

A MIDI sequence can contain meta information that does not have any effect to the produced sound. In MidicaPL a part of this meta information is implemented with global commands, as you have already learned in chapter 1. This applies to meta information like key signature or time signature that can occur more than once at different time spots within the sequence.

Other parts of meta information refer to the whole sequence. These parts are included in a META block, beginning with the keyword META and ending with END.

Inside a META block you can use any field from the Meta Fields table. Each line must begin with a field name, followed by whitespaces and a value.

Meta Fields
Field Meaning
copyright Copyright or legal information
title Song title
composer Composer(s) of the song
lyrics Name of the lyricist(s)
artist Performing musician(s), band or orchestra
MidicaPL
META
	copyright  (c) by our garage band
	title      Our first number one song
	composer   John Doe, Susi Smith
	lyrics     Susi Smith, Richard Roe
	artist     John Doe, Richard Roe, Susi Smith
END
Result (Fields)
Field Value
copyright (c) by our garage band
title Our first number one song
composer John Doe, Susi Smith
lyrics Susi Smith, Richard Roe
artist John Doe, Richard Roe, Susi Smith

If more than one line is needed, the same field must be defined once for each line.

MidicaPL
META
	copyright  (c) by our garage band
	title      Our first number one song
	composer   John Doe
	composer   Susi Smith
	lyrics     Susi Smith
	lyrics     Richard Roe
	artist     John Doe
	artist     Richard Roe
	artist     Susi Smith
END
Result (Fields)
Field Value
copyright (c) by our garage band
title Our first number one song
composer John Doe
Susi Smith
lyrics Susi Smith
Richard Roe
artist John Doe
Richard Roe
Susi Smith

Soft Karaoke

You already know how to create karaoke files. The method we learned so far produces MIDI Karaoke in the officially recommended format. But unfortunately this format is rarely used. Most MIDI files with lyrics use a format called Soft Karaoke.

Soft Karaoke supports some more meta fields than the official standard. In the lyrics it uses some special characters for special purposes.

You can find the Soft Karaoke fields in the Soft Karaoke table.

In order to use Soft Karaoke, you have to define a block inside of the meta block. This inner block starts with SOFT_KARAOKE and ends with END. Inside this block you can define the Soft Karaoke specific meta fields.

Soft Karaoke
Field Meaning
version Format version (e.g. 0100)
language Language of the lyrics.
title Title of the song
author Author of the MIDI file or song
copyright Copyright or further information
info Additional information (may appear multiple times)

The following example shows a complete META block including a nested SOFT_KARAOKE block:

MidicaPL
META
	copyright  (c) by our garage band
	title      Our first number one song
	composer   John Doe
	composer   Susi Smith
	lyrics     Susi Smith
	lyrics     Richard Roe
	artist     John Doe
	artist     Richard Roe
	artist     Susi Smith
	
	SOFT_KARAOKE
		version     0100
		language    ENGL
		title       Our first number one song
		author      John Doe, Susi Smith
		copyright   (c) by our garage band
		info        This is our first song,
		info        that will make us famous.
	END
END
Result (Fields)
Regular Field Value
copyright (c) by our garage band
title Our first number one song
composer John Doe
Susi Smith
lyrics Susi Smith
Richard Roe
artist John Doe
Richard Roe
Susi Smith
Soft Karaoke Field Value
version 1.00
language English
title Our first number one song
author John Doe, Susi Smith
copyright (c) by our garage band
info This is our first song,
that will make us famous.

So you can see how regular meta fields and Soft Karaoke fields can be mixed. Some fields need a bit more explanation:

  • version is available in MidicaPL only for completeness reasons. Actually using it does not make much sense.
  • For the language field, ENGL is the only specified language identifier (meaning english). For other languages you could use your own abbreviation or write out the full language name but this is not specified. However most authors write the language name or abbreviation in upper-case. E.g. FREN for the french language, or CHINESE.
  • title and copyright exist in both formats (regular and Soft Karaoke). This makes them redundant.
  • info is the only Soft Karaoke related meta field that you can use more than once. The other fields may appear only once and so each of these fields can only contain one single line. That's why in the author field the two authors are separated with a comma instead of a new line (like in composer).

Lyrics in Soft Karaoke

If you use Soft Karaoke, there are certain rules and special characters for the syllables:

  • The special characters for a space _ or a comma \c are still valid, like in the regular karaoke format.
  • However the characters for a carriage return \r or line feed \n are forbidden.
  • A new paragraph is added using a \ character at the beginning of the syllable.
  • A new line is added using a / character at the beginning of the syllable.

The meaning of \ is clearing the screen before adding the next lines (starting with the current syllable). However in the Midica Player it only has the same effect as two line breaks.

There are some more rules Midica doesn't care about. But if you want to produce a Soft Karaoke file and process it with a different software later on, you should care about them:

  • The very first syllable in the song should begin with a \.
  • One paragraph should not have more than 3 lines. That means: Between two syllables beginning with \ there should be no more than two syllables beginning with /.
  • Spaces (_) should not be placed at the end of a word's last syllable but at the beginning of the next word's first syllable.

The following examples produce the same notes and lyrics. But the first one uses Soft Karaoke while the second one uses the standard format:

MidicaPL
META
	SOFT_KARAOKE
	END
END

0  c  /8.  lyrics=\Hap
0  c  /16  l=py
0  d  /4   l=_birth
0  c  /4   l=day
0  f  /4   l=_to
0  e  /2   l=_you\c

0  c  /8.  l=/Hap
0  c  /16  l=py
0  d  /4   l=_birth
0  c  /4   l=day
0  g  /4   l=_to
0  f  /2   l=_you.

0  c  /8.  l=\Hap
0  c  /16  l=py...
MidicaPL
0  c  /8.  lyrics=Hap
0  c  /16  l=py_
0  d  /4   l=birth
0  c  /4   l=day_
0  f  /4   l=to_
0  e  /2   l=you\c\r

0  c  /8.  l=hap
0  c  /16  l=py_
0  d  /4   l=birth
0  c  /4   l=day_
0  g  /4   l=to_
0  f  /2   l=you.\n

0  c  /8.  l=Hap
0  c  /16  l=py...
Result (Score)
Result (Screenshot)

As you can see, the SOFT_KARAOKE block only needs to exist in order to use this format. But all fields are optional. In this example the block is completely empty.

Constants

In chapter 3 you learned how to re-use an arbitrary number of commmands by using functions. But sometimes you may want to re-use very small parts of code ‐ even smaller than a whole command. In this case constants can get useful.

A constant looks like a variable. In the definition you just replace the keyword VAR by CONST.

So the definition consists of the following parts:

  • CONST (the constant definition command)
  • The constant name, beginning with a $ symbol
  • An optional = symbol. (If ommitted, whitespaces must be used instead. Otherwise whitespaces may be used anyway.)
  • The value of the constant.

The constant name must begin with a $ but apart from that it must only contain alphanumeric characters or underscores.

The value of a constant can be any part of another command, or even a whole command line. In order to use it, you just write the constant name to the right place. The following three examples are equivalent:

MidicaPL
CONST $legato  = d=100%
CONST $staccato=d=50%
CONST $piano   = v = 30
CONST $forte     v  120
CONST $play_a  = 0 a /4

0  c  /4  $piano, $legato
0  d  /4
0  e  /4  $forte
0  f  /4  
0  g  /4  m, $staccato, q=2
$play_a
MidicaPL
0  c  /4  v = 30, d=100%
0  d  /4
0  e  /4  v  120
0  f  /4  
0  g  /4  m, d=50%, q=2
0  a  /4
MidicaPL
0  c  /4  $piano, $legato
0  d  /4
0  e  /4  $forte
0  f  /4  
0  g  /4  m, $staccato, q=2
$play_a

CONST $legato  = d=100%
CONST $staccato=d=50%
CONST $piano   = v = 30
CONST $forte     v  120
CONST $play_a  = 0 a /4

The first example first defines the constants and then uses them.

The second example shows like the same source would look like, if no constants were used.

The third example first uses the constants and defines them later. This is possible because the Midica parser interprets constant definitions before channel or global commands.

Constants themselves can also consist of other constants. In this case the inner constant must be defined before the outer constant. The following two examples are equivalent.

MidicaPL
CONST $forte    = v=120
CONST $drum     = bd1,to
CONST $drumroll = $drum /1 tr=/32
CONST $play_dr  = p $drumroll, $forte

$play_dr
MidicaPL
p  bd1,to  /1  tr=/32, v=120

The first example first defines the simple constants $forte (a velocity option) and $drum (two percussion instruments: a basedrum and an open triangle).

Then it defines $drumroll which contains the percussion instruments from $drum, a note length and a tremolo option.

$play_dr combines the constants from above to a channel command, to be played in channel 9.

The last line finally executes this combined channel command.

Constants and Variables

At first glance, a constant looks pretty similar to a variable. However there are some important differences:

  • The constant definition key word is CONST instead of VAR.
  • A constant can be defined only once. The same constant name cannot be redefined any more.
  • Constants can be defined after using them - just like functions that can be called before their definition.
  • Most limitations for varibales don't apply for constants. E.g. their values may contain whitespaces. So they can cover several parts of a command.

Redefinitions

The commands and other syntax symbols can be configured to be lower-, mixed- or upper-cased. But maybe you are completely unhappy with the used keywords and symbols. In this case you can redefine a syntax element with the DEFINE command.

Each syntax element has an ID which can be found in the Syntax table. You can see the table after clicking Info & Configuration Details > Configuration > Syntax. Or in this Screenshot.


The DEFINE command needs the ID of the syntax element to be redefined as the first argument. The new value must be provided as the second argument.

The following three examples are equivalent. The first and the last one redefine the symbols for nestable blocks to be ( and ) instead of { and }:

MidicaPL
DEFINE BLOCK_OPEN  (
DEFINE BLOCK_CLOSE )

( q=2
	0  c  /4
)
MidicaPL
{ q=2
	0  c  /4
}
MidicaPL
( q=2
	0  c  /4
)

DEFINE BLOCK_OPEN  (
DEFINE BLOCK_CLOSE )

As you can see in the third example, redefinitions can be written after using them. This is possible because Midica parses DEFINE commands before everything else.

The DEFINE command itself can also be redefined. In this case the order of redefinition commands is important, as the following example demonstrates:

MidicaPL
DEFINE FUNCTION    function[
DEFINE DEFINE      def
def    INSTRUMENTS instr[
def    END         ]
def    REST        %
def    CALL        invoke

instr[
	0  VIOLIN  Fiddle
]

function[ play-c-d-e
	0  c  /4
	0  %  /4
	0  d  /4
	0  %  /4
	0  e  /4
	0  %  /4
]
invoke  play-c-d-e  q=2

The DEFINE command is redefined to def. From this moment on, the new version def can be used for further redefinitions.

In this example we redefine the commands FUNCTION, DEFINE, INSTRUMENTS, END, - (for a rest) and CALL.

Of cause the new keyword function[ must not contain a whitespace. The same applies for instr[.

With these changes, we also need to rewrite the INSTRUMENTS block. This is necessary because the old commands INSTRUMENTS and END don't exist any more.

Limits of Redefinitions

Some redefinitions do not work together. For example the end of a definition block must have a different symbol than the end of an anonymous block. So you cannot change } and END to the same value. There are more syntax elements that may not have the same keyword while for others it's ok. Some elements even have the same keyword by default. It's not possible to list all possibilities here. Just be careful with redefinitions and try to avoid conflicts. Or just try out if it works.

You also have to make sure that your redefinitions don't conflict with other elements like note names or percussion instruments. For example if you redefine the comment symbol to become # instead of //, you must configure your Half Tone Symbol accordingly. The default half tone symbol can contain a # inside of a note name. So this combination won't work.


The following three syntax elements can still be used in their original form after being redefined:

  • COMMENT
  • DEFINE
  • INCLUDE
That means you cannot redefine another command to become one of these three keywords. It also means that after redefining one of these three commands, you may use either the old keyword or the new one. The following example demonstrates this:
MidicaPL
// Here we may use the old comment symbol...
;  ... or the new one, because this is...
;  ... parsed AFTER the redefinitions.
// But during the DEFINE commands,...
;  ...this is different:

DEFINE CHORD   crd    // must use DEFINE and //
DEFINE DEFINE  def    // must use DEFINE and //
def    REST    %      // may use DEFINE or def...
DEFINE GLOBAL  glob   // ...but still must use //
def    COMMENT ;      // must still use //
def    CALL    invoke ;  now we may use ; or //
def    TEMPO   bpm    // both is ok

0 c /4  // may use ; or // for comments
0 % /4  ;  but must use % for rests

// must use the original symbol for file
;  inclusions
INCLUDE  includefile1.midica

DEFINE INCLUDE incl

// now we may use both versions.
INCLUDE  includefile2.midica
incl     includefile3.midica

File Includes

Program languages allow to re-use code from other files - modules or libraries. The same is possible in MidicaPL. In order to include a file, you need the INCLUDE command. The only argument is the path to the included file. The file path can be absolute or relative to the file that contains the INCLUDE command.

Imagine, you are programming music for a latino band and in their repertoire they have music like Salsa, Bachata, Merengue and so on. Then you could create one include file for each category of music. The following example shows a possible include file for Salsa songs. The first example is the include file, and the second file includes and uses the first file.

MidicaPL
SOUNDFONT ../soundfonts/latino-soundfont.sf2

INSTRUMENTS
	0   LEAD_VOICE             Inés
	1   BRIGHT_ACOUSTIC_PIANO  Juan
	2   TROMBONE               Miguel
	3   TROMBONE               Ramón
	4   TROMBONE               José
	5   TRUMPET                Alejandro
	6   TRUMPET                Diego
	7   TRUMPET                Álvaro
	8   E_BASS_FINGER          Jorge
END

FUNCTION  clave
	p  -    /4
	p  cla  /4   q=2
	p  -    /4
	p  cla  /4.  q=2
	p  cla  /4
END
MidicaPL
INCLUDE  salsa.midica
* tempo 190

CALL clave q=100, m

2  c  /4
2  b  /8
2  f# /8
// and so on ...

The first file includes a soundfont that's specialized in Latin music (or maybe even more specialized in Salsa). Then follows the INSTRUMENTS block that can be quite large in a Salsa band. The function clave defines the clave rhythm that's very typical for Salsa.

The second file uses these definitions to create a song.

An included file can also be used for syntax redefinitions or to create constants you often use. The following example shows two include files for Bachata songs of your latino band:

MidicaPL
// definitions.midica

DEFINE SOUNDFONT   sf
DEFINE INSTRUMENTS instr
DEFINE FUNCTION    procedure
DEFINE END         end
DEFINE CALL        invoke

CONST $forte    = v=110
CONST $piano    = v=40
CONST $legato   = d=100%
CONST $staccato = d=30%
MidicaPL
// bachata.midica

INCLUDE definitions.midica
sf /path/to/sounds/bachata.sf2

instr
	0   LEAD_VOICE    Alejandro
	1   STEEL_GUITAR  Juan
	8   E_BASS_FINGER Jorge
end

procedure  bongo
	p  bh  /4  $forte
	p  bh  /4
	p  bh  /4
	p  bl  /4
end
MidicaPL
// my-bachata-song.midica

INCLUDE bachata.midica

invoke  bongo  q=8, m

8  f-2  /4.  $forte
8  f-2  /8
8  c-2  /4
8  e-2  /4
// and so on ...

The first file redefines some syntax elements and creates a few constants.

The second file uses these definitions to create the instruments for Bachata as well as the typical bongo rhythm that's used in most Bachata songs. As you can see, Juan switches from the piano to the guitar. And Alejandro is the now singing because the voice part in Bachata songs is typically a male part.

The third file uses the definitions from the first and second file. Note that it only includes the file bachata.midica directly but not definitions.midica. However the latter one is included by bachata.midica so it can be used in the third file as well.