Skip to content

Track Generators

This document details each track generator in MIDI Sketch.

New to music theory?

The tracks below map onto musical roles — melody, chords, bass, motif, arpeggio. If those terms are new, start with the Course; it teaches the concepts behind every generator with playable notation.

Track Overview

MIDI Sketch generates 9 tracks across different MIDI channels:

The nine tracks and the MIDI channel each one is written to Five groups of tracks. The melody layer holds vocal on channel 0 and aux on channel 5; harmony holds chord on channel 1 and guitar on channel 6; the rhythm section holds bass on channel 2 and drums on channel 9; the synth layer holds motif on channel 3 and arpeggio on channel 4; and a markers group holds the SE track on channel 15. Each box also shows the built-in fallback GM program, which a mood preset may replace, and the role the track plays. Melody Layer Vocal Ch 0 Piano (0) main melody Aux Ch 5 Warm Pad (89) sub-melody support Harmony Chord Ch 1 E.Piano (4) harmonic backing Guitar Ch 6 E.Guitar clean (27) accompaniment Rhythm Section Bass Ch 2 E.Bass (33) harmonic foundation Drums Ch 9 GM drum kit rhythm Synth Layer Motif Ch 3 Synth Lead (81) for BackgroundMotif Arpeggio Ch 4 Synth Lead (81) for SynthDriven Markers SE Ch 15 text events only section markers No notes are written here — the SE track just names each section boundary. Track-to-channel assignment is fixed; the GM program shown is only the built-in fallback, and a mood preset may replace it. Channel 9 is the GM percussion channel, so the drum track ignores its program number altogether. Nine tracks on nine fixed channels — a DAW can swap every sound without disturbing the arrangement.

Channel Assignment

TrackChannelDefault ProgramRole
Vocal0Piano (0)Main melody
Chord1E.Piano (4)Harmonic backing
Bass2E.Bass (33)Harmonic foundation
Motif3Synth Lead (81)BackgroundMotif style
Arpeggio4Synth Lead (81)SynthDriven style
Aux5Warm Pad (89)Sub-melody support
Guitar6E.Guitar clean (27)Accompaniment guitar
Drums9GM DrumsRhythm
SE15-Section markers

Mood-Dependent Programs

The programs above are the built-in fallbacks (src/midi/track_config.h). The actual GM program for each track is selected per mood (getMoodPrograms), so the instruments you hear vary with the mood preset.

Vocal Track

Source: src/track/generators/vocal.cpp, src/track/vocal/melody_designer.cpp

The vocal system uses a template-driven melody designer with style-aware evaluation for predictable, stylistically-accurate melody generation.

Why "Vocal" Track?

The Vocal track generates the main melody line. It's called "Vocal" because it's designed to be sung or played as the lead part. Use MIDI channel 0 (piano) in your DAW to preview it, or assign any instrument you prefer.

Architecture

The vocal generation consists of three major components:

  1. MelodyDesigner (melody_designer.cpp) - Template-driven pitch selection with evaluation
  2. Vocal Generator (vocal.cpp) - Section structure, caching, and coordination
  3. VocalStyleProfile - Unified bias and evaluation configuration per style
How the three vocal components fit together A left-to-right pipeline. VocalStyleProfile sits on the left and supplies two things: a StyleBias that shapes which notes get generated, and an EvaluatorConfig that weights how candidates are judged. MelodyDesigner in the middle generates a batch of candidate phrases, scores each one, culls the bottom half and then picks probabilistically from what remains. The Vocal Generator on the right runs the constraint pipeline, stores the phrase in a cache keyed on section type, bar count and starting chord degree, and writes the result to the vocal track. per vocal style VocalStyleProfile StyleBias shapes what gets written EvaluatorConfig weights how it is judged One profile per style keeps generation and scoring in step. MelodyDesigner generate candidates chorus 100 · B 50 · bridge 30 · elsewhere 20 score each candidate style 40% · culling 40% · bias 20% plus a global-motif bonus weighted by section keep the top half, then pick by weight the top-scoring candidate is a fallback, not an automatic winner Vocal Generator constraint pipeline voice leading, safe pitch, octave fold into range phrase cache keyed on section type, bar count and starting chord degree write to the vocal track one MidiTrack, channel 0 The profile is read twice — once to bias what is generated, once to weight what survives.

Melody Templates

7 melody templates define melodic characteristics:

IDNamePlateauMax StepUse Case
0Auto--VocalStyle-based selection
1PlateauTalk0.702Talk-like, narrow-range pop
2RunUpTarget0.203Anime high-energy, dramatic pop
3DownResolve0.402B-section, pre-chorus
4HookRepeat0.552Short-form, K-POP hooks
5SparseAnchor0.304Sparse, sustained ballad phrasing
6CallResponse0.353Duet patterns
7JumpAccent0.255Emotional peaks
  • Plateau ratio: Probability of staying on the same pitch (higher = more repetitive)
  • Max step: Maximum step size in semitones (lower = smoother)

Generation Flow

