QuantizationProfile

class maelzel.scoring.quant.QuantizationProfile(nestedTuplets=False, gridErrorWeight=1, gridErrorExp=0.85, divisionErrorWeight=0.002, maxDivPenalty=0.1, maxGridDensity=0, rhythmComplexityWeight=0.001, offsetErrorWeight=1.0, restOffsetErrorWeight=0.5, durationErrorWeight=0.2, gracenoteDuration=Fraction(1, 32), gracenoteErrorWeight=0, possibleDivisionsByTempo=<factory>, divisionPenaltyMap=<factory>, divisionCardinalityPenaltyMap=<factory>, numNestedTupletsPenalty=<factory>, complexNestedTupletsFactor=1.8, numSubdivsPenaltyMap=<factory>, divisionPenaltyWeight=1.0, cardinalityPenaltyWeight=0.1, numNestedTupletsPenaltyWeight=1.0, numSubdivisionsPenaltyWeight=0.2, syncopationMinBeatFraction=Fraction(1, 6), syncopationMinSymbolicDuration=Fraction(1, 3), syncopationMaxAsymmetry=2.0, mergedTupletsMaxDuration=Fraction(2, 1), mergeTupletsOfDifferentDuration=False, allowNestedTupletsAcrossBeat=False, allowedTupletsAcrossBeat=(1, 2, 3, 4, 5, 8), allowedNestedTupletsAcrossBeat=<factory>, breakLongGlissandi=True, maxPenalty=1.0, debug=False, debugMaxDivisions=20, blacklist=<factory>, name='', breakSyncopationsLevel='strong', tiedSnappedGracenoteMinRealDuration=Fraction(1, 1000000), _cachedDivisionsByTempo=<factory>, _cachedDivisionPenalty=<factory>)[source]

Bases: object

A QuantizationProfile is used to configure quantization

To construct a QuantiztationProfile based on a preset, use QuantizationProfile.fromPreset()

Most important parameters:

  • nestedTuplets: if True, allow nested tuplets. NB: musicxml rendered via MuseScore does not support nested tuplets

  • gridErrorWeight: a weight to control the overall effect of offset and duration errors when fitting events to a grid. A higher weight will cause quantization to minimize offset and duration errors, at the cost of choosing more complex divisions

  • divisionErrorWeight: also a weight to controll all effect dealing with the complexity of a given division/subdivision

Lower level parameters to calculate grid error:

  • offsetErrorWeight: the importance of offset errors to calculate the best subdivision of a beat

  • restOffsetErrorWeight: how relevant should be the offset error in the case of rests

  • durationErrorWeight: relevance of duration error when selecting the best subdivision

  • graceNoteDuration: if a note is considered a grace note (which have no duration per se), should we still account for this duration?

  • syncopationMinBeatFraction: when merging durations across beats, a merged duration can’t be smaller than this duration. This is to prevent joining durations across beats which might result in high rhythmic complexity

  • tupletsAllowedAcrossBeats: list of tuplets allowed across a beat

  • tupletMaxDur: the max quarternote duration for a merged subdivision

Lower level parameters to calculate division complexity:

  • numNestedTupletsPenaltyWeight: how

Attributes Summary

allowNestedTupletsAcrossBeat

Allow merging nested tuplets across the beat

allowedTupletsAcrossBeat

Which tuplets are allowed to cross the beat

breakLongGlissandi

When a glissando extends over a quarternote, break it into quarter notes

breakSyncopationsLevel

break at all beats, 'strong': only strong beats)

cardinalityPenaltyWeight

Weight of cardinality

complexNestedTupletsFactor

For certain combinations of nested tuplets an extra complexity factor can be applied.

debug

Turns on debugging

debugMaxDivisions

Max number of quantization possibilities to display when debugging

divisionErrorWeight

Weight of the division complexity

divisionPenaltyWeight

Weight of division penalty

durationErrorWeight

Weight of the difference in duration resulting from quantization

gracenoteDuration

A duration to assume for grace notes

gracenoteErrorWeight

gridErrorExp

An exponent applied to the grid error.

gridErrorWeight

Weight of the overall effect of offset and duration errors when fitting events to a grid.

maxDivPenalty

A max.

maxGridDensity

If given (higher than 0) it discards any division of the beat with a higher number of slots than this value.

maxPenalty

A max.

mergeTupletsOfDifferentDuration

