Music Macro Language evaluator

The MML object implements acustom MML evaluator to allow simple and efficient music composition within pyo. The language’s rules are explained below.

The MML object generates triggers on new notes with additional streams to handle frequency, amplitude, duration and custom parameters. See the object documentation for more details.

API documentation

  • The space separates the tokens in a music sequence (a token can be a note value, an amplitude control, a tempo statement, etc.).

Pre-Processing on music text

  • A comment starts with a semicolon ( ; ) and ends at the end of the line. This text will be removed before starting to evaluate the sequences.

  • A musical voice is represented by a single line of code.

  • We can break a long line into multiple short lines with the backslash ( \ ).

  • The symbol equal ( = ), preceded by a variable name in UPPER CASE, creates a macro. The remaining part of the line is the macro body. Anywhere the pre-processor finds the variable name in the music, it will be replaced by the macro’s body.

Realtime Processing of the music

Voice number

  • The symbol #, followed by a number indicates the voice number for the line. This should be the first token of a line. If missing, the line defaults to voice number 0.

Notes

  • The letters a to g correspond to the musical pitches and cause the corresponding note to be played.

  • Sharp notes are produced by appending a + to the pitch value, and flat notes by appending a - to the pitch value.

  • The length of a note is specified by an integer following the note name. If a note doesn’t have a duration, the last specified duration is used. Default duration is the Sixteenth note. Length values are:

    • 0 = Thirty-second note

    • 1 = Sixteenth note

    • 2 = Dotted sixteenth note

    • 3 = Eighth note

    • 4 = Dotted eighth note

    • 5 = Quarter note

    • 6 = Dotted quarter note

    • 7 = Half note

    • 8 = Dotted half note

    • 9 = Whole note

  • The letter r corresponds to a rest. The length of the rest is specified in the same manner as the length of a note.

  • The letter o, followed by a number, selects the octave the instrument will play in. If the letter o is followed by the symbol +, the octave steps up by one. If followed by the symbol -, the octave steps down by one. If a number follows the symbol + or -, the octave steps up or down by the given amount of octaves.

Tuplets

  • Notes surrounded by brakets ( ( and ) ) act as tuplet. Tuplet length is specified just after the closing bracket using the same values as for a note duration. Length of each note in tuplet will evenly be <note length of tuplet> / <count of notes in tuplet>. If not specified, tuplet duration defaults to 5 (quarter note).

Tempo

  • The letter t, followed by a number, sets the tempo in beats-per-minute. If the letter t is followed by the symbol +, the tempo increases by one. If followed by the symbol -, the tempo decreases by one. If a number follows the symbol + or -, the tempo increases or decreases by the given amount of BPM.

Volume

  • The letter v, followed by a number between 0 and 100, sets the volume for the following notes. If the letter v is followed by the symbol +, the volume increases by one. If followed by the symbol -, the volume decreases by one. If a number follows the symbol + or -, the volume increases or decreases by the given amount.

User variables

  • The letters x, y an z, followed by a real number, are user-defined parameters. They can be used to control specific parameters of the synthesizer. If the letter is followed by the symbol +, the value increases by 0.01. If followed by the symbol -, the value decreases by 0.01. If a number follows the symbol + or -, the value increases or decreases by the given amount.

Random selection

  • Random choice within a set of values can be done with the ? symbol, followed by the possible values inside square brackets. Ex. ?[c e g b-] ; the note is a random choice between c e g and b-.

  • Random choice between a range can be done with the ? symbol, followed by the range inside curly brackets. If two values are presents, they are the minimum and maximum of the range. If there is only one value, the range is 0 to this value and if the brackets are empty, the range is 0 to 1. Ex. v?{40 70} ; volume is set randomly between 40 and 70.

Looping segments

  • The symbol |: starts a looped segment and the symbol :| ends it. A number right after the last symbol indicates how many loops to perform. If missing, the number of loops is two (the first pass + one repetition). It is possible to use loops inside other loops. There is no limit to the number of levels of loop embedding.

