Table of Contents

Class VoiceLeadingSolver

Namespace
Celeritas.Core.VoiceLeading
Assembly
Celeritas.dll

High-performance voice leading solver using parallel BFS/A* search. Finds optimal voicings for a chord progression following counterpoint rules.

Algorithm:

  1. Generate all valid voicings for each chord (constraint: notes in range, proper spacing)
  2. Build a graph where edges connect compatible voicings of consecutive chords
  3. Use parallel A* search to find the path with minimum voice leading cost

The rules followed are exactly the ones VoiceLeadingViolation names. Inversion is not among them: a chord arrives here as a set of pitch classes with no bass named, so the bass takes whichever chord tone the smoothest path wants, and a progression may well begin or end on a six-four. Choose the inversions yourself if they matter.

public sealed class VoiceLeadingSolver
Inheritance
VoiceLeadingSolver
Inherited Members

Constructors

VoiceLeadingSolver(VoiceLeadingSolverOptions?)

High-performance voice leading solver using parallel BFS/A* search. Finds optimal voicings for a chord progression following counterpoint rules.

Algorithm:

  1. Generate all valid voicings for each chord (constraint: notes in range, proper spacing)
  2. Build a graph where edges connect compatible voicings of consecutive chords
  3. Use parallel A* search to find the path with minimum voice leading cost

The rules followed are exactly the ones VoiceLeadingViolation names. Inversion is not among them: a chord arrives here as a set of pitch classes with no bass named, so the bass takes whichever chord tone the smoothest path wants, and a progression may well begin or end on a six-four. Choose the inversions yourself if they matter.

public VoiceLeadingSolver(VoiceLeadingSolverOptions? options = null)

Parameters

options VoiceLeadingSolverOptions

Solver options; defaults to VoiceLeadingSolverOptions.Default when null.

Methods

Solve(IReadOnlyList<int[]>, int)

Solve voice leading for a progression of chords. Returns optimal SATB voicings for each chord.

public VoiceLeadingSolution Solve(IReadOnlyList<int[]> chordPitchClasses, int keyRoot = 0)

Parameters

chordPitchClasses IReadOnlyList<int[]>

One pitch-class set per chord.

keyRoot int

Pitch class of the tonic, 0=C .. 11=B. Folded into that range, as Check(Voicing, Voicing, int) folds its own, so -1 is B and 12 is C. It was handed to the rules unfolded, and a root of -12 or below — a tonic an octave down — indexed an array by a negative number inside the parallel search and came back as an AggregateException naming no argument.

Returns

VoiceLeadingSolution

Exceptions

ArgumentNullException

chordPitchClasses is null.

SolveFromSymbols(IReadOnlyList<string>, int)

Solve voice leading from chord symbols.

public VoiceLeadingSolution SolveFromSymbols(IReadOnlyList<string> chordSymbols, int keyRoot = 0)

Parameters

chordSymbols IReadOnlyList<string>
keyRoot int

Returns

VoiceLeadingSolution

Exceptions

ArgumentNullException

chordSymbols is null.