Note¶
- class maelzel.core.event.Note(pitch, dur=None, amp=None, offset=None, gliss=False, label='', dynamic='', tied=False, properties=None, symbols=None, fixed=False, _init=True)[source]¶
Bases:
MEvent
A Note represents a one-pitch event
A Note makes a clear division between the value itself and the representation as notation or as sound. Playback specific options (instrument, pan position, etc) can be set via the
setPlay()
method.Any aspects regarding notation (articulation, enharmonic variant, etc) can be set via
setSymbol()
The pitch parameter can be used to set the pitch and other attributes in multiple ways.
To set the pitch from a frequency, use
pitchtools.f2m
or use a string as ‘400hz’.The spelling of the notename can be fixed by suffixing the notename with a ‘!’ sign. For example,
Note('4Db!')
will fix the spelling of this note to Db instead of C#. This is the same asNote('4Db', fixed=True)
. It is also possible to bind all pitches given as notename, see fixStringNotenamesThe duration can be set as
Note('4C#:0.5')
to set a duration of 0.5, or also Note(‘4C#/8’) to set a duration of an 8th noteDynamics can also be set:
Note('4C#:mf')
. Multiple settings can be combined:Note('4C#:0.5:mf')
.
- Parameters:
pitch (
Union
[int
,float
,str
]) – a midinote or a note as a string. A pitch can be a midinote (a float) or a notename (a string).dur (
Union
[float
,Rational
,Fraction
,None
]) – the duration of this note (optional)amp (
Optional
[float
]) – amplitude 0-1 (optional)offset (
Union
[float
,Rational
,Fraction
,None
]) – offset time fot the note, in quarternotes (optional). If None, the offset time will depend on the context (previous notes) where this Note is evaluated.gliss (
Union
[int
,float
,str
,bool
]) – if given, defines a glissando. It can be either the endpitch of the glissando, or True, in which case the endpitch remains undefinedlabel (
str
) – a label str to identify this notedynamic (
str
) – allows to attach a dynamic expression to this Note. This dynamic is only for notation purposes, it does not modify playbacktied – is this Note tied to the next?
fixed – if True, fix the spelling of the note to the notename given (this is only taken into account if the pitch was given as a notename). See also the configuration key fixStringNotenames. NB: as a shortcut, it is possible to suffix the notename with a ! mark in order to lock its spelling, independently of the configuration settings
_init – if True, fast initialization is performed, skipping any checks. This is used internally for fast copying/cloning of objects.
Attributes Summary
The playback amplitude 0-1 of this note
The fractional part of this pitch, rounded to the cent
The duration of this object, in quarternotes
The end time of this object.
The frequency of this Note (according to the current A4 value)
the end pitch (as midinote), True if the gliss extends to the next note, or False
a label can be used to identify an object within a group of objects
The notename of this Note
Optional offset, in quarternotes.
The parent of this object.
The pitch of this note
The pitch representation of this Note.
The pitch-class of this Note (an int between 0-11)
playargs are set via
setPlay()
and are used to customize playback (instr, gain, …).User-defined properties as a dict (None by default).
A list of all symbols added via
addSymbol()
(None by default)Is this event tied?
Methods Summary
Returns the absolute offset of this object in quarternotes
addSpanner
(spanner[, endobj])Adds a spanner symbol to this object
addSymbol
(*args, **kws)Add a notation symbol to this object
addText
(text[, placement, italic, weight, ...])Add a text annotation to this object
asChord
()Convert this Note to a Chord of one note
asGracenote
([slash])A copy of this note as a gracenote
automate
(param, breakpoints[, ...])Add an automation action to this event
clone
([pitch, dur, amp, offset, gliss, ...])Clone this note with overridden attributes
copy
()Returns a copy of this object
cropped
(start, end)A copy of Self, cropped to the given time range
dump
([indents, forcetext])Prints all relevant information about this object
durSecs
()Returns the duration in seconds according to the active score
events
([instr, delay, args, gain, chan, ...])Returns the SynthEvents needed to play this object
freqShift
(freq)Return a copy of self, shifted in freq.
getPlay
(key[, default, recursive])Get a playback attribute previously set via
MObj.setPlay()
getProperty
(key[, default])Get a property of this objects
getSymbol
(classname)Get a symbol of a given class, if present
The gliss target as notename
invertPitch
(pivot)Invert the pitch of this object
Is this a grace note?
isRest
()Is this a Rest?
Is this event linked to the next?
Is this event linked to the previous?
makeRest
(dur[, offset, label, dynamic])Static method to create a Rest
The mean pitch of this object
mergeWith
(other)Merge this Note with another Note, if possible
overtone
(n)Return a new Note representing the
nth
overtone of this NoteThe absolute offset of the parent
The pitch range of this object, if applicable
pitchTransform
(pitchmap)Apply a pitch-transform to this object, returns a copy
play
([instr, delay, args, gain, chan, ...])Plays this object.
plot
(**kws)- rtype:
Axes
quantizePitch
([step])Returns a new Note, rounded to step.
quantizedScore
([scorestruct, config, ...])Returns a QuantizedScore representing this object
rec
([outfile, sr, verbose, wait, nchnls, ...])Record the output of .play as a soundfile
Resolve the offset of this object, relative to its parent
remap
(deststruct[, sourcestruct])Remap times (offset, dur) from source scorestruct to destination scorestruct
render
([backend, renderoptions, ...])Renders this object as notation
resolveAmp
(config, dyncurve)- rtype:
float
resolveDynamic
([conf])- rtype:
str
Returns the resolved end of this object, relative to its parent
Resolve the target pitch for this note's glissando
scorestruct
([resolve])Returns the ScoreStruct active for this obj or its parent (recursively)
scoringEvents
([groupid, config, parentOffset])Returns its notated form as scoring.Notations
scoringParts
([config])Returns this object as a list of scoring UnquantizedParts.
setPlay
(**kws)Set any playback attributes, returns self
setProperty
(key, value)Set a property, returns self
show
([fmt, external, backend, scorestruct, ...])Show this as notation.
splitAt
(offset[, tie, nomerge])Split this event at the given absolute offset
splitAtOffsets
(offsets[, tie, nomerge])Split this event at the given offsets
timeRangeSecs
([parentOffset, scorestruct])The absolute time range, in seconds
timeScale
(factor[, offset])Create a copy with modified timing by applying a linear transformation
timeShift
(timeoffset)Return a copy of this object with an added offset
timeShiftInPlace
(timeoffset)Shift the time of this by the given offset (inplace)
timeTransform
(timemap[, inplace])Apply a transformation to the time axes of this
transpose
(interval[, inplace])Transpose this note by the given interval
transposeByRatio
(ratio)Transpose this by a given frequency ratio, if applicable
unquantizedScore
([title])Create a maelzel.scoring.UnquantizedScore from this object
withExplicitOffset
([forcecopy])Copy of self with explicit times
write
(outfile[, backend, resolution])Export to multiple formats
Attributes Documentation
- amp: float | None¶
The playback amplitude 0-1 of this note
- cents¶
The fractional part of this pitch, rounded to the cent
- dur¶
The duration of this object, in quarternotes
- dynamic: str¶
- freq¶
The frequency of this Note (according to the current A4 value)
- gliss¶
the end pitch (as midinote), True if the gliss extends to the next note, or False
- label: str¶
a label can be used to identify an object within a group of objects
- name¶
The notename of this Note
- offset: F | None¶
Optional offset, in quarternotes. Specifies the start time relative to its parent
It can be None, which indicates that within a container this object would start after the previous object. For an object without a parent, the offset is an absolute offset.
- parent¶
The parent of this object.
This attribute is set by the parent when an object is added to it. For example, when adding a Note to a Chain, the Chain is set as the parent of the Note. This enables the Note to query information about the parent, like its absolute position or if a score structure has been set upstream
- pitch: float¶
The pitch of this note
- pitchSpelling¶
The pitch representation of this Note. Can be different from the sounding pitch
- pitchclass¶
The pitch-class of this Note (an int between 0-11)
- playargs: PlayArgs | None¶
playargs are set via
setPlay()
and are used to customize playback (instr, gain, …). None by default
- properties: dict[str, Any] | None¶
User-defined properties as a dict (None by default). Set them via
setProperty()
- symbols: list[_symbols.Symbol] | None¶
A list of all symbols added via
addSymbol()
(None by default)
- tied: bool¶
Is this event tied?
Methods Documentation
- absOffset()¶
Returns the absolute offset of this object in quarternotes
If this object is embedded (has a parent) in a container, its absolute offset depends on the offset of its parent, recursively. If the object has no parent then the absolute offset is just the resolved offset
- Return type:
Fraction
- Returns:
the absolute start position of this object
- addSpanner(spanner, endobj=None)¶
Adds a spanner symbol to this object
A spanner is a slur, line or any other symbol attached to two or more objects. A spanner always has a start and an end.
- Parameters:
spanner (
str
|Spanner
) – a Spanner object or a spanner description (one of ‘slur’, ‘<’, ‘>’, ‘trill’, ‘bracket’, etc. - seemaelzel.core.symbols.makeSpanner()
When passing a string description, prepend it with ‘~’ to create an end spannerendobj (
Optional
[MEvent
]) – the object where this spanner ends, if known
- Return type:
Self
- Returns:
self (allows to chain calls)
Example
>>> from maelzel.core import * >>> a = Note("4C") >>> b = Note("4E") >>> c = Note("4G") >>> a.addSpanner('slur', c) >>> chain = Chain([a, b, c])
See also
In some cases the end target can be inferred:
>>> chain = Chain([ ... Note("4C", 1, dynamic='p').addSpanner("<"), ... Note("4D", 0.5), ... Note("4E", dynamic='f') # This ends the hairpin spanner ... ])
Or it can be set later
>>> chain = Chain([ ... Note("4C", 1).addSpanner("slur"), ... Note("4D", 0.5), ... Note("4E").addSpanner("~slur") # This ends the last slur spanner ... ])
- addSymbol(*args, **kws)¶
Add a notation symbol to this object
Notation symbols are attributes attached to one event and are intended for notation only. Such symbols include articulations, ornaments, fermatas but also properties, like color, size, etc. Also customizations like notehead shape, bend signs, all are considered symbols. Notation symbols spanning across multiple events (like slurs, crescendo hairpins, lines, etc.) are considered spanners and are added via
addSpanner()
Some symbols are exclusive, meaning that adding a symbol of this kind will replace a previously set symbol. Exclusive symbols include any properties (color, size, etc) and other customizations like notehead shape
Note
Dynamics are not treated as symbols since they can also be used for playback
Example
>>> from maelzel.core import * >>> n = Note(60) >>> n.addSymbol(symbols.Articulation('accent')) # The same can be achieved via keyword arguments: >>> n.addSymbol(articulation='accent') # Multiple symbols can be added at once: >>> n = Note(60).addSymbol(text='dolce', articulation='tenuto') >>> n2 = Note("4G").addSymbol(symbols.Articulation('accent'), symbols.Ornament('mordent')) # Known symbols - most common symbols don't actually need keyword arguments: >>> n = Note("4Db").addSymbol('accent').addSymbol('fermata') # Some symbols can take customizations: >>> n3 = Note("4C+:1/3").addSymbol(symbols.Harmonic(interval='4th'))
- Return type:
Self
- Returns:
self (similar to setPlay, allows to chain calls)
Symbol
Possible Values
text
any text
notehead
cross, harmonic, triangleup, xcircle, triangle, rhombus, square, rectangle
articulation
accent, staccato, tenuto, marcato, staccatissimo, etc.
size
A relative size (0=default, 1, 2, …=bigger, -1, -2, … = smaller)
color
a css color
- addText(text, placement='above', italic=False, weight='normal', fontsize=None, fontfamily='', box='')¶
Add a text annotation to this object
This is a shortcut to
self.addSymbol(symbols.Text(...))
. Use that for in-depth customization.- Parameters:
text (
str
) – the text annotationplacement – where to place the annotation (‘above’, ‘below’)
italic – if True, use italic as font style
weight – ‘normal’ or ‘bold’
fontsize (
Optional
[int
]) – the size of the annotationfontfamily – the font family to use. It is probably best to leave this unset
box – the enclosure shape, or ‘’ for no box around the text. Possible shapes are ‘square’, ‘circle’, ‘rounded’
- Return type:
Self
- Returns:
self
- automate(param, breakpoints, interpolation='linear', relative=True)¶
Add an automation action to this event
- Parameters:
param (
str
) – the playback parameter to modify, either a builtin parameter like position, or an instrument defined parameter (for example, an instrument based on substractive synthesis could define a ‘filterattack’ parameter, or a vocal synthesis instrument could define a ‘vibratoamount’ parameter)breakpoints (
list
[tuple
[Union
[float
,Rational
,Fraction
,tuple
[int
,Union
[float
,Rational
,Fraction
]]],float
]] |list
[tuple
[Union
[float
,Rational
,Fraction
,tuple
[int
,Union
[float
,Rational
,Fraction
]]],float
,str
]] |list
[Union
[float
,Rational
,Fraction
]]) – the data, a list of pairs in the form (time, value), or (time, value, interpolation). time is given in quarternotes or as a location (measure, beatoffset); value is any valid valud for the given parameter; interpolation is one of ‘linear’, ‘cos’. As a shortcut it is possible to also pass a flat list of the form [time0, value0, time1, value1, …]. A single point is also possible. This sets the value for the given param at the specified timeinterpolation – default interpolation used for breakpoints without interpolation
relative – if True, the time positions are relative to the absolute offset of this event. If False, these times are absolute times
- Return type:
None
Example
note = Note("4c", 10) # Automate position starting at beat 5 after this event has started note.automate('position', [(5, 0.), (6, 1.)], relative=True) # The same data can be given as a flat list note.automate('position', [5, 0., 6, 1.]) # Time position can be also given as a tuple (measure num, beat offset), # and the time mode can be set to absolute # In this case, this automation indicates a modification of the # pan position, from 0 to 1 starting at the 4th measure (index 3) and # ending at the 5th measure (index 4) note.automate('position', [(3, 0), 0., (4, 0), 1.], relative=False)
Any dynamic parameter can be automated:
# Define a preset with some dynamic parameter defPreset('detuned', ''' |kdetune=2| aout1 = oscili:a(kamp, kfreq) + oscili:a(kamp, kfreq+kdetune) ''') # Automate the kdetune param. When automating a Note/Chord, the times # are given in quarterbeats, which means that the real time in seconds # depend on the tempo structure. In this case the kdetune param will # be shifted from 0 to 20 starting at the moment the note is played # and ending 4 **quarterbeats** after. note.automate('kdetune', (0, 0, 4, 20)) # When the note is actually played the automation takes effect synth = note.play(instr='detuned') # The synth itself can be automated. In this case, we are already # in the real-time realm and any times are given in seconds. If # needed the active scorestruct can be used to convert between # quarterbeats and seconds synth.automate('position', (2, 0.5, 4, 1))
- clone(pitch=None, dur=None, amp=None, offset=UNSET, gliss=None, label=None, tied=None, dynamic=None)[source]¶
Clone this note with overridden attributes
Returns a new note
- Return type:
- cropped(start, end)¶
A copy of Self, cropped to the given time range
The returned event will have an explicit offset set to its absolute offset. It is parentless
- Parameters:
start (beat_t) – the start location to crop this event
end (beat_t) – the end location to crop this event
- Return type:
Self
- Returns:
the cropped event
- dump(indents=0, forcetext=False)¶
Prints all relevant information about this object
- Parameters:
indents – number of indents
forcetext – if True, force text output via print instead of html even when running inside jupyter
- durSecs()¶
Returns the duration in seconds according to the active score
- Return type:
Fraction
- Returns:
the duration of self in seconds
- events(instr=None, delay=None, args=None, gain=None, chan=None, pitchinterpol=None, fade=None, fadeshape=None, position=None, skip=None, end=None, sustain=None, workspace=None, transpose=0.0, **kwargs)¶
Returns the SynthEvents needed to play this object
All these attributes here can be set previously via
playargs
(or usingsetPlay()
)- Parameters:
gain (
Optional
[float
]) – modifies the own amplitude for playback/recording (0-1)delay (
Optional
[float
]) – delay in seconds, added to the start of the object As opposed to the .offset attribute of each object, which is defined in quarternotes, the delay is always in secondsinstr (
Optional
[str
]) – which instrument to use (see defPreset, definedPresets). Use “?” to select from a list of defined presets.chan (
Optional
[int
]) – the channel to output to. Channels start at 1pitchinterpol (
Optional
[str
]) – ‘linear’, ‘cos’, ‘freqlinear’, ‘freqcos’fade (
Union
[float
,tuple
[float
,float
],None
]) – fade duration in seconds, can be a tuple (fadein, fadeout)fadeshape (
Optional
[str
]) – ‘linear’ | ‘cos’args (
Optional
[dict
[str
,float
]]) – named arguments passed to the note. A dict{paramName: value}
position (
Optional
[float
]) – the panning position (0=left, 1=right)skip (
Optional
[float
]) – start playback at the given offset (in quarternotes), relative to the start of the object. Allows to play a fragment of the object (NB: this trims the playback of the object. Usedelay
to offset the playback in time while keeping the playback time unmodified)end (
Optional
[float
]) – end time of playback, in quarternotes. Allows to play a fragment of the object by trimming the end of the playbacksustain (
Optional
[float
]) – a time added to the playback events to facilitate overlapping/legato between notes, or to allow one-shot samples to play completely without being cropped.workspace (
Optional
[Workspace
]) – a Workspace. If given, overrides the current workspace. It’s scorestruct is used to determine the mapping between beat-time and real-time.transpose (
float
) – an interval to transpose any pitch
- Return type:
list
[SynthEvent
]- Returns:
A list of SynthEvents (see
SynthEvent
)
Example
>>> from maelzel.core import * >>> n = Note(60, dur=1).setPlay(instr='piano') >>> n.events(gain=0.5) [SynthEvent(delay=0.000, gain=0.5, chan=1, fade=(0.02, 0.02), instr=piano) bps 0.000s: 60, 1.000000 1.000s: 60, 1.000000] >>> play(n.events(chan=2))
- freqShift(freq)[source]¶
Return a copy of self, shifted in freq.
Example:
# Shifting a note by its own freq. sounds one octave higher >>> n = Note("C3") >>> n.freqShift(n.freq) C4
- Return type:
- getPlay(key, default=None, recursive=True)¶
Get a playback attribute previously set via
MObj.setPlay()
- Parameters:
key (
str
) – the key (see setPlay for possible keys)default – the value to return if the given key has not been set
recursive – if True, search the given attribute up the parent chain
- Returns:
either the value previously set, or default otherwise.
- getProperty(key, default=None)¶
Get a property of this objects
Any MObj can have multiple properties. A property is a key:value pair, where the key is a string and the value can be anything. Properties can be used to attach information to an object, to tag it in any way needed.
Properties are set via
MObj.setProperty()
. TheMObj.properties
attribute can be queries directly, but bear in mind that if no properties have been set, this attribute is ``None`` by default.- Parameters:
key (
str
) – the property to querydefault – returned value if the property has not been set
- Returns:
the value of the property, or the default value
See also
setProperty()
,properties
- getSymbol(classname)¶
Get a symbol of a given class, if present
This is only supported for symbol classes which are exclusive (notehead, color, ornament, etc.). For symbols like ‘articulation’, which can be present multiple times, query the symbols attribute directly (NB: symbols might be
None
if no symbols have been set):if note.symbols: articulations = [s for s in note.symbols if s.name == 'articulation']
- Parameters:
classname (
str
) – the class of the symbol. Possible values are ‘articulation’, ‘text’, ‘notehead’, ‘color’, ‘ornament’, ‘fermata’, ‘notatedpitch’. See XXX (TODO) for a complete list- Return type:
Symbol
|None
- Returns:
a symbol of the given class, or None
- glissTarget()[source]¶
The gliss target as notename
Raises ValueError if this Note does not have a gliss
- Return type:
str
- Returns:
The gliss target as notename
- invertPitch(pivot)¶
Invert the pitch of this object
- Parameters:
pivot (
Union
[int
,float
,str
]) – the point around which to invert pitches- Return type:
Self
- Returns:
the inverted object
>>> from maelzel.core import * >>> series = Chain("4Bb 4E 4F# 4Eb 4F 4A 5D 5C# 4G 4G# 4B 5C".split()) >>> inverted = series.invertPitch("4F#") >>> print(" ".join(_.name.ljust(4) for _ in series)) ... print(" ".join(_.name.ljust(4) for _ in inverted)) 4A# 4E 4F# 4D# 4F 4A 5D 5C# 4G 4G# 4B 5C 4D 4G# 4F# 4A 4G 4D# 3A# 3B 4F 4E 4C# 4C >>> Score([series, inverted])
- isGracenote()[source]¶
Is this a grace note?
A grace note has a pitch but no duration
- Return type:
bool
- Returns:
True if this can be considered a grace note
- linkedNext()¶
Is this event linked to the next?
An event is linked to a next event if it is tied or has glissando set to True where this applies. This is not the case if the event has a gliss value set to other than True
- Return type:
bool
- linkedPrev()¶
Is this event linked to the previous?
- Return type:
bool
- static makeRest(dur, offset=None, label='', dynamic='')[source]¶
Static method to create a Rest
A Rest is actually a regular Note with pitch == 0.
- Parameters:
dur (
Union
[float
,Rational
,Fraction
,str
]) – duration of the restoffset (
Union
[float
,Rational
,Fraction
,None
]) – explicit offset of the restlabel (
str
) – a label to attach to the restdynamic – a dynamic for this rest (yes, rests can have dynanic…)
- Return type:
- Returns:
the Note object representing the rest
- meanPitch()[source]¶
The mean pitch of this object
- Return type:
float
|None
- Returns:
The mean pitch of this object
- overtone(n)[source]¶
Return a new Note representing the
nth
overtone of this Note- Parameters:
n (
float
) – the overtone number (1 = fundamental)- Return type:
- Returns:
a new Note
- parentAbsOffset()¶
The absolute offset of the parent
- Return type:
Fraction
- Returns:
the absolute offset of the parent if this object has a parent, else 0
- pitchRange()[source]¶
The pitch range of this object, if applicable
This is useful in order to assign this object to a proper Voice when distributing objects among voices
- Return type:
tuple
[float
,float
] |None
- Returns:
either None or a tuple (lowest pitch, highest pitch)
- pitchTransform(pitchmap)[source]¶
Apply a pitch-transform to this object, returns a copy
- Parameters:
pitchmap (
Callable
[[float
],float
]) – a function mapping pitch to pitch- Return type:
- Returns:
the object after the transform
- play(instr=None, delay=None, args=None, gain=None, chan=None, pitchinterpol=None, fade=None, fadeshape=None, position=None, skip=None, end=None, whenfinished=None, sustain=None, workspace=None, transpose=0, config=None, display=False, **kwargs)¶
Plays this object.
Play is always asynchronous (to block, use some sleep funcion). By default,
play()
schedules this event to be renderer in realtime.Note
To record events offline, see the example below
- Parameters:
gain (
Optional
[float
]) – modifies the own amplitude for playback/recording (0-1)delay (
Optional
[float
]) – delay in seconds, added to the start of the object As opposed to the .offset attribute of each object, which is defined in symbolic (beat) time, the delay is always in real (seconds) timeinstr (
Optional
[str
]) – which instrument to use (see defPreset, definedPresets). Use “?” to select from a list of defined presets.chan (
Optional
[int
]) – the channel to output to. Channels start at 1pitchinterpol (
Optional
[str
]) – ‘linear’, ‘cos’, ‘freqlinear’, ‘freqcos’fade (
Union
[float
,tuple
[float
,float
],None
]) – fade duration in seconds, can be a tuple (fadein, fadeout)fadeshape (
Optional
[str
]) – ‘linear’ | ‘cos’args (
Optional
[dict
[str
,float
]]) – arguments passed to the note. A dict{paramName: value}
position (
Optional
[float
]) – the panning position (0=left, 1=right)skip (
Optional
[float
]) – amount of time (in quarternotes) to skip. Allows to play a fragment of the object (NB: this trims the playback of the object. Usedelay
to offset the playback in time while keeping the playback time unmodified)end (
Optional
[float
]) – end time of playback. Allows to play a fragment of the object by trimming the end of the playbacksustain (
Optional
[float
]) – a time added to the playback events to facilitate overlapping/legato between notes, or to allow one-shot samples to play completely without being cropped.workspace (
Optional
[Workspace
]) – a Workspace. If given, overrides the current workspace. It’s scorestruct is used to to determine the mapping between beat-time and real-time.transpose (
float
) – add a transposition interval to the pitch of this objectconfig (
Optional
[CoreConfig
]) – if given, overrides the current configwhenfinished (
Optional
[Callable
]) – function to be called when the playback is finished. Only applies to realtime renderingdisplay – if True and running inside Jupyter, display the resulting synth’s html
- Return type:
SynthGroup
- Returns:
A
SynthGroup
See also
render()
,
Example
Play a note
>>> from maelzel.core import * >>> note = Note(60).play(gain=0.1, chan=2)
Play multiple objects synchronised
>>> play( ... Note(60, 1.5).events(gain=0.1, position=0.5) ... Chord("4E 4G", 2, start=1.2).events(instr='piano') ... )
Or using play as a context managger:
>>> with play(): ... Note(60, 1.5).play(gain=0.1, position=0.5) ... Chord("4E 4G", 2, start=1.2).play(instr='piano') ... ...
Render offline
>>> with render("out.wav", sr=44100) as r: ... Note(60, 5).play(gain=0.1, chan=2) ... Chord("4E 4G", 3).play(instr='piano')
- plot(**kws)¶
- Return type:
Axes
- quantizePitch(step=0.0)[source]¶
Returns a new Note, rounded to step.
If step is 0, the default quantization value is used (this can be configured via
getConfig()['semitoneDivisions']
) :rtype:Note
Note
If this note has a gliss, the target pitch is also quantized
Any set pitch spelling is deleted
- quantizedScore(scorestruct=None, config=None, quantizationProfile=None, enharmonicOptions=None, nestedTuplets=None)¶
Returns a QuantizedScore representing this object
- Parameters:
scorestruct (
Optional
[ScoreStruct
]) – if given it will override the scorestructure active for this objectconfig (
Optional
[CoreConfig
]) – if given will override the active configquantizationProfile (
Union
[str
,QuantizationProfile
,None
]) – if given it is used to customize the quantization process. Otherwise, a profile is constructed based on the config. It is also possible to pass the name of a quantization preset (possible values: ‘lowest’, ‘low’, ‘medium’, ‘high’, ‘highest’, seemaelzel.scoring.quant.QuantizationProfile.fromPreset()
)enharmonicOptions (
Optional
[EnharmonicOptions
]) – if given it is used to customize enharmonic respelling. Otherwise, the enharmonic options used for respelling are constructed based on the confignestedTuplets (
Optional
[bool
]) – if given, overloads the config value ‘quant.nestedTuplets’. This is used to disallow nested tuplets, mainly for rendering musicxml since there are some music editors (MuseScore, for example) which fail to import nested tuplets. This can be set at the config level asgetConfig()['quant.nestedTuplets'] = False
- Return type:
- Returns:
a quantized score. To render such a quantized score as notation call its
render()
method
A QuantizedScore contains a list of QuantizedParts, which each consists of list of QuantizedMeasures. To access the recursive notation structure of each measure call its
asTree()
method
- rec(outfile='', sr=None, verbose=None, wait=None, nchnls=None, instr=None, delay=None, args=None, gain=None, position=None, extratime=None, workspace=None, **kws)¶
Record the output of .play as a soundfile
- Parameters:
outfile – the outfile where sound will be recorded. Can be None, in which case a filename will be generated. Use ‘?’ to open a save dialog
sr (
Optional
[int
]) – the sampling rate (config key: ‘rec.sr’)wait (
Optional
[bool
]) – if True, the operation blocks until recording is finishes (config ‘rec.block’)nchnls (
Optional
[int
]) – if given, use this as the number of channels to record.gain (
Optional
[float
]) – modifies the own amplitude for playback/recording (0-1)delay (
Optional
[float
]) – delay in seconds, added to the start of the object As opposed to the .start attribute of each object, which is defined in symbolic (beat) time, the delay is always in real (seconds) timeinstr (
Optional
[str
]) – which instrument to use (see defPreset, definedPresets). Use “?” to select from a list of defined presets.args (
Optional
[dict
[str
,float
]]) – named arguments passed to the note. A dict{paramName: value}
position (
Optional
[float
]) – the panning position (0=left, 1=right)workspace (
Optional
[Workspace
]) – if given it overrides the active workspaceextratime (
Optional
[float
]) – extratime added to the recording (config key: ‘rec.extratime’)verbose (
Optional
[bool
]) – if True, display synthesis output**kws – any keyword passed to .play
- Return type:
- Returns:
the offline renderer used. If no outfile was given it is possible to access the renderer soundfile via
OfflineRenderer.lastOutfile()
Example
>>> from maelzel.core import * >>> # a simple note >>> chord = Chord("4C 4E 4G", dur=8).setPlay(gain=0.1, instr='piano') >>> renderer = chord.rec(wait=True) >>> renderer.lastOutfile() '/home/testuser/.local/share/maelzel/recordings/tmpashdas.wav'
See also
OfflineRenderer
- relOffset()¶
Resolve the offset of this object, relative to its parent
If this object has no parent the offset is an absolute offset.
The
.offset
attribute holds the explicit offset. If this attribute is unset (None
) this object might ask its parent to determine the offset based on the durations of any previous objects- Return type:
Fraction
- Returns:
the offset, in quarter notes. If no explicit or implicit offset and the object has no parent it returns 0.
See also
MObj.absOffset()
- remap(deststruct, sourcestruct=None)¶
Remap times (offset, dur) from source scorestruct to destination scorestruct
The absolute time remains the same
- Parameters:
deststruct (
ScoreStruct
) – the destination scorestructsourcestruct (
Optional
[ScoreStruct
]) – the source scorestructure, or None to use the resolved scoresturct
- Return type:
Self
- Returns:
a clone of self remapped to the destination scorestruct
- render(backend='', renderoptions=None, scorestruct=None, config=None, quantizationProfile=None)¶
Renders this object as notation
First the object is quantized to abstract notation, then it is passed to the backend to render it for the specific format (lilypond, musicxml, …), which is then used to generate a document (pdf, png, …)
- Parameters:
backend – the backend to use, one of ‘lilypond’, ‘musicxml’. If not given, defaults to the config key ‘show.backend’
renderoptions (
Optional
[RenderOptions
]) – the render options to use. If not given, these are generated from the active configscorestruct (
Optional
[ScoreStruct
]) – if given, overrides the scorestruct set within the active Workspace and any scorestruct attached to this objectconfig (
Optional
[CoreConfig
]) – if given, overrides the active configquantizationProfile (
Union
[str
,QuantizationProfile
,None
]) – if given, it is used to customize the quantization process and will override any config option related to quantization. A QuantizationProfile can be created from a config viamaelzel.core.config.CoreConfig.makeQuantizationProfileFromPreset()
.
- Return type:
- Returns:
a scoring.render.Renderer. This can be used to write the rendered structure to an image (png, pdf) or as a musicxml or lilypond file.
Example
>>> from maelzel.core import * >>> voice = Voice(...) # Render with the settings defined in the config >>> voice.render() # Customize the rendering process >>> from maelzel.scoring.renderer import RenderOptions >>> from maelzel.scoring.quant import QuantizationProfile >>> quantprofile = QuantizationProfile.simple( ... possibleDivisionsByTempo={80: [] ... })
- resolveEnd()¶
Returns the resolved end of this object, relative to its parent
An object’s offset can be explicit (set in the
.offset
attributes) or implicit, as calculated from the context of the parent. For example, inside a Chain, the offset of an event depends on the offsets and durations of the objects preceding it.Note
To calculate the absolute end of an object, use
obj.absOffset() + obj.resolveEnd
- Return type:
Fraction
- Returns:
the resolved end of this object, relative to its parent. If this object has no parent, the relative end and the absolute end are the same
See also
MObj.relOffset()
,MObj.absOffset()
- resolveGliss()[source]¶
Resolve the target pitch for this note’s glissando
- Return type:
float
- Returns:
the target pitch or this note’s own pitch if its target pitch cannot be determined
- scorestruct(resolve=False)¶
Returns the ScoreStruct active for this obj or its parent (recursively)
If this object has no parent
None
is returned. If resolve is True and this object has no associated scorestruct, the active scorestruct is returned- Parameters:
resolve – if True and this obj (or its parent, recursively) has no associated scorestruct, the active scorestruct is returned
- Return type:
ScoreStruct
|None
- Returns:
the associated scorestruct or the active struct if resolve is True and this object has no associated struct (either directly or through its parent)
Example
>>> from maelzel.core import * >>> n = Note("4C", 1) >>> voice = Voice([n]) >>> score = Score([voice]) >>> score.setScoreStruct(ScoreStruct(timesig=(3, 4), tempo=72)) >>> n.scorestruct() ScoreStruct(timesig=(3, 4), tempo=72)
- scoringEvents(groupid='', config=None, parentOffset=None)[source]¶
Returns its notated form as scoring.Notations
These can then be converted into notation via some of the available backends: musicxml or lilypond
- Parameters:
groupid – passed by an object higher in the hierarchy to mark this objects as belonging to a group
config (
Optional
[CoreConfig
]) – a configuration to customize renderingparentOffset (
Optional
[Fraction
]) – if given this should be the absolute offset of this object’s parent
- Return type:
list
[Notation
]- Returns:
A list of scoring.Notation which best represent this object as notation
- scoringParts(config=None)¶
Returns this object as a list of scoring UnquantizedParts.
- Parameters:
config (
Optional
[CoreConfig
]) – if given, this config instead of the active config will be used- Return type:
list
[UnquantizedPart
]- Returns:
a list of unquantized parts
This method is used internally to generate the parts which constitute a given MObj prior to rendering, but might be of use itself so it is exposed here.
An
maelzel.scoring.UnquantizedPart
is an intermediate format used by the scoring package to represent notated events. It represents a list of non-simultaneous Notations, unquantized and independent of any score structure
- setPlay(**kws)[source]¶
Set any playback attributes, returns self
- Parameters:
**kws – any argument passed to
play()
(delay, dur, chan, gain, fade, instr, pitchinterpol, fadeshape, params, priority, position).- Return type:
- Returns:
self. This allows to chain this to any constructor (see example)
Attribute
Type
Descr
instr
str
The instrument preset to use
delay
float
Delay in seconds, added to the start of the object
chan
int
The channel to output to, channels start at 1
fade
float
The fade time; can also be a tuple (fadein, fadeout)
fadeshape
str
One of ‘linear’, ‘cos’, ‘scurve’
pitchinterpol
str
One of ‘linear’, ‘cos’, ‘freqlinear’, ‘freqcos’
gain
float
A gain factor applied to the amplitud of this object. Dynamic argument (kgain)
position
float
Dynamic argument. Panning position (0=left, 1=right). Dynamic argument (kpos)
skip
float
Skip time of playback; allows to play a fragment of the object. NB: set the delay to the -skip to start playback at the original time but from the timepoint specified by the skip param
end
float
End time of playback; counterpart of
skip
, allow to trim playback of the objectsustain
float
An extra sustain time. This is useful for sample based instruments
transpose
float
Transpose the pitch of this object only for playback
glisstime
float
The duration (in beats) of the glissando for events with glissando. A short glisstime can be used for legato playback in non-percusive instruments
priority
int
The order of evaluation. Events scheduled with a higher priority are evaluated later in the chain
args
dict
Named arguments passed to the playback instrument
gliss
float/ bool
An object can be set to have a playback only gliss. It is equivalent to having a gliss., but the gliss is not displayed as notation.
Example:
# a piano note >>> from maelzel.core import * # Create a note with predetermined instr and panning position >>> note = Note("C4+25", dur=0.5).setPlay(instr="piano", position=1) # When .play is called, the note will play with the preset instr and position >>> note.play()
See also
addSymbol()
,playargs
- setProperty(key, value)¶
Set a property, returns self
Any MObj can have user-defined properties. These properties are optional: before any property is created the
.properties
attribute isNone
. This method creates the dict if it is still None and sets the property.- Parameters:
key (
str
) – the key to setvalue – the value of the property
- Return type:
Self
- Returns:
self (similar to setPlay or setSymbol, to allow for chaining calls)
Example
>>> from maelzel.core import * >>> n = Note("4C", 1) >>> n.setProperty('foo', 'bar') 4C:1♩ >>> # To query a property do: >>> n.getProperty('foo') bar >>> # Second Method: query the properties attribute directly. >>> # WARNING: if no properties were set, this attribute would be None >>> if n.properties: ... foo = n.properties.get('foo') ... print(foo) bar
See also
getProperty()
,properties
- show(fmt=None, external=None, backend='', scorestruct=None, config=None, resolution=None)¶
Show this as notation.
- Parameters:
external (
Optional
[bool
]) – True to force opening the image in an external image viewer, even when inside a jupyter notebook. If False, show will display the image inline if inside a notebook environment. To change the default, modify config[‘openImagesInExternalApp’]backend – backend used when rendering to png/pdf. One of ‘lilypond’, ‘musicxml’. If not given, use default (see config[‘show.backend’])
fmt (
Optional
[str
]) – one of ‘png’, ‘pdf’, ‘ly’. None to use default.scorestruct (
Optional
[ScoreStruct
]) – if given overrides the current/default score structureconfig (
Optional
[CoreConfig
]) – if given overrides the current/default configresolution (
Optional
[int
]) – dpi resolution when rendering to an image, overrides the config key ‘show.pngResolution’
- Return type:
None
- splitAt(offset, tie=True, nomerge=False)¶
Split this event at the given absolute offset
- Parameters:
offset (beat_t) – the absolute offset at which to split this event. Can be a beat or a location
tie – tie the parts
nomerge – if True, adds a break symbol to the events resulted in the split operation to prevent them from being merged when converted to notation
- Return type:
tuple[Self, …]
- Returns:
a tuple with the parts. If the offset lies perfectly at the start or end of this event, only one part will be returned. If the offset does not intersect the event, ValueError is raised
Example
>>> n = Note(60, 4) >>> n.splitAt(2) TODO
- splitAtOffsets(offsets, tie=True, nomerge=False)¶
Split this event at the given offsets
- Parameters:
offsets (
list
[Union
[float
,Rational
,Fraction
]]) – absolute offsets. To use score locations, convert those to absolute offsets viascorestruct.locationToBeat
tie – if True, tie the parts
nomerge – if True, adds a break symbol to the events resulted in the split operation to prevent them from being merged when converted to notation
- Return type:
list
[Self
]- Returns:
the parts. The total duration of the parts should sum up to the duration of self
- timeRangeSecs(parentOffset=None, scorestruct=None)¶
The absolute time range, in seconds
- Parameters:
parentOffset (
Optional
[Fraction
]) – if given, use this offset as parent offset. This is useful if the parent’s offset has already been calculatedscorestruct (
Optional
[ScoreStruct
]) – use this scorestruct to calculate absolute time. This is useful if the scorestruct is already known.
- Return type:
tuple
[Fraction
,Fraction
]- Returns:
a tuple (absolute start time in seconds, absolute end time in seconds)
- timeScale(factor, offset=0)¶
Create a copy with modified timing by applying a linear transformation
- Parameters:
factor (
Union
[float
,Rational
,Fraction
]) – a factor which multiplies all durations and start timesoffset (
Union
[float
,Rational
,Fraction
]) – an offset added to all start times
- Return type:
Self
- Returns:
the modified object
- timeShift(timeoffset)[source]¶
Return a copy of this object with an added offset
- Parameters:
timeoffset (time_t) – a delta time added
- Return type:
Self
- Returns:
a copy of this object shifted in time by the given amount
- timeShiftInPlace(timeoffset)¶
Shift the time of this by the given offset (inplace)
- Parameters:
timeoffset (
Union
[float
,Rational
,Fraction
]) – the time delta (in quarterNotes)- Return type:
None
- timeTransform(timemap, inplace=False)¶
Apply a transformation to the time axes of this
- Parameters:
timemap (
Callable
[[Fraction
],Fraction
]) – a callable mapping time (in quarterbeats) to time (in quarterbeats)inplace
- Return type:
Self
Returns:
- transpose(interval, inplace=False)[source]¶
Transpose this note by the given interval
If inplace is True the operation is done inplace and the returned note can be ignored.
Note
If this Note has a set spelling, its spelling will also be transposed To remove a fixed spelling do
note.pitchSpelling = ''
- Parameters:
interval (
float
) – the transposition interval (1=one semitone)inplace – if True, the note itself is modified
- Return type:
- Returns:
The transposed note
- transposeByRatio(ratio)¶
Transpose this by a given frequency ratio, if applicable
A ratio of 2 equals to transposing an octave higher.
- Parameters:
ratio (float) – the ratio to transpose by
- Return type:
_MObjT
- Returns:
a copy of this object, transposed by the given ratio
Example
>>> from maelzel.core import * >>> n = Note("4C") # A transposition by a ratio of 2 results in a pitch an octave higher >>> n.transposeByRatio(2) 5C
- unquantizedScore(title='')¶
Create a maelzel.scoring.UnquantizedScore from this object
- Parameters:
title – the title of the resulting score (if given)
- Return type:
- Returns:
the Arrangement representation of this object
An
UnquantizedScore
is a list ofUnquantizedPart
, which is itself a list ofNotation
. AnArrangement
represents an unquantized score, meaning that the Notations within each part are not split into measures, nor organized in beats. To generate a quantized score seequantizedScore()
This method is mostly used internally when an object is asked to be represented as a score. In this case, an Arrangement is created first, which is then quantized, generating a
QuantizedScore
See also
quantizedScore()
,QuantizedScore
- withExplicitOffset(forcecopy=False)¶
Copy of self with explicit times
If self already has explicit offset and duration, self itself is returned. If you relie on the fact that this method returns a copy, use
forcecopy=True
- Parameters:
forcecopy – if forcecopy, a copy of self will be returned even if self already has explicit times
- Returns:
a clone of self with explicit times
Example
>>> n = None("4C", dur=0.5) >>> n 4C:0.5♩ >>> n.offset is None True # An unset offset resolves to 0 >>> n.withExplicitTimes() 4C:0.5♩:offset=0 # An unset duration resolves to 1 quarternote beat >>> Note("4C", offset=2.5).withExplicitTimes() 4C:1♩:offset=2.5
- write(outfile, backend='', resolution=None)¶
Export to multiple formats
Formats supported: pdf, png, musicxml (extension: .xml or .musicxml), lilypond (.ly), midi (.mid or .midi) and pickle
- Parameters:
outfile (
str
) – the path of the output file. The extension determines the format. Formats available are pdf, png, lilypond, musicxml, midi, csd and pickle.backend – the backend used when writing as pdf or png. If not given, the default defined in the active config is used (key: ‘show.backend’). Possible backends:
lilypond
;musicxml
(uses MuseScore to render musicxml as image so MuseScore needs to be installed)resolution (
Optional
[int
]) – image DPI (only valid if rendering to an image) - overrides the config key ‘show.pngResolution’
- Return type:
None
Formats¶
pdf, png: will render the object as notation and save that to the given format
lilypond:
.ly
extension. Will render the object as notation and save it as lilypond text- midi:
.mid
or.midi
extension. At the moment this is done via lilypond, so the midi produced follows the quantization process used for rendering to notation. Notice that midi cannot reproduce many features of a maelzel object, like microtones, and many complex rhythms will not be translated correctly
- midi:
- pickle: the object is serialized using the pickle module. This allows to load it
via
pickle.load
:myobj = pickle.load(open('myobj.pickle'))