In GNU Solfege, each exercise is created by a lesson file interpreted by one of the exercise modules.
Deprecated modules: chord, harmonicprogressiondictation,
Missing documentation: chordvoicing, identifybpm, twelvetone
Solfege by default expects the content of lesson files to be in UTF-8 encoding. Modern editors often let you specify the encoding in the "Save As" dialog. One example is gedit. Other programs, like vim and emacs let you specify the encoding inside the text file.
If this sounds complicated, you can safely ignore the whole encoding issue if you restrict yourself to use only standard ascii characters. That is only the letters a to z.
If you create lesson files with a different encoding, you have to declare the encoding in a special comment at the top of the file. This because Solfege and the tools used to translate Solfege cannot guess the encoding safely. We follow the same conventions as the Python language. See PEP-0263 for the details.
What you have to do is add a comment to one of the first two lines
of the lesson file, where part of the line matches coding=encoding
or coding: encoding
. Extra characters on the
line are ignored, so if you use the emacs or vim editors, you can conveniently
tell the editor about the file encoding. The following example sets
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 -*-
Same as above, but in a format that works with the vim:
# vim: set fileencoding= 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.
Unicode has some characters that you might want to use to make labels look more professionally. If your editor use unicode by default, you may copy-and-paste the characters you need from here, if you are viewing this documentation in a web browser. The number is a hexidecimal number.
00F8 LATIN SMALL LETTER O WITH STROKE
Half-diminished seventh chord.
00B0 DEGREE SIGN
Diminished seventh chord.
25B3 WHITE UP-POINTING TRIANGLE
, Δ 0394 GREEK CAPITAL LETTER DELTA
Major seventh chord. We do not know which character to recommend. Solfege does not care, so you can use the symbol you like.
266D MUSIC FLAT SIGN
This sign can be used instead of the letter 'b' for a flat sign.
266F MUSIC SHARP SIGN
This can be used instead of the letter '#' for the sharp sign.
Everything after # on a line is ignored. Example:
# This line is ignored. The next line is not. question { bla bla }
Strings are quoted with the "
character. Example:
"this is a string"
Use triple quotes for strings that contain line breaks, or
if the string itself has to contain the "
character:
description = """<h1>Long desription<h1> This lessonfile need very much descriptions. Qoutes (") are ok here. bla bla bla"""
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 ';lt;' as a valid token.' (line 20): question { (line 21): question { (line 22): name = _("Ionia�)
then you must check the encoding of your file, and maybe you should read “File encoding”. You can change the encoding of a file using the iconv program:
iconv -f YOUR_ENCODING -t utf8 your.file
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") }
A lesson file consist of one header block and zero or more question blocks:
header { ASSIGNMENT ASSIGNMENT ... } question { ASSIGNMENT ... }
The header block can be placed anywhere in the file, but by convention it should be the first block in the file. And there is a limitation that the header has to be within the first 40000 characters of the file.
Variables shared by many exercise modules
module
Tell what exercise module that will run the lesson file. This
variable is required for all lesson files. (The variable was added in
Solfege 2.9.0 where it replaced the content
variable.). Example:
module = idbyname
replaces
A string or list of strings with hash values of lesson files that
this lesson file can replace without dropping the statistics. Use this only when
you know what you are doing. The hash value is calculated by
solfege.lessonfile.hash_of_lessonfile()
.
tools/hash-of-file.py can be used to get the hash value
of files before modifying them.
replaces = "bf7dd374206451bff43d61fc8191f5fb3e88d007" replaces = "bf7dd374206451bff43d61fc8191f5fb3e88d007", "cdb2f9415171650ee7682028788c1c42c62fdbf"
lesson_id
This variable is deprecated in Solfege 3.15.3. It should remain in existing lesson files because if you remove it, you will have to add a replaces entry to keep the statistics. But it should not be added to new lesson files.
version
Tell the version of solfege the lessonfile is known to work with. 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. Example:
version = "3.0.7"
title
Short one-line description that will be used for creating the menu entry for the exercise. You should add this to all lesson files. Example:
title = "Minor and major chords in root position"
lesson_heading
A short heading that will be displayed above the exercise. It should say what the purpose of the exercise is. Some modules provide a default value, others leave the string empty. Example:
lesson_heading = _("Identify the chord")
help
This variable say which help file from the user manual will be displayed when the user presses F1. Example:
help = "idbyname-intonation"
By default, Solfege will display the help file that has the same name as the exercise module being used in the lesson file.
theory
This variable say which help file from the user manual will be displayed when the user presses F3. Pressing F3 should display music theory about the exercise. Don't include this variable if there are no music theory written. Example:
theory = "scales/maj"
random_transpose
In some exercises the program can transpose the music to
create variation. The default value is yes
. (The
default value changed from no
to
yes
in Solfege 3.0.)
Used in modules: chord
,
chordvoicing
, harmonicprogressiondictation
,
idbyname
, singanswer
,
singchord
Possible values
No transposition will be done.
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.
Transpose the question by random and make sure the key signature of the question does not get more than a certain number of accidentals. In this context, the number of accidentals can be described by an integer value. A negative value denote a number of flats (b), and a positive number denote a number o sharps (#). Zero mean no accidentals. The integers INTEGER1 and INTEGER2 defines a range of allowed number of accidentals.
For this to work properly the music must
either be in C major or A minor, or the key of the music has
to be set with the
key
variable.
Transpose the music INTEGER1 steps down or INTEGER2 steps up the circle of fifth. In this context up is more sharps and down is more flats. This is real transposition where both the key and the notes are transposed.
For this to work properly the music must
either be in C major or A minor, or the key of the music has
to be set with the
key
variable.
Transpose the music at most INTEGER1 semitones down or INTEGER2 semitones 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.
Transpose the music at most INTEGER1 semitones down or INTEGER2
semitones up. Similar to semitones
, but the
notes will be transposed one by one, and the key will not change.
enable_right_click = no
By default, Solfege will let the user right-click on buttons to hear
the music they represent without guessing. Set this variable to
no
for lesson files where it does not make sense, for
example in a idbyname
lesson file where many questions
have the same name.
Modules: idbyname
, chordvoicing
and chord
.
disable_unused_intervals
= no
By default, Solfege will make the buttons insensitive for intervals
that are not being asked. Set this variable to no
if you
want all buttons to be sensitive.
Modules: harmonicinterval
and
melodicinterval
.
ask_for_intervals_0
Select which intervals to ask for. 1 for minor second, 2 for major
second, 3 or minor third etc. Use a negative number for descending
intervals. To ask for more that one interval create the variables
ask_for_intervals_1
,
ask_for_intervals_2
etc. In the following example
Solfege will ask for two intervals. The first will be either a minor second
or a major second, both intervals going up. And the second interval will be
either major second or minor third, both intervals going down.
ask_for_intervals_0 = 1, 2 ask_for_intervals_1 = -2, -3
Modules: melodicinterval
and
singinterval
.
intervals
This variable tell which intervals should be asked for in exercises
using the harmonicinterval
module. 1 for minor second, 2 for major
second, 3 or minor third etc. Example that will practise thirds:
intervals = 3, 4
Modules: harmonicinterval
.
test
This variable defines the test for the exercise. In a test,
Solfege will ask all the questions in the lesson file a number
of times.
This variable is always used together with test_requirement
.
In the following example, each question will be asked
3 times:
test = "3x"
Modules: harmonicinterval
,
idbyname
, melodicinterval
and singinterval
.
test_requirement
This variable defines how large percentage of the questions has to be answered correctly to pass the test. Example:
test_requirement = "90%"
Modules: harmonicinterval
,
idbyname
, melodicinterval
and singinterval
.
have_repeat_arpeggio_button
= yes
Set to yes
if you want the exercise to have a
"Repeat arpeggio" button.
Modules: singanswer
.
have_music_displayer
= yes
Set to yes
if you want the question to have a
music displayer.
In the idbyname module, setting this variable will add a music displayer where the program will display the answer when the user gives up or answers the question correctly. You might also want to read about at_question_start.
In the singanswer
module, setting this variable
will add a music displayer where the music will be displayed when
the question is displayed.
Modules: idbyname
,
elembuilder
and
singanswer
.
music_displayer_stafflines
= INTEGER
The number of empty staff lines to display when we have no music to display.
Modules: idbyname
and
elembuilder
.
at_question_start
This variable changes what happens when the user clicks
have_music_displayer
variable is set to
yes
. Setting this variable will also set
have_music_displayer
to yes
.
at_question_start = show
The exercise will get a
button. When the user clicks the music will be displayed in the music displayer, but no music is played. Click to hear the music.at_question_start = play
The exercise will get a
button. When the user clicks the music is played. Click to see the music.at_question_start = show, play
When the user clicks
the music is both played and displayed.Modules: idbyname
, elembuilder
,
rhythmtapping
and rhythmtapping2
.
vmusic
This variable holds a representation of the question intended to be
displayed. This can be necessary if the music is a .wav or .mp3 file. It
will be used when the user clicks Show music or when the question is
answered correctly (if we have a musicdisplayer). Added to
idbyname
in Solfege 2.5.1 and to
elembuilder
in 3.9.2.
Modules: idbyname
and elembuilder
.
rhythm_elements
A list of integers (1-34) telling what elements we should use when creating questions. Example:
rhythm_elements = 0, 1, 2, 3, 4
0: , 1: , 2: , 3: , 4: , 5: , 6: , 7: , 8: , 9: , 10: , 11: , 12: , 13: , 14: , 15: , 16: , 17: , 18: , 19: , 20: , 21: , 22: , 23: , 24: , 25: , 26: , 27: , 28: , 29: , 30: , 31: , 32: , 33: , 34:
Modules: rhythm
and rhythmtapping2
statistics_matrices = enabled | disabled | hidden
Set to disabled
if the statistics page
of the exercise should not display the matrices showing more details
on how you have answered. Set to hidden
if the
matrices should be hidden by an expander button. (Added in Solfege 3.21.3)
Default value: enabled
Variables you can define in the question block
name
Questions written for the idbyname or elembuilder exercise modules need a name. A name is optional for dictation module.
music
For most lesson files the music representing the question is assigned to this 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(...) }
Music objects are documented in “music
objects”.
rhythm
If defined in a question, the rhythm of this music object is used when comparing the users answer to the question. This can be useful if the Solfege cannot find the rhythm of the question, for example when the music object is a MP3 file.
Used in modules: rhythmtapping
and
rhythmdictation.
tempo
Set the tempo for this questions music. The variable is defined "beats per minute" / "notelen per beat". Example:
tempo = 150 / 4
This variable can also be defined globally for the whole lesson file. Do do so you should put it in the beginning of the file, outside any question blocks.
Modules: idbyname
, chord
,
chordvoicing
,
rhythmdictation2
and
rhythmtapping
.
countin
A music object representing a count-in to be played before
the question. Only music objects that are parsed by the
mpd
module can be used as count-in, and only
questions parsed by this module can have count-in. Example:
tempo = rhythm("\time 4/4 d4 d d d")
Entering the time signature is not necessary if the time signature is 4/4, but for all other time signatures you must include it.
Modules: rhythmdictation
and
rhythmdicatation2
instrument
By default, Solfege will use the instrument specified on the preferences window when playing questions. This variable let you select a different instrument. Example:
instrument = "cello", 100
The instrument name has to be quoted. The integer is the volume, and it should be in the range 0-127. You can see a list of instrument names in “Midi instrument names”. 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
This variable can also be defined globally for the whole lesson file. Do do so you should put it in the beginning of the file, outside any question blocks.
Modules: idbyname
, chord
,
singanswer
and chordvoicing
set
The set variable is used by some exercise modules to select which question to play when the user right clicks on one of the answer buttons. This can be useful if the lesson file has many questions with the same name, and you want solfege to play the question that is most closely related to the question being asked. You can assign whatever value you want. A good suggestion is to use integers.
In lesson files that does not use the set
variable,
solfege will play the first question it can find with
the same name as the button the user right clicks on.
If the lesson file uses the set
, or more
precisely, if the question being asked has the variable defined, the
program will first try to find a question where the
set
variable matches the question being asked, and the
name matches the button clicked. If no match is found,
the program will select a question to play as if the
set
variable was not used at all.
Modules: idbyname
and
chordvoicing
.
key
Needed to make some random transposition work properly if the music is not in C major on A minor. Two examples:
key="b \minor" key="g \major"
The import statement will parse a library file and bind it to a
name in the global namespace. You then refer to names defined in the
libarary file using dot notation. In the example below, the
files jazz_progressions
and progression_elements
are two library files that are part of GNU Solfege and
is located in the INSTALLDIR/exercises/standard/lib/ directory.
import progression_elements ❶ import jazz_progressions as j ❷ question { elements = progression_elements.I, progression_elements.V } question { elements = j.I, j.V, j.V }
Parse the file and bind it to the same name as the file name:
| |
Parse the |
The program will first search for a library file in
INSTALLDIR/exercises/standard/lib/
and if not found,
in the ../lib/
relative to the location of the
lesson file.
The rimport
statement work exactly the same
way as import
except that ../lib/
relative to the lesson file is searched before
INSTALLDIR/exercises/standard/lib/
.
Include and import works a little differently. One thing is that how they
find the file to parse differs. But also what happens with the file content. If
one idbyname
lesson file includes another
idbyname
lesson file, when the questions from the included
file will be asked when you practise the including file. But if you copy the
included file to ../lib/
and import it,
the questions in the imported file will not be asked. Only the global
variables in the imported file will be available with dot-notation, as
described in “The import
statement”.
Each question in your lesson files will define one or more
music
objects.
This is music entered completely following the music format FIXME spec. This means you
have to enter complete code with a \staff
command. Example:
variable = music("\staff\relative c' { c' d' }")
The music object can be used for music that has 3 or more staffs. It works the same way as music, but if "Use different instruments for chords and harmonic intervals" is checked in the preferences window, the 3 instruments you can select the same place will be used instead of the preferred MIDI instrument.
Enter the tones from the lowest to the highest tone, like this:
variable = chord("c' e' g'")
This type of music is used by the singchord exercises. It let you say which tones of a chord the different voices in a choir will sing. Take this, for example:
variable = satb("c''|e'|g|c")
The c''
will be sung by the soprano, e'
by the alto, g
by the tenor and
c
by the bass. Please notice that when this music
is played in arpeggio, the tones to be sung by the women, will be played
one octave deeper, of the user is a male. And vice versa if the user
is a female or a child.
This musictype saves some key strokes if you want to enter a melody.
variable = voice("c'4 c' g' g' | a' a' g'2")
is the same as
variable = music("\staff{ c'4 c' g' g' | a' a' g'2")
rvoice
is similar to voice
except that the music is in \relative
mode, relative
to the first tone. The following two statements produce the same music:
variable = rvoice("c'4 c g' g | a a g2") \staff\relative c'{ c4 c g' g' | a a g2 }
This music object provides a simple way to play rhythms with percussion instruments. Each tone represents a percussion instrument as defined in “Percussion instrument names”. In the following example, the tone c is translated to the midi sound Side Stick and d to a Mute triangle.
variable = percussion("d4 d d d c8 c8 c4")
This music object let you write questions that tap rhythms with the
two percussion instruments defined in the preferences window. The tone
c
will play with the instrument intended for the
question and d
will use the instrument
intended for count off. Example:
rhythm("d4 d d d c8 c8 c4 c c8 c8")
You should only use two pitches, c
and
d
. Other pitches will print a warning, but will still
work in the current implementation. To play real percussion with many
different instruments you should use the percussion music object.
Play a midi file. The path given to the file is relative to the directory the lesson file is stored in. Example:
variable = midifile("share/example.mid")
Play a .wav
file. The path given to the file
is relative to the directory the lesson file is stored in. Example:
variable = wavfile("share/fifth-small-220.00.wav")
Play a MP3 file. Similar to wavfile
.
Play an Ogg Vorbis file. Similar to wavfile
.
Given a CSound orchestra and score, this music object will generate a WAV file and play it. Example:
csound(load("share/sinus.orc"), """ f1 0 4096 10 1 i1 0 1 220.0 i1 + 1 329.04 """)
Create a music object that use MMA to generate music that it will play. If you create the object
with one argument, mmacode should be a string with
complete MMA code. With two arguments, groove
is
a string with the name of the groove, and mmacode
is
comple MMA code, except it could be missing the initial
"Groove" instruction. The groove from groove
will be prepended the string.
Run an external program. Example:
cmdline("./bin/csound-play-harmonic-interval.sh 220.000000 320.100000")
_(
message
)
Return the translation of message
if it exist.
Return the string unchanged if not.
title = _("Bla bla title")
include(
filename
)
Read the file filename
into the lesson file
and parse it as a part of the file.
The program will first search for the file with the filename relative
to the location of the lesson file. If not found, it will search
the exercises/standard/lesson-files
directory
of the installation directory of the program.
include("singchord-1")
The lesson header variables will be taken from the including lesson file. Only if a variable is only defined in the included lesson file, and not in the including lesson file, then the value will be taken from the included file.
load(
filename
)
Read the file filename
from disk and return
it as a string. The filename is relative to the location
of the lesson file.
orc = load("share/sinus.orc")
Label functions
We call these functions label functions because we use them to create the label for some questions in the program. You should only use these functions where they are documented to work.
Return a label that the program can put on a button. The label is created using GTK pangomarkup. Google for "pango markup" to get the markup explained. Notice that you have to use triple qoutes around the string.
pangomarkup("""<span size="xx-large">V</span>""")
This function has existed in Solfege for a while, but it has not been documented until now. Should we find a shorter function name? An alias can be added so that the old long function name still works.
Return a label. str
is interpreted like
this:
Each letter outside of a parentheses is displayed with a large serif font.
The text inside parentheses is displayed as a superscript: smaller letters above the baseline.
If the text inside the parentheses is divided by a comma, the text before the comma is superscript and after the comma is subscript.
progressionlabel("I-IV-(6,4)V(5,3)-I") progressionlabel("I-VI-V(6)-I")" progressionlabel("C(maj7)")
Display a sequence of roman numeral chords. The chords are separated by whitespace and an optional hyphen. The exact implementation of this is still open for discussion. The current developent version of Solfege will divide each chord in 3 parts and give them different font sizes, and also try to make the chord compact, so that it should not take too much space on screen.
The first part of the chord is the roman numberal, including
an optional b
, ♭
(unicode character U+266D MUSIC FLAT SIGN
),
#
or ♯
(unicode character U+266F MUSIC SHARP SIGN
).
The second part is the letters (if any) between the first and the third part.
The third part is from the first digit and the rest of the chord.
rnc("Imaj7-IIm7-V9-Imaj7")
Spaces are not allowed in the chord name.
New in version 3.11.0.
Display a sequence of chords. The chords are separated by whitespace. Each chord consist of up to four parts, and part two to four are optional:
[notename][txt1][:txt2][/bass]
notename
and bass
music be
a notename in the format understood by the music parser. You can read
more about this in “The mpd
module”. Example:
g:11b9 cm/g ges:Δ besm:7/f
New in version 3.11.1.