What happens when a section asks for a vocal phrase A section begins and the phrase cache is looked up with a key made of section type, bar count and starting chord degree. On a hit the stored phrase is reused, shifted to this section's start and re-fitted to the range. On a miss a MelodyTemplate is chosen, a phrase is generated, scored and cached. Either way one phrase comes out and passes through the same tail: voice leading, HarmonyContext.getSafePitch, an octave fold back into the vocal range, and finally the write to the vocal track. a section starts verse, chorus, bridge… phrase cache look up the phrase cache key = section type + bar count + starting chord degree hit reuse the phrase shifted to this section and re-fitted to its range miss design a new phrase pick a MelodyTemplate, generate, score, then cache one phrase for this section then, for every phrase voice leading smooth motion from the last note HarmonyContext.getSafePitch keeps it consonant with the rest octave fold ±12 back into the vocal range add to the vocal track A reused phrase is only lightly varied — a shifted or lengthened last note, a breath rest, an accent, an echo. Only a cache miss runs the full designer; a hit still goes through the same constraint stage.

Octave Fold (Range Safety)

Notes that land outside the allowed range are folded by octaves (±12 semitones) back into range, preserving the pitch class — a chord tone stays a chord tone. A chromatic clamp to the range boundary is used only as a last resort, because clamping can turn a safe note into a dissonance (e.g. G folded down an octave stays G, while clamping G to a ceiling of F# would create a tritone).

Pitch Selection (4 Choices Only)

The MelodyDesigner limits pitch selection to 4 options:

cpp
enum class PitchChoice {
    Same,       // Stay on current pitch (plateau_ratio)
    StepUp,     // Up one scale step (whole step preferred over half)
    StepDown,   // Down one scale step
    TargetStep  // Move toward the template's target pitch, bounded by max_step
};

This constrained approach produces more natural, singable melodies.

Vocal Attitudes

AttitudeDescriptionImplementation
CleanConservative, singableChord tones only, on-beat
ExpressiveEmotional, dynamicTensions allowed, timing variance
RawEdgy, unconventionalNon-chord tones, boundary breaking

Phrase Caching

Phrases are cached using a composite key (V2 cache) to ensure musical coherence:

cpp
struct PhraseCacheKey {
    SectionType section_type;  // A, Chorus, etc.
    uint8_t bars;              // Section length in bars
    int8_t chord_degree;       // Starting chord degree
};

The first reuse of a cached phrase is always exact, so the phrase is established before it is varied. After that, the chance of an exact repeat falls with each chorus occurrence: 80% on the first occurrence, 60% on the second, 30% from the third onward, so the final chorus is the freshest. Exact repetition is also forced to stop after two consecutive identical statements.

Phrase Variation

When a reuse is not exact, one of six variations is applied. All of them preserve the melodic identity of the phrase — none of them transpose, invert or re-cut it:

  • LastNoteShift: Move the final note by one or two scale degrees
  • LastNoteLong: Extend the final note for a more dramatic ending
  • BreathRestInsert: Insert a short rest before the phrase ends
  • DynamicAccent: Raise the final note's velocity
  • LateOnset: Start the phrase a sixteenth note late
  • EchoRepeat: Echo the final note, shorter and quieter

Range Constraints

cpp
struct VocalRangeResult {
    uint8_t effective_low;
    uint8_t effective_high;
    float velocity_scale;
};

The effective range starts with the singer bounds (vocal_low and vocal_high), then applies the Blueprint max_pitch ceiling and reserves headroom for a later upward modulation by lowering the effective high bound by the modulation amount. The lower bound is preserved. When positive modulation is requested, the adjusted high is clamped so at least one octave remains; a Blueprint max_pitch cap without modulation may produce a narrower span. Composition styles change velocity_scale; they do not create a separate foreground/background vocal range. Motif-follow-vocal behavior is a separate constraint: when a vocal exists, the motif generator still narrows its register around the vocal median.

Non-Chord Tone Decoration

The vocal track uses non-chord tones (NCT) to add melodic interest beyond simple chord-tone melodies:

Beat strength

The engine grades beats four ways in 4/4: strong (beats 1 and 3), medium (beats 2 and 4), weak (off-beat 8ths) and very weak (16ths). Chord tones and accented appoggiaturas belong on strong beats; passing tones, neighbour tones and anticipations go on the weak subdivisions between beats, not on beats 2 and 4.

NCT TypeDescriptionPlacement
ChordToneNotes belonging to the current chord (baseline)Strong beats
PassingToneStepwise connection between two chord tonesOff-beat subdivisions
NeighborToneStep away from a chord tone and returnOff-beat subdivisions
AppoggiaturaAccented dissonance that resolves by stepStrong beats
AnticipationEarly arrival of the next chord's toneOff-beat subdivisions, before the chord change
SuspensionA tone held over from the previous chord, resolving down by stepStrong beat, resolving on the following weak one
TensionExtended chord tones (9th, 11th, 13th)Based on style

Configuration varies by mood:

  • Bright: More chord tones, less dissonance
  • Jazzy: More tensions, syncopation
  • Ballad: Balanced with expressive appoggiaturas
  • J-POP: Prefers pentatonic scale (yonanuki) intervals

VocalStyleProfile

Each vocal style has a unified profile that controls both generation bias and evaluation weights. Eight profiles are shared across the fourteen vocal styles (Idol/BrightKira/CuteAffected → Idol; Vocaloid/UltraVocaloid/CoolSynth → Vocaloid; Rock/PowerfulShout → Rock; Auto/Standard → Standard):

ProfilePlateau BiasHigh RegisterSingabilitySurprise
Standard1.000.800.150.15
Idol1.250.850.180.05
Rock0.801.200.150.20
Ballad1.000.500.300.05
Anime1.301.300.100.15
Vocaloid0.901.200.100.20
CityPop0.900.900.150.15
KPop1.401.100.120.18

UltraVocaloid Mode

Enhanced Vocaloid-style generation with:

  • Machine-gun rhythm: Rapid-fire 16th note sequences characteristic of Vocaloid songs
  • Breathing points: Automatic insertion of micro-pauses for phrasing even in dense passages
  • Per-section rhythm lock: Each section maintains consistent rhythmic identity
Profile Parameters
  • Plateau Bias: Preference for staying on the same pitch (higher = more repetitive)
  • High Register: Preference for high notes (higher = brighter)
  • Singability: Weight for human-singable melodies (higher = easier to sing)
  • Surprise: Weight for unexpected melodic turns (higher = more dynamic)

Melody Evaluation System

The MelodyDesigner generates a batch of candidate melodies — 100 for a chorus, 50 for a B section, 30 for a bridge or chant, 20 everywhere else — and scores each one:

The shared scoring reference is Melody Evaluation; this page keeps only the track-level wiring and constraints.

How a batch of candidate melodies is scored and one of them chosen A batch of candidate phrases is generated — a hundred for a chorus, fifty for a B section, thirty for a bridge, twenty elsewhere. Each candidate is scored three ways: a style score worth forty percent, a penalty-based culling score worth forty percent, and an interval bias score worth twenty percent. The three combine into one score, plus a global-motif bonus whose weight depends on the section. The candidates are then sorted, the bottom half is discarded, and one of the survivors is drawn at random with higher scores given higher odds. candidates chorus 100 · B 50 bridge 30 · rest 20 style score 40% contour match, pattern consistency, surprise balance culling score 40% penalties for singing difficulty, monotony, awkward gaps bias score 20% interval mix against the style's own preference combined score 40 / 40 / 20, plus a motif bonus weighted by section selection sort, highest first stable, so ties break the same way cull the bottom half only the top 50% stay in the draw weighted random pick higher score, higher odds Scoring narrows the field; the final pick stays random inside it, so equally good phrases stay in rotation.

Combined score:

ComponentWeightCriteria
Style score40%Seven weighted qualities, listed below
Culling score40%Penalty-based: singing difficulty, monotony, awkward gaps
Bias score20%Interval distribution matching style preferences

A global-motif bonus is added on top, weighted by section: 0.35 in the chorus, 0.25 in a repeated A section, 0.22 in B, 0.15 in the first A section and 0.05 in the bridge, where contrast is wanted instead.

The style score is itself seven components whose weights come from the vocal style profile and sum to 1.0. The values below are the Standard profile:

ComponentStandard weightCriteria
Singability0.15Interval distribution: step-heavy, few large leaps
Chord tone ratio0.15Chord tones landing on strong beats
Contour0.15Recognisable arch / wave / descending shape
Surprise0.15One or two deliberate leaps of a 4th or more
AAAB pattern0.15Three-plus-one repetition structure
Rhythm-interval fit0.15Long note before a leap, short note for a step
Catchiness0.10Short-cell repetition, rhythmic consistency, hook contour

The culling score starts at 1.0 and subtracts penalties: consecutive high notes, a leap onto a high note, rapid direction changes, non-chord tones on strong beats, melodically isolated notes, low phrase cohesion, excessive silence, and breathless runs of short notes.

Candidates are then sorted by combined score, the bottom half is discarded, and one of the survivors is drawn at random with higher scores weighted more heavily. The top-scoring candidate is only the fallback, so equally good phrases stay in rotation.

Hook System

Chorus sections use a dedicated hook generation system built from 17 rhythm patterns and 25 hook skeletons. The most common are:

Common rhythm patterns:

PatternRhythmCharacter
Buildup8-8-4Classic step resolution
Syncopated4-8-8Syncopated start
FourNote8-8-8-4High energy
Powerful4-4Simple, strong
Dotted8-4-8Dotted rhythm feel
CallResponse4-8-8-8Call and response

Common hook skeletons:

SkeletonDescription
RepeatSame pitch repeated
AscendingRising contour
AscendDropRise then fall
LeapReturnJump and return
RhythmRepeatPitch varies, rhythm constant

Hook Intensity controls hook prominence:

  • Off (0): No hook emphasis
  • Light (1): Chorus start only
  • Normal (2): Chorus start and middle
  • Strong (3): All hook points
  • Maximum (4): Maximum repetition, simple patterns only

Global Motif System

The vocal track extracts a global motif from the chorus hook and uses it as a light evaluation bonus for later sections — it biases selection, it does not constrain generation:

cpp
struct GlobalMotif {
    ContourType contour_type;        // Ascending, Descending, Peak, Valley, Plateau
    int8_t  interval_signature[8];   // Relative pitch changes
    uint8_t interval_count;
    uint8_t rhythm_signature[8];     // Relative duration ratios
    uint8_t rhythm_count;
};

Each section compares its candidates against a transformation of the motif chosen to suit that section: the original in the chorus, a diminished version in A, a sequenced version in B, an inverted version in the bridge and a fragmented version in the outro. The bonus is then scaled by the section weights listed above, so the chorus preserves the hook identity most strongly and the bridge is left free to contrast.

Piano Roll Safety API

Source: src/core/piano_roll_safety.cpp

The read-only Piano Roll Safety API helps external tools such as piano roll editors display pitch-placement warnings. checkBgmCollisionDetailed checks sounding notes in six BGM tracks (Chord, Bass, Arpeggio, Aux, Motif and Guitar) by pitch-class interval. It reports Severe for interval classes 1 or 11, Mild for class 6, and None otherwise. This display helper does not apply chord, duration, register or generator-specific exceptions; the generator's separate HarmonyContext filter is described in Harmony.

cpp
enum class CollisionType : uint8_t {
    None,    // No display warning
    Mild,    // Pitch-class interval 6: display warning
    Severe   // Pitch-class intervals 1/11: display warning
};

Collision Detection:

Pitch-class intervalTypeDisplay result
1 or 11SevereSevere display warning
6MildMild display warning
Other classesNoneNo display warning

Modulation Awareness

The generated vocal range starts with the singer bounds, is capped by the Blueprint's max_pitch, and reserves upward modulation headroom by reducing effective_vocal_high. The read-only display helper is independent of that range calculation: it reports pitch-class collisions and does not create a separate foreground-motif range.


Aux Track

Source: src/track/generators/aux.cpp

The Aux (auxiliary) track provides sub-melody support when a main vocal exists. In BackgroundMotif, Vocal is always skipped; Traditional/MelodyDriven run Aux before Motif without a vocal reference, while RhythmSync keeps Motif before Aux. SynthDriven skips Aux. Aux is not a counter-melody, but a layer that shapes the arrangement around the lead when one is present.

Purpose

RoleDescription
AddictivenessPulse loops create repetitive, catchy patterns
PhysicalityGroove accents add body movement feel
StabilityPhrase tails provide resolution
StructureHelps listeners perceive section boundaries

Aux Functions

9 auxiliary functions are available:

IDFunctionDescription
0PulseLoopRepetitive same-pitch or fixed-interval patterns
1TargetHintHints at vocal target with chord tones
2GrooveAccentRhythmic accents with staccato
3PhraseTailEnd-of-phrase descending resolution
4EmotionalPadLong sustained chord tones
5UnisonVocal unison doubling
6MelodicHookMelodic hook riff
7MotifCounterCounter melody (contrary motion)
8SustainPadWhole-note chord tone pad

Aux Function Selection

For the main song sections the aux function comes from the Blueprint's aux profile, not from the melody template:

SectionSource
IntroAn echo of the cached chorus motif, or aux_profile.intro_function when no motif is cached
A / B / Bridgeaux_profile.verse_function
Chorusaux_profile.chorus_function

So a Traditional blueprint runs MelodicHook in the intro, MotifCounter in the verses and MelodicHook again in the chorus, while RhythmLock holds a single PulseLoop cell throughout. The remaining section types — interlude, outro, chant, mix break — fall back to the first aux configuration the melody template defines:

TemplateFallback functionRange offsetWidthVelocity ratio
PlateauTalkPulseLoop-1250.6
RunUpTargetTargetHint070.5
DownResolvePhraseTail050.5
HookRepeatPulseLoop-1240.7
SparseAnchorEmotionalPad-580.4
CallResponseMotifCounter060.7
JumpAccentPhraseTail050.5

Generation Constraints

  • Generated after Vocal when Vocal is present, so its pitches can avoid the lead; with BackgroundMotif, Traditional/MelodyDriven run Aux before Motif because Vocal is absent, while RhythmSync keeps Motif before Aux. SynthDriven does not generate Aux
  • When a vocal exists, the range is an absolute semitone width — 4 to 12 semitones wide — centred on its tessitura and offset by the section's range_offset; without a vocal it uses the configured/default tessitura. In both cases it is clamped to G3 (55) - C6 (84)
  • Velocity ratios of 0.4-0.8 scale a fixed base velocity of 80, not the vocal note's own velocity; a blueprint's velocity_scale multiplies that ratio
  • Uses HarmonyContext to avoid dissonance with vocal

Chorus Behavior

In chorus sections, Aux track adapts its behavior:

  • Reduced density: Aux takes a backseat to let vocal shine
  • Lower register: Moves to lower range to avoid vocal collision
  • Simplified patterns: Uses more sustained notes, less busy patterns
  • Phrase endings: Respects phrase boundaries with proper resolution

Chord Track

Source: src/track/generators/chord.cpp

Generates harmonic voicings with voice leading optimization.

Voicing Types

The three chord voicing shapes, read low note at the bottom Three stacks of the same chord tones. A close voicing packs root, third, fifth and seventh into a single octave. An open voicing takes that stack and drops the second voice from the top an octave, so the fifth ends up below the root; Drop 3 and Spread are its other variants. A rootless voicing leaves out the root the bass is already holding and stacks third, fifth, seventh and, when only two voices would remain, a ninth. Whichever candidate moves least from the previous chord is the one that gets used. close 7th 5th 3rd root Packed into a single octave. An adjacent major 2nd is rejected unless the chord is built on one. open 7th 3rd root 5th, an octave down With four voices the second from the top drops an octave. Drop 3 and Spread are the other variants. rootless 9th, if needed 7th 5th 3rd The bass already holds the root, so it is left out; a 9th (or 11th) fills the gap when two would remain. chosen by voice leading the candidate that moves least from the previous chord wins rootless when the bass covers the root a pitch-class mask of the bass on beats 1 and 3 decides it All three hold the same chord tones — only the spacing, and what the bass makes redundant, differ.

Three voicing types are available. Close packs the chord tones into a single octave. Open is a Drop 2 voicing: the second voice from the top drops an octave, so a root-3rd-5th-7th stack becomes 5th-root-3rd-7th; Drop 3 and Spread are its other variants, selected per section and mood. Rootless omits the root the bass is already holding and adds a 9th when only two voices would otherwise remain.

Voice Leading Algorithm

  1. Generate candidates from the section's voicing type (close, open/Drop2, Drop3, spread, rootless)
  2. Score each by weighted movement from the previous voicing — the outer voices (bass and soprano) count double, the inner voices once, over up to five pitches
  3. Reward retained common tones
  4. Penalise parallel 5ths and octaves, by an amount that depends on the mood: strict for classical and sophisticated moods, relaxed for pop and dance
  5. Penalise a voicing identical to the previous one three times running

Bass Coordination

The chord track is generated after the bass, so it can read what the bass is actually playing. Two mechanisms use that:

  • buildBassPitchMask collects the pitch classes the bass sustains across beats 1 and 3 of the bar, and candidate voicings that would clash with them by a minor 2nd or a tritone are rejected.
  • BassAnalysis::analyzeBar reports whether the bass states the root on beat 1. When it does, a rootless voicing becomes the preferred choice, so the root is not doubled.

Register Constraints

cpp
constexpr uint8_t CHORD_LOW = 48;   // C3
constexpr uint8_t CHORD_HIGH = 84;  // C6

Guitar Track

Source: src/track/generators/guitar.cpp

The Guitar track generates accompaniment guitar patterns on a dedicated MIDI channel (Ch 6). It provides rhythmic and harmonic support that complements the chord track.

Parameters

ParameterDefaultDescription
guitarEnabledtrueEnable/disable guitar track generation (default enabled in both JS and C++)

Blueprint Constraints

Guitar generation is influenced by Blueprint constraints:

ConstraintDescription
guitar_skillSkill level (Beginner/Intermediate/Advanced/Virtuoso) affecting pattern complexity and voicing sophistication
guitar_below_vocalWhen enabled, keeps guitar voicings below the vocal register (vocal_low - 2 semitones) to avoid masking the melody
guitar_style_hintPer-section style hint (0-7) defined in the Blueprint's SectionSlot. 0 = auto-select based on mood and energy

Generation

  • Guitar is generated after the chord track, allowing it to complement existing harmonic voicing
  • Patterns adapt to section energy and mood
  • Per-section guitar_style_hint (0-7) in the Blueprint's SectionSlot can influence the style of guitar accompaniment
  • Guitar appears on MIDI channel 6 with Electric Guitar clean (program 27) as the fallback program; moods can assign a different guitar program

Bass Track

Source: src/track/generators/bass.cpp

Generates the harmonic foundation with root-focused patterns.

Pattern Types

BassPattern has 17 values. The active pattern is selected automatically based on mood and section, or pinned per section via bass_style_hint in the Blueprint's SectionSlot (0=auto, 1-17 maps to BassPattern+1). Common ones:

PatternDescriptionRhythm
WholeNoteSustained roots for stability (ballad, intro)Half notes, approach into the next bar
RootFifthClassic pop root-fifth alternationQuarter notes, fifth on beat 3
SyncopatedOff-beat accents for groove (pre-chorus)Root with an off-beat fifth
DrivingEnergetic, forward (chorus)Eighth notes throughout
WalkingQuarter-note scale walk (jazz, city pop)Four quarter notes, chromatic approach

The rest cover genre-specific cases: RhythmicDrive, PowerDrive, Aggressive, SidechainPulse, Groove, OctaveJump, PedalTone, Tresillo, SubBass808, RnBNeoSoul, SlapPop and FastRun.

Generation Logic

How one bar of bass is built The bar's chord supplies a root and a chord function. A pattern is then chosen — automatically from the mood and section type, out of seventeen patterns, or pinned per section by the Blueprint's bass_style_hint where zero means auto. The root is only shifted by an octave when that is what keeps it inside the E1 to G3 bass range. Across the bar the root lands on beat 1, the middle beats follow the pattern, and the second half of beat 4 carries an approach note into the next bar's root — usually a fifth below, with a chromatic half step reserved for walking lines. the bar's chord root and chord function pattern choice auto: mood and section type 17 patterns, from whole notes to 16th runs bass_style_hint per section — 0 = auto, 1–17 pins a pattern octave, for range only moved up or down purely to stay inside E1–G3 The chord's function shapes how the bass approaches the next bar's root. one bar, four beats beat 1 the root lands here beat 2 pattern-dependent beat 3 pattern-dependent beat 4, second half an approach note into the next bar's root, usually a 5th below; a chromatic half step in walking lines Section type steers which pattern is used; the octave only ever moves to keep the note playable.

The section type steers which pattern is used, but it never shifts the octave. The root only moves by an octave when that is what keeps it inside the bass range of E1 (28) to G3 (55).

Peak handling runs after pattern selection. PeakLevel::Medium promotes the selected pattern one density level and PeakLevel::Max promotes it twice. This applies to an explicit bass_style_hint as well as to an automatically selected pattern: the hint names the base pattern, while the peak still adds density.

Approach Notes

The second half of beat 4 usually carries an approach note into the next bar's root. The choice is chord-function aware rather than always chromatic: a perfect 5th below the target for tonic and dominant chords, a step below for subdominants, with the leading tone, a step above and a perfect 4th below as fallbacks. Any candidate that would clash with a tone the target chord actually sounds is rejected, which matters for secondary dominants, whose third is raised and seventh lowered relative to the diatonic triad.

A chromatic half step below the target is reserved for walking lines, and only when the next root is a whole step or a minor 3rd away.


Drums Track

Source: src/track/generators/drums.cpp

Generates drum patterns with fills and dynamics.

GM Drum Map

cpp
constexpr uint8_t KICK = 36;
constexpr uint8_t SNARE = 38;
constexpr uint8_t SIDE_STICK = 37;
constexpr uint8_t CLOSED_HH = 42;
constexpr uint8_t OPEN_HH = 46;
constexpr uint8_t RIDE = 51;
constexpr uint8_t CRASH = 49;
constexpr uint8_t TOM_HIGH = 50;
constexpr uint8_t TOM_MID = 47;
constexpr uint8_t TOM_LOW = 45;

Pattern Styles

Which drum style each mood preset resolves to The mood preset selects one of eight drum styles, unless a Blueprint pins one with drum_style_hint, where zero means auto. Sparse covers Ballad, Chill, Lofi and EmotionalPop. Standard covers StraightPop, CityPop, Sentimental, Nostalgic and RnBNeoSoul. FourOnFloor covers EnergeticDance, ElectroPop and DarkPop. Upbeat covers BrightUpbeat, MidPop, ModernPop, IdolPop and Anthem. Rock covers LightRock and Dramatic. Synth covers AnimeHighEnergy, Synthwave and FutureBass. Trap and Latin each serve a single mood. mood preset 24 presets, one drum style each drum_style_hint Blueprint override — 0 = auto DrumStyle Sparse Ballad · Chill · Lofi · EmotionalPop Standard StraightPop · CityPop · Sentimental · Nostalgic · RnBNeoSoul FourOnFloor EnergeticDance · ElectroPop · DarkPop Upbeat BrightUpbeat · MidPop · ModernPop · IdolPop · Anthem Rock LightRock · Dramatic Synth AnimeHighEnergy · Synthwave · FutureBass Trap Trap half-time snare, 16th hats Latin LatinPop dembow kick-snare figure The style holds for the whole song and sets the kick, snare and hi-hat grid every fill is written against.

Fill Types

FillType has 13 members. The common ones are SnareRoll, TomDescend, TomAscend and SnareTomCombo; the rest cover sparser and more idiomatic cases — SimpleCrash, LinearFill, GhostToAccent, BDSnareAlternate, HiHatChoke, TomShuffle, BreakdownFill, FlamsAndDrags and HalfTimeFill. selectFillType() picks one from the section pair, the drum style and the next section's energy.

A fill does not have to cover every beat of its window; when a fill type has nothing to say on a beat, the section's ordinary pattern is kept there rather than leaving silence.

Fills are inserted at:

  • Section transitions
  • Every 4 or 8 bars
  • Before chorus

For a Dramatic or DrumHit chorus drop, the final drop zone also truncates the kit. If that cut removes an entry crash, post-processing restores the crash at the next section boundary so the chorus still has an arrival marker.

Euclidean Drums

Blueprints provide euclidean_drums_percent, which the drum generator samples when choosing the Euclidean branch. The field is currently classified as UnprovenLiveness in Blueprint accounting, so its audible effect is not guaranteed; treat it as reserved rather than as a reliable tuning control.

Drum Role

Per-section drum_role in the Blueprint's SectionSlot controls drum behavior:

RoleDescription
FullStandard full drum kit
AmbientSubdued, atmospheric
MinimalSparse, minimal patterns
FXOnlySound effects only, no standard kit

Ghost Notes

Velocity-reduced snare articulations for groove:

cpp
// Ghost velocity is a multiplier on the section velocity (0.25-0.65),
// not an absolute value; ghosts land in roughly the 25-35 band.

Density is a table lookup by section and mood category, giving 0%, 15%, 30% or 45%, then adjusted for tempo and backing density:

  • Energetic moods (EnergeticDance, IdolPop, Anthem, AnimeHighEnergy): up to 45% ghost probability in the chorus
  • Calm moods (Ballad, Sentimental, Chill): none in verses, light elsewhere

Swing Timing

Swing only applies when the mood's groove feel is Swing or Shuffle — Sentimental, Chill, Ballad, Nostalgic and CityPop swing; RnBNeoSoul and Lofi shuffle. Every other mood is straight and the offset is zero.

SectionSwing amountBehaviour
Intro0.25Lightest
A / Bridge / Interlude / MixBreak0.35Constant
B0.40Constant
Chorus0.50Deepest, constant
Outro0.40 → 0.20Quadratic decay to the end

The amount is held constant within a section on purpose; bar-to-bar drift makes the groove feel unstable. A Blueprint SectionSlot can override it via swing_amount (0.0-0.7).

Swing is not a separate grid. Off-beat notes are pushed toward the triplet position by swing_amount: up to +80 ticks on the 8th-note grid and +40 on the 16th-note grid, so swing_amount = 1.0 lands exactly on the triplet. Shuffle multiplies the amount by 1.5 before clamping.

Humanization

Subtle timing and velocity variations make patterns feel less mechanical:

  • Timing jitter: ±5-15 ticks from grid
  • Velocity variation: ±5-10 from base velocity
  • Hi-hat accent patterns: Natural emphasis on downbeats

Vocal Synchronization

When drums_sync_vocal is enabled, kick drums align with vocal onset positions:

cpp
void generateDrumsTrackWithVocal(
    MidiTrack& track,
    const Song& song,
    const GeneratorParams& params,
    std::mt19937& rng,
    const VocalAnalysis& vocal_analysis  // Pre-analyzed vocal data
);

This "rhythm lock" effect makes the groove follow the melody, common in modern pop production.


Motif Track

Source: src/track/generators/motif.cpp

For BackgroundMotif composition style (BGM-only mode). Vocal is always skipped; the motif is the primary melodic element. The generator also runs for SynthDriven, the RhythmSync paradigm, and Blueprint section flows that request it.

Parameters

cpp
struct MotifParams {
    MotifLength length;                 // Bars1, Bars2 (default), Bars4
    uint8_t note_count;                 // 3-8 notes per cycle, default 6
    bool register_high;                 // false = mid, true = high
    MotifRhythmDensity rhythm_density;  // Sparse, Medium (default), Driving
    MotifMotion motion;                 // Stepwise, GentleLeap, WideLeap,
                                        // NarrowStep, Disjunct, Ostinato
    MotifRepeatScope repeat_scope;      // FullSong (default), Section
};

MotifLength counts bars, not beats. The register is a boolean, not an enum — there is no MotifRegister type.

Override Parameters

When motif overrides are specified in the config, the following parameters take precedence over style defaults:

ParameterTypeDescription
motifLengthint (0=auto, 1/2/4)Override motif length in bars (0 defaults to 2 bars)
motifNoteCountint (0=auto, 3-8)Override number of notes in the motif (0 defaults to 6)
motifMotionint (0xFF=preset, 0-5)Override motion type (0=Stepwise, 1=GentleLeap, 2=WideLeap, 3=NarrowStep, 4=Disjunct, 5=Ostinato)
motifRegisterHighint (0=auto, 1=low, 2=high)Override the register the motif builds from
motifRhythmDensityint (0xFF=preset, 0-2)Override rhythm density (0=Sparse, 1=Medium, 2=Driving)

Pattern Generation

How a motif pattern is built, and what the motion type changes A motif starts from a base note — 67 in the high register, 60 otherwise. Rhythm positions come next, derived from the rhythm density and the motif length, or taken from a locked rhythm template. The note count is clamped to between three and eight, six by default. Only then is the pitch sequence generated, one step per note, with the step size set by the motion type: Stepwise stays on 2nds, GentleLeap reaches a 3rd, WideLeap a 5th, NarrowStep moves one scale degree, Disjunct leaps irregularly, and Ostinato repeats a single pitch class. Repeat scope then decides whether one pattern serves the whole song or each section gets its own — unless the riff policy has already forced a fresh pattern per section. base note high register starts at 67, otherwise at 60 rhythm positions from density and length — or a locked rhythm template note count 3–8 notes per cycle, 6 by default pitch sequence one step per note, its size set by the motion type MotifMotion Stepwise 2nds only GentleLeap up to 3rds WideLeap up to 5ths NarrowStep ±1 scale degree Disjunct irregular leaps Ostinato one pitch class, Blueprint only repeat scope FullSong one pattern for the whole song Section a fresh pattern per section the riff policy comes first under a free policy every section rebuilds The motion type only sets how far each step may travel; the rhythm grid is fixed before any pitch is chosen.

MotifMotion values (API: 0-5):

ValueNameDescription
0StepwiseScale steps only (2nds)
1GentleLeapUp to 3rds
2WideLeapUp to 5ths
3NarrowStepNarrow scale degrees (jazzy)
4DisjunctIrregular leaps (experimental)
5OstinatoSame pitch class repeated

Register

The motif track occupies C4 (60) - C8 (108). The register flag picks the base note it builds from, not a range of its own:

RegisterBase note
Mid (default)C4 (60)
HighG4 (67)

When a vocal is present, the usable range is narrowed around the vocal median: the ceiling drops to three semitones above it and the floor rises to fifteen below, which keeps the motif from piling up at the top of its range.

Repetition

For the Free policy, repeat_scope controls whether FullSong generates a fresh motif for each section or Section caches and reuses a pattern by section type. The locked policies (LockedContour, LockedPitch, LockedAll) replay the cached pattern on repeated section types. Evolving mutates its cached riff once per section while retaining its identity. When phrase_tail_rest applies, the motif stops starting notes halfway through the final bar of the tail; the coordinator asks the generator for that cutoff when it copies a frozen bar.


Arpeggio Track

Source: src/track/generators/arpeggio.cpp

For SynthDriven composition style (BGM-only mode). Creates arpeggiated patterns that serve as the primary harmonic/melodic element in electronic-style tracks.

Parameters

cpp
struct ArpeggioParams {
    ArpeggioPattern pattern = Auto;  // Up, Down, UpDown, Random, Pinwheel,
                                     // PedalRoot, Alberti, BrokenChord, Auto
    ArpeggioSpeed speed = Auto;      // Eighth, Sixteenth, Triplet, Auto
    uint8_t octave_range = 2;        // 1-3 octaves
    float gate = -1.0f;              // Note length ratio (0.0-1.0); -1 = style default
    bool sync_chord = true;          // Follow chord changes
    uint8_t base_velocity = 90;      // Base velocity for arpeggio notes
};

Pattern Types

The eight arpeggio patterns, with the first three spelled out Over a C major triad in a single octave, Up plays C, E, G; Down plays the same list reversed, G, E, C; and UpDown plays C, E, G and then back down without repeating the outer notes, ending on E. Raising octave_range repeats the whole triad an octave higher, so Up becomes C, E, G, C, E, G two octaves wide. The remaining five patterns are Random, Pinwheel, PedalRoot, Alberti and BrokenChord. Speed only changes each note's length. note order — C major triad, one octave Up C E G every chord tone in range, ascending Down G E C the same list, reversed UpDown C E G E up, then back down without repeating the ends Raising octave_range repeats the whole triad an octave up, so Up becomes C E G C E G across two octaves. the other five patterns Random any chord tone Pinwheel 1-5-3-5 alternation PedalRoot 1-3-1-5-1-7 Alberti 1-5-3-5, classical BrokenChord 1-3-5-8-5-3 Speed changes only each note's length — 8th 240 ticks, 16th 120, triplet 160, out of 480 per beat.
IDPatternDescription
0UpAscending through chord tones
1DownDescending through chord tones
2UpDownAscending then descending (endpoints not repeated)
3RandomShuffled chord tone order
4PinwheelRoot - 5th - 3rd - 5th
5PedalRootRoot alternating with each upper chord tone
6AlbertiClassical low-high-mid-high; same figure as Pinwheel
7BrokenChordAscending then descending; same figure as UpDown
255AutoUse the mood or blueprint default pattern (the JS default)

The chord tones are stacked across octave_range octaves before the pattern is applied, so with the default of 2 an Up arpeggio on a C major triad plays C E G C E G, not C E G C.

Speed Conversion

cpp
Tick getNoteDuration(ArpeggioSpeed speed) {
    switch (speed) {
        case Eighth:    return TICKS_PER_BEAT / 2;    // 240
        case Sixteenth: return TICKS_PER_BEAT / 4;    // 120
        case Triplet:   return TICKS_PER_BEAT / 3;    // 160
    }
}

SE Track

Source: src/track/generators/se.cpp

The SE track carries a text marker at the start of every section, plus a marker at the modulation point when the song modulates. It takes no part in pitch collision detection.

When calls are enabled it also writes call-and-response chants: chant and mix-break sections get their preset pattern, choruses get scattered short calls at a probability set by the call density, a PPPH figure is placed in the last bar before a B → Chorus transition, and an intro mix pattern is placed at each intro. Call notes are optional; with them switched off only the text markers are written. Every call note sounds at a fixed C3 (48), so the track can be muted or re-pointed without affecting the rest of the arrangement.


Velocity Calculation

Common velocity formula across tracks:

cpp
uint8_t calculateVelocity(
    uint8_t baseVelocity,
    int beat,
    SectionType section,
    float trackBalance
) {
    float beatAdjust = getBeatAccent(beat);      // Strong beats: +10
    float sectionMult = getSectionEnergy(section); // Chorus: 1.2

    return clamp(
        baseVelocity * beatAdjust * sectionMult * trackBalance,
        1, 127
    );
}

Track Balance

TrackBalanceNotes
Vocal1.00Lead instrument
Aux0.50-0.80Sub-melody support
Chord0.75Supporting
Bass0.85Foundation
Guitar0.70Accompaniment
Drums0.90Timing driver
Motif0.70Background
Arpeggio0.85Mid-level