Allow merging tuplets which have different total durations?

mergedTupletsMaxDuration

How long can a tuplet over the beat be

name

A name for this profile, if needed

nestedTuplets

Are nested tuplets allowed?

numNestedTupletsPenaltyWeight

Weight of sublevel penalty

numSubdivisionsPenaltyWeight

Weight to penalize the number of subdivisions

offsetErrorWeight

Weight of the offset between original start and makeSnappedNotation start

restOffsetErrorWeight

Similar to offsetErrorWeight but for rests

rhythmComplexityIrregularDurationsWeight

When calculating rhythm complexity this weight is applied to the penalty of notes whose duration is irregular (durations of 5 or 9 units, which need ties to be represented)

rhythmComplexityNotesAcrossSubdivisionWeight

When calculating rhythm complexity this weight is applied to the penalty of notes extending over subdivisions of the beat (inner-beat syncopes)

rhythmComplexityWeight

Weight of the actual quantized rhythm.

syncopationMaxAsymmetry

The max.

syncopationMinBeatFraction

How long can a synchopation be, in terms of the length of the beat

syncopationMinSymbolicDuration

Min.

tiedSnappedGracenoteMinRealDuration

The min.

Methods Summary

divisionPenalty(division)

A penalty based on the complexity of the division of the pulse alone

fromPreset([complexity, nestedTuplets, ...])

Create a QuantizationProfile from a preset

makeSimple([maxSubdivisions, ...])

Static method to create a simple QuantizationProfile based on a preset

possibleBeatDivisionsByTempo(tempo)

The possible divisions of the pulse for the given tempo

Attributes Documentation

allowNestedTupletsAcrossBeat: bool = False

Allow merging nested tuplets across the beat

allowedTupletsAcrossBeat: tuple[int, ...] = (1, 2, 3, 4, 5, 8)

Which tuplets are allowed to cross the beat

breakLongGlissandi: bool = True

When a glissando extends over a quarternote, break it into quarter notes

If the noteheads are hidden, a glissando over a half-note cannot be differentiated from a glissando over a quarternote. If this option is True, such a long glissando is broken into quarternotes in order to prevent this misinterpretation

breakSyncopationsLevel: str = 'strong'

break at all beats, ‘strong’: only strong beats)

Type:

Break syncopations at beat boundaries (‘none’

Type:

do not break syncopations, ‘all’

cardinalityPenaltyWeight: float = 0.1

Weight of cardinality

complexNestedTupletsFactor: float = 1.8

For certain combinations of nested tuplets an extra complexity factor can be applied. If this factor is 1.0, then no extra penalty is calculated. Any number above 1 will penalize complex nested tuplets (prefer (5, 5, 5) over (3, 3, 3, 3, 3)).

debug: bool = False

Turns on debugging

debugMaxDivisions: int = 20

Max number of quantization possibilities to display when debugging

divisionErrorWeight: float = 0.002

Weight of the division complexity

divisionPenaltyWeight: float = 1.0

Weight of division penalty

durationErrorWeight: float = 0.2

Weight of the difference in duration resulting from quantization

gracenoteDuration: Fraction = Fraction(1, 32)

A duration to assume for grace notes

gracenoteErrorWeight: float = 0
gridErrorExp: float = 0.85

An exponent applied to the grid error. Since this values is always between 0 and 1, an exponent less than 1 makes the effects of grid errors grow faster

gridErrorWeight: float = 1

Weight of the overall effect of offset and duration errors when fitting events to a grid. A higher weight minimizes offset and duration errors at the cost of more complex divisions

maxDivPenalty: float = 0.1

A max. division penalty, will discard any divisions which have a penalty higher than this value. This can be used to further customize the quantization process

maxGridDensity: int = 0

If given (higher than 0) it discards any division of the beat with a higher number of slots than this value. For example, a division of (3, 4, 4) has a density of 12, since the highest subdivision, 4, applied to the entire beat would result in 12 notes per beat

maxPenalty: float = 1.0

A max. penalty when quantizing a beat, to limit the search space

mergeTupletsOfDifferentDuration: bool = False

Allow merging tuplets which have different total durations?

mergedTupletsMaxDuration: Fraction = Fraction(2, 1)

How long can a tuplet over the beat be

name: str = ''

A name for this profile, if needed

nestedTuplets: bool = False

Are nested tuplets allowed?

numNestedTupletsPenaltyWeight: float = 1.0

Weight of sublevel penalty

numSubdivisionsPenaltyWeight: float = 0.2

Weight to penalize the number of subdivisions

offsetErrorWeight: float = 1.0

Weight of the offset between original start and makeSnappedNotation start

restOffsetErrorWeight: float = 0.5

Similar to offsetErrorWeight but for rests

rhythmComplexityIrregularDurationsWeight = 0.8

When calculating rhythm complexity this weight is applied to the penalty of notes whose duration is irregular (durations of 5 or 9 units, which need ties to be represented)

rhythmComplexityNotesAcrossSubdivisionWeight = 0.2

When calculating rhythm complexity this weight is applied to the penalty of notes extending over subdivisions of the beat (inner-beat syncopes)

rhythmComplexityWeight: float = 0.001

Weight of the actual quantized rhythm. This includes evaluating synchopes, ties, etc.

syncopationMaxAsymmetry: float = 2.0

The max. ratio between the longer and the shorter parts to be mergeable as a syncopation

syncopationMinBeatFraction: Fraction = Fraction(1, 6)

How long can a synchopation be, in terms of the length of the beat

syncopationMinSymbolicDuration: Fraction = Fraction(1, 3)

Min. symbolic duration of a syncopation

tiedSnappedGracenoteMinRealDuration: Fraction = Fraction(1, 1000000)

The min. real duration of a tied snapped gracenote in order for it NOT to be removed

Methods Documentation

divisionPenalty(division)[source]

A penalty based on the complexity of the division of the pulse alone

Parameters:

division (tuple[int, ...]) – the division to rate

Returns:

float, debuginfo: str), where the penalty is an arbitrary number (lower=simpler division, higher=more complex) and debuginfo can be used to query how this penalty was calculated (debuginfo will only be filled if .debug is True)

