Language
All language functions grouped by creation,compostion and audio control.
Structure
Expressions
Musical objects are created, composed and played using the melrõse tool by evaluating expressions. Expressions use any of the predefined functions (creation,composition,audio control). By assigning an expression to a variable name, you can use that expression by its name to compose other objects.
variables
Variable names must start with a non-digit character and can have zero or more characters in [a-z A-Z _ 0-9]. An assignment “=” is used to create a variable. To delete a variable, assign it to the special value “nil”.
comment
Use “//” to add comment, either on a new line or and the end of an expression.
Creation functions
Composition functions
- at
- bare
- duration
- dynamic
- dynamicmap
- export
- fraction
- fractionmap
- group
- if
- import
- index
- interval
- iterator
- join
- joinmap
- listen
- map (collect)
- merge
- midi_send
- next
- notemap
- octave
- octavemap
- onbar
- random
- repeat
- replace
- resequence
- reverse
- rotate
- stretch
- tabs
- track
- transpose (pitch)
- transposemap (pitchmap)
- trim
- undynamic
- ungroup
- value
- velocitymap
Audio control functions
at
Create an index getter (1-based) to select a musical object.
at(index,object)
at(1,scale('e/m')) // => E
bare
Transforms the object into a simple basic sequence of notes without fractions,dynamics and rests.
bare(somevar,othervar)
b = bare(sequence('.2F+++ =')) // => 2F
biab
Set the Beats in a Bar; default is 4.
biab(beats-in-a-bar)
biab(4)
bpm
Set the Beats Per Minute (BPM) [1..300]; default is 120.
bpm(beats-per-minute)
bpm(90)
speedup = iterator(80,100,120,140)
l = loop(bpm(speedup),sequence('c e g'),next(speedup))
channel
Select a MIDI channel, must be in [1..16]; must be a top-level operator.
channel(number,sequenceable)
channel(2,sequence('c2 e3')) // plays on instrument connected to MIDI channel 2
chordsequence
Create a Chord sequence using this format.
chordsequence(‘chords’)
chordsequence('e f') // => (E A_ B) (F A C5)
chordsequence('(c d)') // => (C E G D G_ A)
device
Select a MIDI device from the available device IDs; must become before channel.
device(number,sequenceable)
device(1,channel(2,sequence('c2 e3'))) // plays on connected device 1 through MIDI channel 2
duration
Computes the duration of the object using the current BPM.
duration(object)
duration(note('c')) // => 375ms
dynamic
Creates a new modified musical object for which the dynamics of all notes are changed. The first parameter controls the emphasis the note, e.g. + (mezzoforte,mf), – (piano,p) or a velocity [0..127]. .
dynamic(emphasis,object)
dynamic('++',sequence('e f')) // => E++ F++
dynamic(112,note('a')) // => A++++
dynamicmap
Changes the dynamic of notes from a musical object. 1-index-based mapping.
dynamicmap(‘mapping’,object)
dynamicmap('1:++,2:--',sequence('e f')) // => E++ F--
dynamicmap('2:o,1:++,2:--,1:++', sequence('a b') // => B A++ B-- A++
euclidean
Euclidean creates a euclidean rythm generator.
euclidean(steps,beats,rotation,noteOrVariable)
e = euclidean(12,4,0,sequence('c e g'))
export
Writes a multi-track MIDI file.
export(filename,sequenceable)
export('myMelody-v1',myObject)
fraction
Creates a new object for which the fraction of duration of all notes are changed. The first parameter controls the fraction of the note, e.g. 1 = whole, 2 = half, 4 = quarter, 8 = eight, 16 = sixteenth. Fraction can also be an exact float value between 0 and 1. .
fraction(object,object)
fraction(8,sequence('e f')) // => 8E 8F , shorten the notes from quarter to eight
fractionmap
Create a sequence with notes for which the fractions are changed. 1-based indexing. use space or comma as separator.
fractionmap(‘fraction-mapping’,object)
fractionmap('3:. 2:4,1:2',sequence('c e g')) // => .G E 2C
fractionmap('. 8 2',sequence('c e g')) // => .C 8E 2G
group
Create a new sequence in which all notes of a musical object are grouped.
group(sequenceable)
group(sequence('c d e')) // => (C D E)
if
Supports conditions with operators on numbers: <,<=,>,>=,!=,==.
if(condition,then,else)
import
Evaluate all the statements from another file.
import(filename)
import('drumpatterns.mel')
index
Returns the current index of an object (e.g. iterator,interval,repeat).
index(generator)
interval
Create an integer repeating interval (from,to,by,method). Default method is ‘repeat’, Use next() to get a new integer.
interval(from,to,by)
int1 = interval(-2,4,1)
lp_cdef = loop(transpose(int1,sequence('c d e f')), next(int1))
iterator
Iterator that has an array of constant values and evaluates to one. Use next() to increase and rotate the value.
iterator(array-element)
i = iterator(1,3,5,7,9)
p = transpose(i,note('c'))
lp = loop(p,next(i))
join
Joins one or more musical objects as one.
join(first,second)
a = chord('a')
b = sequence('(c e g)')
ab = join(a,b) // => (A D_5 E5) (C E G)
joinmap
Creates a new join by mapping elements. 1-index-based mapping.
joinmap(‘indices’,join)
j = join(note('c'), sequence('d e f'))
jm = joinmap('1 (2 3) 4',j) // => C (D E) F
key
Use the key to trigger the play of musical object.
key(‘note’)
c2 = key('c2') // C2 key on the default input device and default channel
c2 = key(device(1,note('c2'))) // C2 key on input device 1
c2 = key(device(1,channel(2,note('c2'))) // C2 key on input device 1 and channel 2
c2 = key(channel(3,note('c2')) // C2 key on the default input device and channel 3
knob
Use the knob as an integer value for a parameter in any object.
knob(device-id,midi-number)
axiom = 1 // device ID for my connected M-Audio Axiom 25
B1 = 20 // MIDI number assigned to this knob on the controller
k = knob(axiom,B1)
transpose(k,scale(1,'E')) // when played, use the current value of knob "k"
listen
Listen for note(s) from a device and call a playable function to handle.
listen(variable-or-device-selector,function)
rec = note('c') // define a variable "rec" with a initial object ; this is a place holder
fun = play(rec) // define the playable function to call when notes are received ; loop and print are also possible
listen(rec,fun) // start a listener for notes from default input device, store it in "rec" and call "fun"
listen(device(1,rec),fun) // start a listener for notes from input device 1
loop
Create a new loop from one or more musical objects.
loop(object)
cb = sequence('c d e f g a b')
loop(cb,reverse(cb))
map (collect)
Map will collect tranformations of each sequence of a collection using a function that references a replacement.
map(collection,function-with-underscore)
j = join(sequence('C E G'),sequence('D F A'))
// uses the special variable named "_"
c = map(j, transpose(1, _ ))
merge
Merges multiple sequences into one sequence.
merge(sequenceable)
m1 = notemap('..!..!..!', note('c2'))
m2 = notemap('4 7 10', note('d2'))
all = merge(m1,m2) // => = = C2 D2 = C2 D2 = C2 D2 = =
midi
Create a Note from MIDI information and is typically used for drum sets. The first parameter is a fraction {1,2,4,8,16} or a duration in milliseconds or a time.Duration. Second parameter is the MIDI number and must be one of [0..127]. The third parameter is the velocity (~ loudness) and must be one of [0..127].
midi(numberOrDuration,number,number)
midi(500,52,80) // => 500ms E3+
midi(16,36,70) // => 16C2 (kick)
midi_send
Sends a MIDI message with status, channel(ignore if < 1), 2nd byte and 3rd byte to an output device. Can be used as a musical object.
midi_send(device-id,status,channel,2nd-byte,3rd-byte
midi_send(1,0xB0,7,0x7B,0) // to device id 1, control change, all notes off in channel 7
midi_send(1,0xC0,2,1,0) // program change, select program 1 for channel 2
midi_send(2,0xB0,4,0,16) // control change, bank select 16 for channel 4
midi_send(3,0xB0,1,120,0) // control change, all notes off for channel 1
multitrack
Create a multi-track object from zero or more tracks.
multitrack(track)
multitrack(track1,track2,track3) // 3 tracks in one multi-track object
next
Is used to produce the next value in a generator such as random, iterator and interval. The function itself does not return the value; use the generator for that.
next(generator)
i = interval(-4,4,2)
pi = transpose(i,sequence('c d e f g a b')) // current value of "i" is used
lp_pi = loop(pi,next(i)) // "i" will advance to the next value
loop(lp_pi)
note
Create a Note using this format.
note(‘letter’)
note('e')
note('2.e#--')
notemap
Creates a mapper of notes by index (1-based) or using dots (.) and bangs (!).
notemap(‘space-separated-1-based-indices-or-dots-and-bangs’,has-note)
m1 = notemap('..!..!..!', note('c2'))
m2 = notemap('3 6 9', octave(-1,note('d2')))
octave
Change the pitch of notes by steps of 12 semitones for one or more musical objects.
octave(offset,sequenceable)
octave(1,sequence('c d')) // => C5 D5
octavemap
Create a sequence with notes for which the order and the octaves are changed.
octavemap(‘int2int’,object)
octavemap('1:-1,2:0,3:1',chord('c')) // => (C3 E G5)
onbar
Puts a musical object on a track to start at a specific bar.
onbar(bar,object)
tr = track("solo",2, onbar(1,soloSequence)) // 2 = channel
onkey
Assign a playable to a key. If this key is pressed the playable will start. If pressed again, the play will stop. Remove the assignment using the value nil for the playable.
onkey(key,playable-or-evaluatable-or-nil)
onkey('c',myLoop) // on the default input device, when C4 is pressed then start or stop myLoop
axiom = 1 // device ID for the M-Audio Axiom 25
c2 = key(device(axiom,note('c2')))
fun = play(scale(2,'c')) // what to do when a key is pressed (NoteOn)
onkey(c2, fun) // if C2 is pressed on the axiom device then evaluate the function "fun"
onoff
Play will send MIDI Note On, stop will send MIDI Note Off.
onoff(note)
// latch example
// if C4 is hit on input device 1
// then play (sustain) key E on the default output device.
// A second hit of C4 will stop it
onkey('c4',onoff('e')) // uses default input and default output MIDI device
play
play(sequenceable)
play(s1,s2,s3) // play s3 after s2 after s1
Prints an object when evaluated (play,loop).
print(object)
prob
Creates a new musical object for which the notes are played with a certain probability.
prob(perc,note-or-sequenceable)
prob(50,note('c')) // 50% chance of playing the note C, otherwise a quarter rest
prob(0.8,sequence('(c e g)')) // 80% chance of playing the chord C, otherwise a quarter rest
progression
Create a Chord progression using this format.
progression(‘scale’,‘space-separated-roman-chords’)
progression('1c3++','II V I') // => (1D3++ 1F3++ 1A3++) (1G3++ 1B3++ 1D++) (1C3++ 1E3++ 1G3++)
random
Create a random integer generator. Use next() to generate a new integer.
random(from,to)
num = random(1,10)
loop(transpose(num,note('C')),next(num))
record
Create a recorded sequence of notes from the current MIDI input device using the currrent BPM.
record(rec)
rec = sequence('') // variable to store the recorded sequence
record(rec) // record notes played on the current input device
repeat
Repeat one or more musical objects a number of times.
repeat(times,sequenceables)
repeat(4,sequence('c d e'))
replace
Replaces all occurrences of one musical object with another object for a given composed musical object.
replace(target,from,to)
c = note('c')
d = note('d')
tc = transpose(1,c)
td = replace(tc, c, d) // c -> d in tc
resequence
Creates a modifier of sequence notes by index (1-based).
resequence(‘space-separated-1-based-indices’,sequenceable)
s1 = sequence('C D E F G A B')
i1 = resequence('6 5 4 3 2 1',s1) // => B A G F E D
i2 = resequence('(6 5) 4 3 (2 1)',s1) // => (B A) G F (E D)
reverse
Reverse the (groups of) notes in a sequence.
reverse(sequenceable)
reverse(chord('a')) // (A D_5 E5)
rotate
Rotates note(groups) in a sequence. count is negative for rotating left.
rotate(count,object)
rotate(-1,sequence('C E G')) // E G C
scale
Create a Scale using this format.
scale(‘scale-syntax’)
// E major
scale('e') // => E G_ A_ A B D_5 E_5
/ E minor
scale('e/m') // => E F G A B C5 D5
// E flat minor
scale('e_/m') // => E_ E G_ A_ B_ B D_5
sequence
Create a Sequence using this format.
sequence(‘space-separated-notes’)
sequence('c d e')
sequence('(8c d e)') // => (8C D E)
sequence('c (d e f) a =')
set
Generic function to change a default setting.
set(setting-name,setting-value)
set('midi.in',1) // default MIDI input device is 1
set('midi.in.channel',2,10) // default MIDI channel for device 2 is 10
set('midi.out',3) // default MIDI output device is 3
stop
Stop running loop(s) or listener(s). Ignore if it was stopped.
stop(control)
l1 = loop(sequence('c e g'))
play(l1)
stop(l1)
stop() // stop all playables
stretch
Stretches the duration of musical object(s) with a factor. If the factor < 1 then duration is shortened.
stretch(factor,object)
stretch(2,note('c')) // 2C
stretch(0.25,sequence('(c e g)')) // (16C 16E 16G)
stretch(8,note('c')) // C with length of 8 x 0.25 (quarter) = 2 bars
sync
Synchronise playing musical objects. Use play() for serial playing.
sync(object)
sync(s1,s2,s3) // play s1,s2 and s3 at the same time
sync(loop1,loop2) // begin loop2 at the next start of loop1
tabs
Create a tabs using this format.
tabs($1:string)
bass = tabs('E e3 a2 a5 d5 a5 a3 e3 G24')
track
Create a named track for a given MIDI channel with a musical object.
track(‘title’,midi-channel, onbar(1,object))
track("lullaby",1,onbar(2, sequence('c d e'))) // => a new track on MIDI channel 1 with sequence starting at bar 2
transpose (pitch)
Change the pitch with a delta of semitones.
transpose(semitones,sequenceable)
transpose(-1,sequence('c d e'))
p = interval(-4,4,1)
transpose(p,note('c'))
transposemap (pitchmap)
Create a sequence with notes for which the order and the pitch are changed. 1-based indexing.
transposemap(‘int2int’,object)
transposemap('1:-1,1:0,1:1',note('c')) // => B3 C D
trim
Create a new sequence object with notes trimmed at the start or/and at the end.
trim(remove-from-start,remove-from-end,object)
t = trim(1,2,sequence('c d e f a') // d e
undynamic
Set the dymamic to normal for all notes in a musical object.
undynamic(sequenceable)
undynamic('A+ B++ C-- D-') // => A B C D
ungroup
Undo any grouping of notes from one or more musical objects.
ungroup(sequenceable)
ungroup(chord('e')) // => E G B
ungroup(sequence('(c d)'),note('e')) // => C D E
value
Returns the current value of a variable.
value(variable)
velocitymap
Create a sequence with notes for which the order and the velocities are changed. Velocity 0 means no change.
velocitymap(‘int2int’,object)
velocitymap('1:30,2:0,3:60',chord('c')) // => (C3--- E G5+)