This page is being rewritting for Solfege 3.0. Don't translate it before this message has been removed.

Lesson files

In GNU Solfege, each exercise is created by a lesson file interpreted by one of the exercise modules:

melodicintervals
Train one or more melodic intervals.
harmonicintervals
Train harmonic intervals.
singinterval
singinterval is an exercise where the program display a interval and plays the first tone. Then the user should sing the interval, and then click a button to hear the correct answer. No microphone support yet.
idbyname
idbyname is a very generic exercise. In its most basic form, the program play some sound, and you have to select among several buttons that it some way represents the music.
chord
The chord module act as a specialized idbyname module. The difference is that with the chord module you can write lesson files where the user should tell what inversion the chord is in, and what the top tone is.
chordvoicing
A two-step exercise. First you should identify the chord. Then you should stack the tones in the chord in the correct order.
compareintervals
Solfege plays two intervals, and you should say which one is largest.
rhythm
A simple rhythm exercise. Solfege will randomly generate rhythm patterns that the user should recreate by clicking on buttons.

You can read the page lesson file tutorial for step by step tutorial.

In a standard install, Solfege will look for lesson files in two places:

If you create your own lesson files, you should save them in $HOME/lessonfiles/. If you save them in lesson-files/ they might get accidentally deleted when you upgrade the program.

File encoding

Solfege by default expect the content of lesson files to be in UTF-8 encoding. gedit is a nice little editor that let you edit unicode files.

If you don't like unicode, you can tell Solfege that the file has another encoding by inserting a special comment line as the first line of the file. The following example set the charset to ISO 8859-1, a charset commonly used in many west-european languages:

 # -*- coding: iso-8859-1 -*-

Russians might want to use koi8-r:

 # -*- coding: koi8-r -*-

The program use the python libs to convert to unicode, so it should understand almost any encoding you can think of. If you see some characters are missing, for example when the name of questions are displayed on buttons, then most likely you have done something wrong with the encoding.

Lesson file contents

A lesson file consist of one header block and zero or more question blocks:

 header {
 ASSIGNMENT
 ASSIGNMENT
 ...
 }
 question {
 ASSIGNMENT
 ...
 }

Header block

The header block can be placed anywhere in the file, but by convention it should be the first block in the file. FIXME Raise exception if there is more than one header block in a file?

Definitions to put in the header block:

module = STRING
Tell what execise module that will run the lesson file, for example idbyname, melodicinterval, chord etc. (Added in Solfege 2.9.0. Replaces the content variable.)
version = STRING
Tell the oldest version of solfege the lessonfile is known to work with. For example version = "1.1.1" This variable is not required, but it should be used because it can (but don't guarantee to) help avoid trouble if the lesson file format changes in the future.
title = STRING
Short oneline description. You should add this to all lesson files.
description = STRING
Optional, long description that can contain html tags. Use this if you have to describe how the lesson file should be used. The description is read from within Solfege on the "Config" page of an exercise when the user has clicked the button labeled "Details".
lesson_heading
a short heading that will be displayed above the exercise. It should way what the purpose of the exercise is. For example "Identify the interval" or "Is the chord minor or major?". (Added in Solfege 3.0)
random_transpose = [key|semitones|accidentals], INTEGER, INTEGER | no | yes
In some exercises the program can transpose the music to create variation. The variable is ignored in exercises that does not support transposing. The default value is yes. (The default value changed from no to yes in Solfege 3.0)
random_transpose = no
No transposition will be done.
random_transpose = yes
The exercise will do random transposition. What kind of transposition depends on the exercise, but you get a ok result from this. This is the default value.
random_transpose = accidentals, INTEGER, INTEGER
For this transposition mode to work propertly, then music in the lessonfile has to be in the keys c major or a minor, or the question must have a key variable like this:
            question {
              name = "the name" 
              key = "d \major" 
              music = music("\key d \major d' e fis")
            }
for this to work correctly. Transpose the music by random. But make sure the number of flats or sharps are within the range specified by INTEGER, INTEGER. To explain how this works, think of flats as negative numbers and sharps as positive numbers. The code
            random_transpose = accidentals, -2, 3
will give you questions with 1 or 2 flats, 0 accidentals or 1, 2 or 3 sharps. The code
            random_transpose = accidentals, 2, 3
will create questions with two or three sharps.
random_transpose = key, INTEGER1, INTEGER2
Transpose the music INTEGER1 steps down or INTEGER2 steps steps up the circle of fifth. (And by my own definition, up is more sharps and down is more flats ... :-) ) This is real transposition where both the key and the notes are transposed.
random_transpose = semitones, INTEGER1, INTEGER2
Transpose the music at most INTEGER1 steps down or INTEGER2 steps up. This is real transposition where both the key and the notes are transposed. You will easily end up with music in the keys with LOTS of accidentals. The code
            random_transpose = semitones, -2, 6