Return type:

a tuple (penalty

static fromPreset(complexity='high', nestedTuplets=None, blacklist=None, **kws)[source]

Create a QuantizationProfile from a preset

Parameters:
  • complexity – complexity presets, one of ‘low’, ‘medium’, ‘high’, ‘highest’ (see maelzel.scoring.quantdata.presets)

  • nestedTuplets (Optional[bool]) – if True, allow nested tuplets.

  • blacklist (Optional[list[tuple[int, ...]]]) – if given, a list of divisions to exclude

  • kws – any keywords passed to QuantizationProfile

Return type:

QuantizationProfile

Returns:

the quantization preset

static makeSimple(maxSubdivisions=3, possibleSubdivisions=(1, 2, 3, 4, 5, 6, 8), maxDensity=16, allegroTempo=132, allegroMaxSubdivisions=1, allegroPossibleSubdivisions=(1, 2, 3, 4, 6), nestedTuplets=False, complexityPreset='medium', mintempo=1)[source]

Static method to create a simple QuantizationProfile based on a preset

Parameters:
  • maxSubdivisions – the max. subdivisions of a beat for tempi under allegro

  • possibleSubdivisions – the kind of subdivisions possible

  • maxDensity – the max. number of slots per quarter note

  • allegroTempo – tempo used to switch to the allegro subdivision profile. Set this very high to always use the slow profile, or set it very low to always use the high profile

  • allegroMaxSubdivisions – similar to maxSubdivisions, used for tempi which are higher than the value given for allegroTempo

  • allegroPossibleSubdivisions – similar to possibleSubdivisions, used for tempi higher than allegroTempo

  • nestedTuplets – are nested tuplets allowed? A nested tuple is a non-binary subdivision of the beat within a non-binary subdivision of the beat (something like (3, 5, 7), which divides the beat in three, each subdivision itself divided in 3, 5 and 7 parts)

  • complexityPreset – the preset to use to fill the rest of the parameters (one of ‘lowest’, ‘low’, ‘medium’, ‘high’, ‘highest’)

  • mintempo – the min. allowed tempo for the quarter note.

Return type:

QuantizationProfile

Returns:

a QuantizationProfile

possibleBeatDivisionsByTempo(tempo)[source]

The possible divisions of the pulse for the given tempo

Parameters:

tempo (Union[int, float, Rational, Fraction]) – the tempo to calculate divisions for. A profile can define different divisions according to different tempi (simpler divisions if the tempo is fast, more complex if the tempo is slow).

Return type:

list[tuple[int, ...]]

Returns:

a list of possible divisions for the given tempo.