Objects

MML

class MML(music, voices=1, loop=False, poly=1, updateAtEnd=False)[source]

Generates music sequences based on a custom MML notation.

Music Macro Language (MML) is a music description language used in sequencing music on computer and video game systems.

Parent

PyoObject

Args
music: string

The new music code to parse. If the string is a valid path to a text file, the file is opened and its content is taken as the music code.

voices: int, optional

The number of voices in the music code. This number is used to initialize the internal voices that will play the sequences. Defaults to 1.

loop: bool, optional

If True, the playback will start again when the music reaches its end, otherwise the object just stops to send triggers. Defaults to False.

poly: int, optional

Per voice polyphony. Denotes how many independent streams are generated per voice by the object, allowing overlapping processes.

Available only at initialization. Defaults to 1.

updateAtEnd: bool, optional

If True, voices will update their internal sequence only when the current one reaches its end, no matter when the music argument is changed. If False, sequences are updated immediately. Defaults to False.

Note

MML outputs many signals identified with a string between brackets:

obj[‘freq’] returns an audio stream of the current note frequency.
obj[‘amp’] returns an audio stream of the current note amplitude.
obj[‘dur’] returns an audio stream of the current note duration in seconds.
obj[‘end’] returns an audio stream with a trigger at the end of the sequence.
obj[‘x’] returns an audio stream with the current value of the x parameter.
obj[‘y’] returns an audio stream with the current value of the y parameter.
obj[‘z’] returns an audio stream with the current value of the z parameter.

obj without brackets returns the generated trigger streams of the music.

The out() method is bypassed. MML’s signal can not be sent to audio outs.

MML has no mul and add attributes.

>>> s = Server().boot()
>>> s.start()
>>> a = '''
>>> ; Title: La perdriole
>>> ; Author: traditionnel
>>> A = r6 o4 v40 g3 v50 o5 c d e f g5 o+ c o- b3 a g f e d c7
>>> B = |: g3 g g4 f1 e3 d c5 :| g1 g g g g g g g b-3 o+ c d7 r7
>>> C = |: o5 c4 d1 e3 f g4 o+ c1 o- b3 a g f e d e d c5 r5 :|
>>> #0 t92 x.1 |: A A B C :|
>>> A1 = |: r7 o4 c7 d7 e5 f g c7 :|
>>> B1 = |: g7 o- b5 o+ c :| d5 d f g7 r7
>>> C1 = |: c8 d7 g c5 r5 :|
>>> #1 t92 x0.25 v50 |: A1 B1 C1 :|
>>> '''
>>> t = CosTable([(0,0), (64,1), (1024,1), (4096, 0.5), (8191,0)])
>>> mml = MML(a, voices=2, loop=True, poly=4).play()
>>> dur = Sig(mml.getVoice(0, "dur"), mul=2)
>>> tr = TrigEnv(mml.getVoice(0), table=t, dur=dur, mul=mml.getVoice(0, "amp"))
>>> a = SineLoop(freq=mml.getVoice(0, "freq"), feedback=mml.getVoice(0, "x"), mul=tr).mix()
>>> dur2 = Sig(mml.getVoice(1, "dur"), mul=2)
>>> tr2 = TrigEnv(mml.getVoice(1), table=t, dur=dur2, mul=mml.getVoice(1, "amp"))
>>> a2 = LFO(freq=mml.getVoice(1, "freq"), sharp=mml.getVoice(1, "x"), type=2, mul=tr2).mix()
>>> output = STRev([a, a2], inpos=[0.2, 0.8], bal=0.2, mul=1.5).out()

Public Data Attributes:

music

string.

Inherited from PyoObject

mul

float or PyoObject.

add

float or PyoObject.

Public Methods:

__init__(music[, voices, loop, poly, ...])

__getitem__(i)

getVoice(voice[, stream])

get([identifier, all])

Return the first sample of the current buffer as a float.