will transpose the questions no more than 2 semitones down and 6 semitones up. This is the same as the old random_transpose = INTEGER, INTEGER syntax.
enable_right_click = yes | no
Default value: yes. Set to no for lesson files where it does not make sense to right click buttons. This variable is recognised by the modules idbyname, chordvoicing and chord.
disable_unused_intervals = yes | no
Make the buttons insensitive for intervals that are not being asked. Used by the harmonicinterval and melodicinterval modules. Default value: yes. Added as a header variable for Solfege 3.0. It was only available as a url parameter in earlier versions of the program.

melodicinterval header variables

number_of_intervals = INTEGER
The number of intervals to be asked. Default value is 1.

idbyname header variables

labelformat = normal | progression
The default value is normal. Set to progression for lesson files where the name of the questions is a harmonic progression, written in a undocumented, but not difficult format. Check some existing lesson file to see how it works. This variable is ignored by all modules except id-by-name

FIXME

have_repeat_slowly_button = yes | no
Set to yes if you want the exercise to have a "Repeat slowly" button. Works for idbyname and is ignored by the other modules.
have_repeat_arpeggio_button = yes | no
Set to yes if you want the exercise to have a "Repeat arpeggio" button. Works for singanswer and is ignored by the other modules.
have_music_displayer = yes | no
Set to yes if you want the question to have a music displayer. The program will display the answer in the music displayer when the user gives up or answers correctly. Works for idbyname and is ignored by the other exercises.
filldir = horiz | vertic
Tell the direction the buttons are filled. Default value is horiz. Works for idbyname and is ignored by the other modules.
fillnum = INTEGER
Tell how many buttons there are in each row or column. The default value is 1. Works for idbyname and is ignored by the other modules.
at_question_start = show | play | play, show
What to do when the user clicks 'New question'. Added to idbyname in Solfege 2.5.1.

rhythm header variables

rhythm_elements
A list of integers (1-21) telling what elementes we should use when creating questions. This variables replaces all the rhythm_element_nn variables used in links.
countin_perc = INTEGER
An integer value between 35 and 81, representing the percussion instrument used to give you the beat before the question.
rhythm_perc = INTEGER
Same as countin_perc, but setting the instrument used for the question.
count_in = INTEGER
The number of beats as count in.
bpm = INTEGER
The tempo, in beats per minute.
num_beats = INTEGER
The number of elements the question is made of.

compareinterval header variables

first_interval_type = harmonic | melodic
last_interval_type = harmonic | melodic
first_interval_up
first_interval_down
last_interval_up
last_interval_down
list of integers. Example: last_interval_down = 1, 2, 3, 4

Question block

name = "some short name"
Questions written for the idbyname and chord exercise need a name.

<!-- FIXME UGH what to write about shortcut... -->

music = music(MUSICSTRING, MUSICFORMAT)"
For most lesson files the music representing the question is assigned to the music variable. Note that there is a shortcut. Instead of:
      question {
        name = "Lisa gikk til skolen"
        music = music(...)"
      }
you can write:
      question {
        name = "Lisa gikk til skolen"
        music(...)
      }
There is a separate section documenting the music object.
tempo = INTEGER / INTEGER
beats per minute / notelen per beat, for example 120/4.
instrument = STRING, INTEGER
instrument = STRING, INTEGER, STRING, INTEGER, STRING, INTEGER
Example:
      instrument = "cello", 100
The instrument name should be one of those defined in the file soundcard/__init__.py. If you don't enter a complete name, solfege will try to find a matching instrument name. The integer is the velocity of the tones, it should be in the range 0-127. For lesson files where it makes sense, it is possible to specify three set of instruments. The following example will play bass for the lowest tone, piano in the middle and clarinet on the top tone:
      instrument = "bass", 100, "acoustic grand", 100, "clarinet", 100
Solfege will try to lookup the midi instrument in this order:
  • inside the question block
  • lesson file global variable
  • instrument set in preferences window

Question block definitions for the idbyname exercise module

vmusic
A presentation of the question intended to be displayed. This can be necessary if music is a .wav or .mp3 file. Will be used when the user click Show music or when the question is answered correctly (if we have a musicdisplayer). (Added in Solfege 2.5.1)
cuemusic
Will be displayed in the music displayer when the user click New. Ignored if on_new = play, show or on_new = show, because then the content of music or vmusic is displayed when the user clicks New. (Added in Solfege 2.5.1)

Question block definitions for the chord module

<!-- UGH FIXME complete this --> In lesson files that is written to work with chord module, two more variables can used:

inversion
0 = root position, 1 = first inversion etc.
toptone
1, 3, 5, 7

