Skip to content

garncarz/muspl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MusPl, a musical Prolog library

Build Status

This is a beginning project aiming at logical construction/analysis of musical pieces. It's written in SWI-Prolog (version 7, using dicts). So far the construction phase is being developed.

Simple example

Load and export Flies's Lullaby (included in the project) as a Lilypond file and a karaoke text file.

$ swipl
?- [muspl].
true.

?- loadData('examples/wiegenlied').
true.

?- exportLy('wiegenlied.ly').
maxCount:144
count:100
count:0
true.

?- exportUS('wiegenlied.txt', 'wiegenlied.ogg').
true.

?- halt.

Now run Lilypond to convert it to MIDI and PDF.

$ lilypond wiegenlied.ly

PDF screen

You can use TiMidity++ or some other MIDI renderer to convert the MIDI to OGG (or MP3, if you like).

$ timidity -Ov wiegenlied.midi -o wiegenlied.ogg

If you use UltraStar Deluxe as your karaoke program, just copy the TXT and OGG files to the program's songs folder and sing it!

Construction

Simple melody line:

extra scale{root:f, quality:major}.  % scale of a song

m melody{start:(1, 1, v),  % bar 1, beat 1, staff 'v' (e.g. voice)
	relative:(a, 1, 8),  % tone a, octave 1, duration 1/8
	pitch:[0, 1, 0, -1, -2, -1, -2],  % relative pitches from the scale
	len:[1, 1, 1, 1, 1, 1, 2]}.  % multiples of the relative duration

The same line with lengths described briefly:

m melody{start:(1, 1, v), relative:(a, 1, 8),
	pitch:[0, 1, 0, -1, -2, -1, -2], len:[1*6, 2]}.

Repeated pitch/length sequences can be reused by a name:

m [
	'6long' = [1*6, [4, 8, 4]],  % [4, 8, 4] = exact duration 1/4 + 1/8 + 1/4
	melody{start:(5, 1, v), relative:(g, 1, 8),
		pitch:[0, -1:1, 0, 0, -1:1, 0, 2], len:'6long'},
			% :1 = one semitone up, :(-1) would be one semitone down
	melody{start:(5, 1, g), relative:(e, 1, 8),
		pitch:[0, -1:1, 0, 0, -1:1, 0, 2], len:'6long'}
].

Bars can be copied, under a condition and transformed in a way:

m copyBars{from:6, to:10, count:2, cond:isStaff(f), action:pitchShift(5)}.