Quantization is the process of moving all note starting positions to a specified and periodic grid. This "grid" does not have the be equi-spaced but it has to be periodic per quarter note.
quantize(notes::Notes, grid, duration = true) quantize(note::AbstractNote, grid, tpq::Integer)
Return a quantized copy of the given notes on the given
grid, which can be any sorted iterable that starts on
0 and ends on
Each note is quantized (relocated) to its closest point of the
grid, by first identifying that point using
classify. It is assumed that the grid is the same for all quarter notes of the track.
true, the function also quantizes the duration of the notes on the same grid, while ensuring a duration spanning at least one grid point.
This function respects the notes' absolute position and quantizes in absolute position, not relative.
Here are some examples
using MusicManipulations midi = readMIDIFile(testmidi()) notes = getnotes(midi, 4) sixteens = 0:1//4:1 notes16 = quantize(notes, sixteens) swung_8s = [0, 2//3, 1] swung_notes = quantize(notes, swung_8s)
533 Notes with tpq=960 Note F4 | vel = 69 | pos = 7360, dur = 320 Note A♯4 | vel = 85 | pos = 7680, dur = 640 Note D5 | vel = 91 | pos = 8320, dur = 320 Note D4 | vel = 88 | pos = 8320, dur = 320 Note G♯3 | vel = 88 | pos = 8320, dur = 320 Note A♯4 | vel = 76 | pos = 8640, dur = 640 Note G4 | vel = 66 | pos = 9280, dur = 320 ⋮ Note D5 | vel = 91 | pos = 189760, dur = 320 Note D5 | vel = 106 | pos = 190720, dur = 320 Note A4 | vel = 99 | pos = 190720, dur = 320 Note D♯4 | vel = 101 | pos = 190720, dur = 960 Note A3 | vel = 106 | pos = 190720, dur = 960 Note D4 | vel = 106 | pos = 190720, dur = 960 Note G4 | vel = 109 | pos = 190720, dur = 320
The first quantization quantized the notes on the 16-th subdivision. The second one did something a bit more specialized, as it separated the notes to "quarter notes" and swung 8th notes, the typical way a Jazz standard (like Serenade To A Cuckoo) is played.
quantize works in two steps. In the first step, each note is "classified", according to which is the closest grid point to this note (modulo the quarter note).
classify(notes::Notes, grid) classify(note::AbstractNote, grid, tpq::Integer)
Classify given notes according to the given grid.
Returns an integer (or vector of integers) that corresponds to the index of the closest grid point to the note position modulo the quarter note.
1 means start of the grid and
length(grid) means end of the grid (i.e. next quarter note).
After the notes have been classified, this classification vector is used to simply relocate all notes to the closest grid point (modulo the quarter note).
humanize!(notes, property, σ, noise = :ARFIMA; kwargs...)
notes by adding noise of standard deviation
σ to their
property, typically either
:velocity. Research[Datseris2019] suggests that
σ should be around 40 (for
:position) but that depends on the BPM, and around 10 for
noise argument decides the type of noise:
:ARFIMAuses ARFIMA.jl and attempts to generate a power-law correlated (pink) noise. Keywords
d = 0.25, φ = SVector(-0.5, -1.5)are propagated to function
:whiteplain ol' white noise.
humanize for a non-modifying version.
- Datseris2019Datseris, G., et al. Microtiming Deviations and Swing Feel in Jazz. Sci Rep 9, 19824 (2019)