Skip to content

Voice Architecture ​

Each voice in a MIDI Sketch Bach composition is an independent melodic line. The form decides how many voices there are and what each one does; there is no voice-count option.

What is a Voice?

In Baroque music, a "voice" is an independent melodic line — whether sung or played. A three-voice fugue has three simultaneous lines, each with its own rhythm, contour, and identity. In MIDI Sketch Bach, each voice becomes a separate MIDI track.

Track is the export container; voice is the musical role

The MIDI file uses tracks because DAWs understand tracks. The composition engine uses voices because counterpoint rules care about independent musical lines. Usually one voice maps to one track.

The Form Decides the Voice Count ​

Voice count is fixed per form. Picking the form picks the texture:

FormVoices
fugue, prelude_and_fugue, trio_sonata, chorale_prelude, toccata_and_fugue, passacaglia, fantasia_and_fugue, goldberg_variations3
chaconne3
cello_prelude1

Passing numVoices/num_voices is accepted and ignored for backward compatibility. See Forms for the full table including meter and natural length.

For the chaconne, the engine declares three lanes even though Bach's historical work is for solo violin: V0 carries the variation, V1 carries middle material where clean register space is available, and V2 carries the ground. V1 starts as a rest and may rest for individual bars or whole cycles when no clean placement exists, while the output still reports three chaconne tracks. Character also sets note articulation and the MIDI CC profile applied to every form; see Instruments for the instrument-specific output.

Voice Intents ​

The form director assigns each voice a voice intent over the bar spans of the piece — the role that voice plays at each point. The engine defines 33 named intents (voice_intent.h), including three dedicated Goldberg carriers; they group into a handful of families:

Voice intents over bar spansThe upper half reads a fugue left to right as three voice lanes. Each lane is divided into spans, and every span carries one named intent: subject carrier, answer carrier, countersubject carrier, episode, middle entry, pedal, stretto and coda. The lower half groups the named intents into seven families and says what each family is for.one intent per bar span — a fugue, read left to rightV1SubjectCarrierEpisodeMiddleEntryCarrierEpisodeStrettoCarrierV2AnswerCarrierCountersubjectCarrierEpisodeMiddleEntryCarrierStrettoCarrierV3SubjectCarrierEpisodePedalCarrierCodaCarrierthe families those names group intoFugal entriessubject, answer, and therecurring companion lineDevelopmentmiddle entries, stretto,pedal points, closing materialEpisodessequential travel materialderived from subject motifsFixed linesgrounds and cantus firmuslines that never changeFiguralcontinuous idiomaticfiguration and solo writingVariationauthored variation material,including three Goldberg linesTexturerhythm shapes, declarednon-chord tones, trio linesThe engine names 33 intents. What matters is that every bar of every voice carries exactly one, and the validator knows which.
FamilyRepresentative intentsRole
Fugal entriesSubjectCarrier, AnswerCarrier, CountersubjectCarrierFugue theme entries (tonic), their answers (dominant), and the recurring companion line
DevelopmentMiddleEntryCarrier, StrettoCarrier, PedalCarrier, CodaCarrierRelated-key entries, overlapping entries, pedal points, closing material
EpisodesEpisode, FortspinnungSpanSequential travel material derived from subject motifs
Fixed linesGroundCarrier, PassacagliaGround, CantusFirmusCarrierImmutable repeating basses and chorale melodies
FiguralFigurationCarrier, ArpeggioFlow, ToccataCarrier, FantasiaCarrierContinuous idiomatic figuration and sectional solo writing
VariationVariationCarrier, GoldbergBassCarrier, GoldbergVariationCarrier, GoldbergInnerVoiceCarrierAuthored variation material and the three distinct Goldberg lines
TextureRhythmCarrier, NctCarrier, TrioVoiceCarrierAnacrusis/hemiola rhythm shapes, declared non-chord-tone figures, and authored trio/counterlines

For the standalone fugue form, each voice waits for its own exposition entry: V0 carries the subject, V1 the answer, and V2 the third entry. Ordinary development entries rotate V0 → V1 → V2; during the pre-coda pedal cycle, the subject returns to V0.

Episodes place an authored FortspinnungSpan sequence in V0 and thin to two voices: V1 rests in two of each three non-final episode cycles, V2 rests in the third, and the final episode keeps all three. When V2 sounds in a thinned episode, its bass support alternates a faster running figure with slower walking support. When a pedal cycle is present, one supporting voice holds the dominant while the other supplies figuration.

All default shipped forms use carrier assembly: candidate search dispatches the spans but replays the authored material verbatim, so scored search contributes no default notes. The opt-in --free-counterpoint path reroutes only Passacaglia V1 (voice == 1) from TrioVoiceCarrier to SequentialCounterline; it is unavailable for other forms. See Candidate Search.

Subject, answer, ground, cantus firmus

A subject is the main fugue theme. An answer is that theme restated in another voice, usually shifted toward the dominant. A ground bass is a repeating low pattern. A cantus firmus is a fixed long-note melody.

Voice Independence ​

Maintaining independence between voices is a core principle of Baroque counterpoint. The engine sustains it through:

Rhythmic Differentiation ​

Voices use complementary rhythmic patterns so they do not move in lockstep — when one voice sustains, another tends to be active. This complementarity is a hallmark of Bach's writing.

Melodic Differentiation ​

Each voice has its own intervallic profile and directional tendencies, and develops its thematic material independently.

Register Differentiation ​

Voices keep to distinct registers. Voice crossing is minimized; when voices approach each other, they tend to move apart. The form builders author the carrier lines against the harmonic plan, and the validator checks their register, harmony, and independence.

Register and voice crossing

Register means pitch range: bass is low, soprano-like writing is high. Voice crossing happens when a lower voice moves above a higher voice, or a higher voice moves below a lower one. That makes the streams harder to follow.

Voice-to-Track Mapping ​

Each voice maps to a separate MIDI track with its own channel and program:

js
const events = generator.getEvents()

for (const track of events.tracks) {
  console.log(`Voice: ${track.name}`)      // track name
  console.log(`Channel: ${track.channel}`)  // MIDI channel (0-15)
  console.log(`Program: ${track.program}`)  // GM program number
  console.log(`Notes: ${track.note_count}`) // number of notes
}

Every note also carries a source provenance tag ("material", "compose", or "ornament") — see the JavaScript API.

General MIDI Program Mapping ​

InstrumentGM ProgramSound
Organ19Church Organ
Harpsichord6Harpsichord
Piano0Acoustic Grand Piano
Violin40Violin
Cello42Cello
Guitar24Acoustic Guitar (Nylon)

The output is a Type 1 Standard MIDI File with one track per voice, so you can reassign instruments per voice in your DAW.

Dual-licensed: AGPL-3.0 · commercial licensing available. Generated MIDI is yours to use freely.