setMusic(x)

Replace the music attribute.

getSequences()

Returns the sequences parsed from the music text.

getNoteFromPitch(x)

Converts a MIDI note to MML notation and returns the result as a string.

getVolumeFromVelocity(x)

Converts a MIDI velocity to MML volume notation and returns the result as a string.

play([dur, delay])

Start processing without sending samples to output.

stop([wait])

Stop processing.

out([chnl, inc, dur, delay])

Start processing and send samples to audio output beginning at chnl.

setMul(x)

Replace the mul attribute.

setAdd(x)

Replace the add attribute.

setSub(x)

Replace and inverse the add attribute.

setDiv(x)

Replace and inverse the mul attribute.

editor([title, wxnoserver])

Opens the text editor for this object.

Inherited from PyoObject

__init__(music[, voices, loop, poly, ...])

__add__(x)

__radd__(x)

__iadd__(x)

__sub__(x)

__rsub__(x)

__isub__(x)

__mul__(x)

__rmul__(x)

__imul__(x)

__truediv__(x)

__rtruediv__(x)

__itruediv__(x)

__div__(x)

__rdiv__(x)

__idiv__(x)

__pow__(x)

__rpow__(x)

__mod__(x)

__neg__()

__lt__(x)

Return self<value.

__le__(x)

Return self<=value.

__eq__(x)

Return self==value.

__ne__(x)

Return self!=value.

__gt__(x)

Return self>value.

__ge__(x)

Return self>=value.

__do_comp__(comp, mode[, default])

isPlaying([all])

Returns True if the object is currently playing, otherwise, returns False.

isOutputting([all])

Returns True if the object is outputting.

get([identifier, all])

Return the first sample of the current buffer as a float.

play([dur, delay])

Start processing without sending samples to output.

out([chnl, inc, dur, delay])

Start processing and send samples to audio output beginning at chnl.

stop([wait])

Stop processing.

mix([voices])

Mix the object's audio streams into voices streams and return a Mix object.

range(min, max)

Adjust mul and add attributes according to a given range.

setMul(x)

Replace the mul attribute.

setAdd(x)

Replace the add attribute.

setSub(x)

Replace and inverse the add attribute.

setDiv(x)

Replace and inverse the mul attribute.

set(attr, value[, port, callback])

Replace any attribute with portamento.

ctrl([map_list, title, wxnoserver])

Opens a sliders window to control the parameters of the object.

Inherited from PyoObjectBase

__init__(music[, voices, loop, poly, ...])

dump()

Print infos about the current state of the object.

getBaseObjects()

Return a list of Stream objects managed by the instance.

getServer()

Return a reference to the current Server object.

getSamplingRate()

Return the current sampling rate (samples per second), as a float.

getBufferSize()

Return the current buffer size (samples per buffer), as an integer.

allowAutoStart([switch])

When autoStartChildren is activated in the Server, call this method with False as argument to stop the propagation of play/out/stop methods to and from this object.

useWaitTimeOnStop()

When autoStartChildren is activated in the Server, call this method to force an object given to the mul attribute of another object to use the wait time from the stop method instead of being stopped immediately.

addLinkedObject(x)

When autoStartChildren is activated in the Server, use this method to explicitly add an object in a dsp chain, which is generally controlled by the last object of the chain.

setStopDelay(x)

Set a specific waiting time when calling the stop method on this object.

getStopDelay()

Return the waiting time applied when calling the stop method on this object.

__iter__()

__next__()

next()

Alias for __next__ method.

__getitem__(i)

__setitem__(i, x)

__len__()

__repr__()

Return repr(self).

__dir__()

Default dir() implementation.

Private Data Attributes:

Inherited from PyoObject

_STREAM_TYPE

Inherited from PyoObjectBase

_STREAM_TYPE

Private Methods:

Inherited from PyoObject

_init_play()

_reset_from_set([attr])

Inherited from PyoObjectBase