Question block definitions for the dictation module

By default, the dictation exercise will show the first column of music, and then the user should write the rest. But if the first column is not good enough, if there for example are only rests on the first beat, these two variables can tell the program how much music to display:

clue_end = nn/dd
clue_end=1/4 will display all music in the first quarter note.

UGH FIXME rewrite para

clue_music = MUSIC
Write the exact music you want to display. If for example you want to display the whoe bar in the upper staff, and only one note in the lower staff.

(Use only one if these variables in a question. Using both are undefined.)

Question block definitions for the singchord module

Questions for this exercise need to have the key variable set if the key signature is anything else than c major (or a minor). Example:

 question { "c''|e'|g|c" }
 question { "a'|e'|c'|a" }
 question { key="d \major" "a'|fis'|d'|d"}
 question { key="f \minor" "as'|f'|c'|f"}

music objects

Synopsis: music(MUSICCODE, MUSICTYPE=normal). The default value for MUSICTYPE is normal, so you only have to specify it for other music types. Available musictypes:

normal
This is music entered completely following the music format spec. This means you have to enter complete code with a \staff command. Example:
      variable = music("\staff\relative c' { c' d' }")
chord
Enter the tones from the lowest to the highest tone, like this:
      variable = music("c' e' g'", chord)
Short-hand function chord is defined. Calling
      chord("c e g")

is the same as

      music("c e g", chord)
satb
Use this format to enter music where the program need to know what voice (in a choir) will sing the different tones. Take this, for example:
      variable = music("c''|e'|g|c")
The c'' will be sung by the soprano, e' by the alto, etc. Short-hand function satb is defined.
voice
This musictype saves some key strokes if you want to enter a melody.
      variable = music("c'4 c' g' g' | a' a' g'2", voice)
is the same as
      variable = music("\staff{ c'4 c' g' g' | a' a' g'2", normal)
Short-hand function voice is defined.
rvoice
rvoice is similar to voice except that the music is in \relative mode, relative to the first tone. The music from:
      variable = music("c'4 c g' g | a a g2", rvoice)
will be interpreted as
      \staff\relative c'{ c4 c g' g' | a a g2 }
and producing the same music as in the voice example above. Short-hand function rvoice is defined.
wavfile
MUSICDATA is the file name of a .wav file. The path given to the file is relative to the directory the lesson file is stored in. Example:
      variable = music("share/fifth-small-220.00.wav", wavfile)
Short-hand function wavfile is defined.
cmdline
MUSICDATA is a command you want to execute. Example:
      cmdline("./bin/csound-play-harmonic-interval.sh 220.000000 320.100000")
Short-hand function cmdline is defined.

Global variables

Global variables can save you a few key strokes.

 s = "\score\relative c'{ %s }

 question {
  # instead of music = music("\score\relative c'{ c d e f g2 g2 }") :
  music = music(s % "c d e f g2 g")
 }

Also, the two variables tempo and instrument can at top level to set the defaul values for a whole file. You can override this for singel questions by putting another difinition inside the question block.

Comments

Everything after # on a line is ignored

Grammar

Disclaimer: I don't know any of the standard ways of describing grammar, like BNF. So this is just an attemt to describe the file format to get people started writing lesson files.

Lessonfiles consists of assignment statements and blocks containing assignment statements.

Functions

_
takes a string as its only argument. Use this if you want Solfege to translate the string for you. Example:
 description = _("This is a short description")
include
includes another file in to this file. Example:
 include("singchord-1")

Types

string
is quoted using the " character, like this: "this is a string". Use tripple quotes for strings that contain line breaks:
      description = """<h1>Long desription<h1> This lessonfile need
      very much descriptions. bla bla bla"""
If the string need to contain the " character, you have to use tripple quotes:
      description = """Try <a href="solfege:practise/melodic-interval">this </a>
      for a simpler interval exercise."""

NB: All strings have to be unicode strings. If you get error messages like this one:

 In line 21 of input: does not recognise this string '<' as a valid token.'
 (line 20): question {
 (line 21): question {
 (line 22):   name = _("Ionia�)

then you must check the encoding of your file. See the section about file encoding. You can change the encoding of a file using the iconv program:

 iconv -f YOUR_ENCODING -t utf8 your.file
integer
is an integer is an integer...
tempotype (in lack of a better name)
is entered as bpm/beatlen. An example:
      tempo = 120/4

will set the tempo to 120 beats per minute, each beat being a quarter note.

Operators

Operators can only be used on strings

+
is used for joining strings
%
is similar to what you find in python, but it is very limited. It only know about %s. One example:
      "\staff\relative c'{%s}" % "c d e"

evaluates to

      \staff\relative c'{c d e}

FIXME see if we should add the outdated last paragraphs from the old docs.