11
$\begingroup$

I would like to write a Mathematica routine for generating random musical melodies that obey (some of) the constraints of traditional tonal harmony. For simplicity's sake, I'm interested only in strictly diatonic melodies in a major key.

Assuming that all the note values in the melody are equal (whole notes, say), I simply represent the diatonic scale degrees of the major key by the integers 1 to 7. The harmonic constraints that I wish to implement are then as follows:

  1. The degrees 1, 3, 5 can move, by step or by leap, to any other scale degree.
  2. Degree 2 can move to either 1 or 3, with a slight stochastic bias towards 1.
  3. Degree 4 moves to 3.
  4. Degree 6 moves to 5.
  5. Degree 7 moves to 1.
  6. The "natural" tendencies of scale degrees 2, 4, 6, 7, as outlined above, can be negated by stepwise movement, up or down, along the major scale. For example: 7 - 6 in isolation is not allowed, but 1 - 7 - 6 or 7 - 6 - 5 is. The relative frequency of such scalar movements should preferably be (very roughly) proportional to the length of the scale fragment. For example, 1 - 7 - 6 - 5 - 4 should occur "more often" than just 1 - 7 - 6.
  7. Melodies should begin with one of the scale degrees 1, 3, 5, and end with one of the formulas 7 - 1, 2 - 1, 4 - 3, or 2 - 3.
  8. For bass melodies, I would instead of (7) like to have the optional constraint that all melodies end with the cadential formula 5 - 1.
  9. Melodies may be any length between 5 and 16 notes.
  10. Stepwise motion should predominate over leaps, in roughly the ratio 4 to 1.

Finally, if it's possible, I'd like to have a function to put the generated melody into an audible form.

A tall order perhaps, but any suggestions would be appreciated, even if they solve my problem only partially.

$\endgroup$
16
$\begingroup$

Perhaps have a look at DiscreteMarkovProcess using an appropriate transition matrix embedding your constraints?

Here's a simple example, implementing 1-5 above, to get you started:

transitionMatrix = {
   {0, 0, 1/2, 0, 1/2, 0, 0},
   {6/10, 0, 4/10, 0, 0, 0, 0},
   {1/2, 0, 0, 0, 1/2, 0, 0},
   {0, 0, 1, 0, 0, 0, 0},
   {1/2, 0, 1/2, 0, 0, 0, 0},
   {0, 0, 0, 0, 1, 0, 0},
   {1, 0, 0, 0, 0, 0, 0}};

\[ScriptCapitalP] = 
  DiscreteMarkovProcess[2 (*initial state*), transitionMatrix];

data = RandomFunction[\[ScriptCapitalP], {0, 100}];
GraphicsRow[{MatrixPlot[transitionMatrix, PlotLegends -> Automatic], 
  ListPlot[data, Filling -> Axis, Frame -> True, ImageSize -> 500]}]

enter image description here

$\endgroup$
1
  • $\begingroup$ Wow, thanks! That should definitely get me started. $\endgroup$ Oct 13 at 1:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.