Skip to content

About

Procedural fugue composition via Markov chains — constrained transition sampling with counterpoint rules as hard filters. Includes full paper.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Stochastic Methods for Procedural Content Generation

A Markov Chain model for procedural fugue composition, trained on Bach's Well-Tempered Clavier (BWV 846-893). The model operates on a constrained state space derived from diatonic pitch classes and generates multi-voice output subject to counterpoint restrictions encoded as hard filters on the transition distribution.

Full paper: StochasticMethodsForMusicGeneration.pdf


Model

State Space

Pitch states are restricted to diatonic pitch classes (C major):

N  = {0, 2, 4, 5, 7, 9, 11} mod 12,   21 <= n <= 108
Nc = {1, 3, 6, 8, 10} mod 12  (excluded)

Time is quantized to multiples of 125ms, bucketed to the nearest standard note duration (sixteenth to whole).

Transition Probability Matrix

For each piece (or collection of pieces), the parser constructs a transition frequency matrix F_{i,j} over N x tau by recording all observed note-to-note transitions and their durations. This is row-normalized to yield the TPM P_{i,j}:

F_{i,j} -> P_{i,j}

The generated sequence is a discrete-time, discrete-state stochastic process:

(x_i, t_i^x)_{i in Z+} in N x tau

which can equivalently be viewed as a continuous-time process (X_t)_{t in R+} -- a CTMC representation that enables cross-voice synchronization rules.

Counterpoint Constraints

Rather than soft penalties, counterpoint rules are implemented as hard rejection filters on the transition sampler. Invalid transitions are resampled until a valid next state is found.

Single-voice constraints on x_i:

Constraint Formal Definition
Leap bound |x_{i+1} - x_i| <= 9
No non-ornamental trills x_i = x_{i+2} and |x_{i+1} - x_i| <= 2 implies x_{i+3} != x_{i+1}
Leap recovery x_{i+1} - x_i >= 4 implies x_{i+2} steps down; x_{i+1} - x_i <= -4 implies x_{i+2} steps up
Resolving cadence After n >= 16 notes, leading tones {67,71,79,83} resolve to tonic on a downbeat (t = 0 mod 1000)

Joint constraints on (X_t, Y_t) across voices:

Constraint Formal Definition
No parallel octaves X_t = Y_t (mod 12) and X advances implies Y_{j+1} != X_{i+1} (mod 12)
No parallel fifths X_t = Y_t +/- 7 (mod 12) and X advances implies Y_{j+1} != X_{i+1} +/- 7 (mod 12)

The dual discrete/continuous time representation is necessary because two voices accumulate different note counts over the same wall-clock duration; cross-voice rules are therefore indexed by continuous time t in R+ rather than note index.


Implementation

File Role
Parse.py Reads MIDI via Mido, constructs F_{i,j} and normalizes to P_{i,j}
Simulation.py Rejection-sampled Markov walk with counterpoint filter stack
Track.py Voice management, multi-track assembly, MIDI output (entry point)
WriteMidi.py Standalone MIDI serialization utility
bach_846.mid Training data: BWV 846, Fugue in C Major

Dependencies

pip install mido numpy

Running

python Track.py

Trains on bach_846.mid, generates a soprano subject (16 notes), constructs a countersubject via retrograde at a time offset equal to the subject duration, and writes testTrack12.mid. To swap training data:

# Track.py -> Track.build_track()
file = Parse('your_fugue.mid')

Limitations

First-order Markov Chains have no long-range memory, which limits thematic coherence across a full fugue. Higher-order chains (order n) partially address this but cause state space explosion and quickly degrade to verbatim training data reproduction. The countersubject quality is the weakest output -- it requires denser joint restrictions between voices than are currently implemented. A deep learning approach (e.g., convolutional counterpoint) would better preserve long-term structure but sacrifices the interpretability and controllability of an explicit stochastic model.


References

  1. Ames, C. (1989). The Markov Process as a Compositional Model: A Survey and Tutorial. Leonardo 22(2), 175-187.
  2. Briot, J. P., Hadjeres, G., & Pachet, F. D. (2017). Deep learning techniques for music generation -- a survey. arXiv:1709.01620.
  3. Huang et al. (2019). Counterpoint by convolution. arXiv:1903.07227.
  4. Inesta, J. M., Conklin, D., & Ramirez, R. (2016). Machine learning and music generation. Journal of Mathematics and Music, 10(2), 87-91.
  5. Volchenkov, D., & Dawin, J. R. (2012). Musical Markov Chains. IJMPCS Vol. 16, pp. 116-135.

About

Procedural fugue composition via Markov chains — constrained transition sampling with counterpoint rules as hard filters. Includes full paper.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages