A collection of C++ tools for MIDI and music development, built with the JUCE framework.
A namespace containing a Chord class, a Scale class, and utility functions for handling MIDI notes and chords.
MidiTools::Chord represents a musical chord. It can be constructed from a chord-name string (e.g. "CM", "Am7", "F#M") and exposes its constituent semitones as degrees (indices 0–6). Raw MIDI note arrays are used internally for the "chord played as is" mode.
MidiTools::Scale represents a diatonic or non-diatonic scale. Construct it with a root semitone (0–11) and a Scale::Type enum value. getNotes() returns the semitone set; fromScaleAndDegree() builds a Chord voiced from a given scale degree.
The Arpeggiator class drives a MIDI arpeggio engine. It takes a Chord, an octave, and a pattern string and generates time-stamped MIDI events.
Call prepareToPlay(sampleRate) once, then call processBlock(numSamples, midiChannel) every audio block. The method returns a juce::MidiBuffer containing any note-on / note-off events that fall inside the block.
The arpeggiator maintains a position (pos) in the pattern string that advances one musical step per call to the internal getNext() function. All state (global octave, global velocity, scope stack, root-relative flag) persists between calls.
The pattern string is read character by character. A step is any single note command. Prefix commands are consumed before the note command of the same step and modify how that note (or subsequent notes) sounds.
| Command | Description |
|---|---|
1 – 9 |
Plays a specific degree of the chord/scale (1 = root, 2 = second, …). |
+ |
Advances to the next chord degree (wraps). |
- |
Goes back to the previous chord degree (wraps). |
? |
Plays a random valid degree from the chord. |
= |
Repeats the last played degree. |
_ |
Sustains the previous note (no new note-on). |
. |
Rest — no note is played. |
| Command | Description |
|---|---|
# |
Raises the next note by one semitone (local, one step only). |
b |
Lowers the next note by one semitone (local, one step only). |
Velocity levels 1–8 map to MIDI velocities 16–127.
| Command | Description |
|---|---|
vN |
Local — sets velocity for the next note only (N = 1–8). |
v+ |
Local — increases velocity one level for the next note only. |
v- |
Local — decreases velocity one level for the next note only. |
VN |
Global — sets velocity for all subsequent notes until the next V command. |
V+ |
Global — increases velocity one level for all subsequent notes. |
V- |
Global — decreases velocity one level for all subsequent notes. |
| Command | Description |
|---|---|
oN |
Local — sets octave to N (0–7) for the next note only. |
o+ |
Local — increases octave by one for the next note only. |
o- |
Local — decreases octave by one for the next note only. |
ON |
Global — sets octave to N for all subsequent notes. |
O+ |
Global — increases octave by one for all subsequent notes. |
O- |
Global — decreases octave by one for all subsequent notes. |
Block commands wrap one or more steps and alter the evaluation context for everything inside them.
When the parser encounters ( it pushes the current global octave and global velocity onto an internal scope stack. When it encounters ) it pops the stack, restoring both values. Any O+/O-/V+/V- (or absolute ON/VN) used inside the parentheses therefore have no lasting effect outside the block.
1 2 (O+ 1 2 3) 1 2
Steps 3–5 are played one octave higher; the global octave is restored for steps 6 and 7. Parentheses may be nested.
In scale chord-method mode the arpeggiator normally voices notes relative to the degree of the currently pressed MIDI note within the selected scale. Steps placed between double-quotes are instead voiced relative to degree 0 of the scale (the scale root), regardless of which key is held.
1 2 "1 2 3" 4
Steps 3–5 always follow the root of the scale; steps 1, 2, 4 follow the pressed note's degree as usual.
The root chord is supplied by the host via setRootChord(). In non-scale modes the "…" block has no effect.
Note:
"is a block delimiter and is not a note command. Use=to repeat the last degree.
| Method | Description |
|---|---|
setChord(chord) |
Sets the chord the arpeggiator voices against. |
setRootChord(chord) |
Sets the chord used inside "…" root-relative blocks. |
setPattern(string) |
Sets a new pattern string and resets position and scope state. |
setTempo(bpm) |
Sets the tempo in BPM. |
setSubdivision(index) |
Sets the note subdivision (0 = 1/4, 4 = 1/16, …). |
setChordMethod(index) |
0 = notes played, 1 = chord as is, 2 = scale/single note. |
setBaseOctaveFromNote(midi) |
Derives the base octave from an incoming MIDI note number. |
numSteps() |
Returns the number of musical steps in the current pattern. |
getPatternIndexForStep(n) |
Maps a step index to its character position in the pattern string. |
getLastPlayedNote() |
Returns the last MIDI note number that was output (-1 if none). |
makeEuclidianPattern(hits, steps, rot) |
Generates a Euclidean rhythm pattern string. |
makeRandomPattern() |
Generates a random but balanced pattern string. |
reset() |
Resets position, octave, velocity, and scope state. |
turnOff() |
Generates a note-off for the last played note and resets state. |