_autoplay([dur, delay])

_autostop([wait])


get(identifier='amp', all=False)[source]

Return the first sample of the current buffer as a float.

Can be used to convert audio stream to usable Python data.

“freq”, “amp”, “dur”, “end”, “x”, “y” or “z” can be given to identifier to retrieve a specific stream to get the value from.

Args
identifier: string {“freq”, “amp”, “dur”, “end”, “x”, “y”, “z”}

Address string parameter identifying audio stream. Defaults to “amp”.

all: boolean, optional

If True, the first value of each object’s stream will be returned as a list.

If False, only the value of the first object’s stream will be returned as a float.

setMusic(x)[source]

Replace the music attribute.

Args
x: string

The new music code to parse. If the string is a valid path to a text file, the file is opened and its content is taken as the music code.

getSequences()[source]

Returns the sequences parsed from the music text.

getNoteFromPitch(x)[source]

Converts a MIDI note to MML notation and returns the result as a string.

Args
x: int

The MIDI note to convert to MML notation. This will return two tokens, the octave followed by the note name.

getVolumeFromVelocity(x)[source]

Converts a MIDI velocity to MML volume notation and returns the result as a string.

Args
x: int

The MIDI velocity to convert to MML volume notation. This will return a volume token.

play(dur=0, delay=0)[source]

Start processing without sending samples to output. This method is called automatically at the object creation.

This method returns self, allowing it to be applied at the object creation.

Args
dur: float, optional

Duration, in seconds, of the object’s activation. The default is 0 and means infinite duration.

delay: float, optional

Delay, in seconds, before the object’s activation. Defaults to 0.

stop(wait=0)[source]

Stop processing.

This method returns self, allowing it to be applied at the object creation.

Args
wait: float, optional

Delay, in seconds, before the process is actually stopped. If autoStartChildren is activated in the Server, this value is propagated to the children objects. Defaults to 0.

Note

if the method setStopDelay(x) was called before calling stop(wait) with a positive wait value, the wait value won’t overwrite the value given to setStopDelay for the current object, but will be the one propagated to children objects. This allow to set a waiting time for a specific object with setStopDelay whithout changing the global delay time given to the stop method.

Fader and Adsr objects ignore waiting time given to the stop method because they already implement a delayed processing triggered by the stop call.

out(chnl=0, inc=1, dur=0, delay=0)[source]

Start processing and send samples to audio output beginning at chnl.

This method returns self, allowing it to be applied at the object creation.

Args
chnl: int, optional

Physical output assigned to the first audio stream of the object. Defaults to 0.

inc: int, optional

Output channel increment value. Defaults to 1.

dur: float, optional

Duration, in seconds, of the object’s activation. The default is 0 and means infinite duration.

delay: float, optional

Delay, in seconds, before the object’s activation. Defaults to 0.

If chnl >= 0, successive streams increment the output number by inc and wrap around the global number of channels.

If chnl is negative, streams begin at 0, increment the output number by inc and wrap around the global number of channels. Then, the list of streams is scrambled.

If chnl is a list, successive values in the list will be assigned to successive streams.

setMul(x)[source]

Replace the mul attribute.

Args
x: float or PyoObject

New mul attribute.

setAdd(x)[source]

Replace the add attribute.

Args
x: float or PyoObject

New add attribute.

setSub(x)[source]

Replace and inverse the add attribute.

Args
x: float or PyoObject

New inversed add attribute.

setDiv(x)[source]

Replace and inverse the mul attribute.

Args
x: float or PyoObject

New inversed mul attribute.

editor(title='MML Editor', wxnoserver=False)[source]

Opens the text editor for this object.

Args
title: string, optional

Title of the window. If none is provided, the name of the class is used.

wxnoserver: boolean, optional

With wxPython graphical toolkit, if True, tells the interpreter that there will be no server window.

If wxnoserver is set to True, the interpreter will not wait for the server GUI before showing the controller window.

property music

string. The music code to parse.