Skip to content

tourdefran/running-man

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 

Repository files navigation

running-man

Generates MIDI Pitch Events From Integer Sequences

Info

The CDF version of running-man should be runnable using this free CDF Player. To edit the running-man notebook, you'll need Mathematica.

under the hood, for begginers

1. Pitch Class Integer Notation

running-man uses integer notation to represent pitch classes. Integer notation is a translation of pitch classes into natural numbers. For example, if C = 0, then C# = 1, D = 2, D# = 3, and so on. By extension, integer notation can also represent harmonies and scales:

Hamony / Scale Note Names Pitch Classes
C Maj (C, E, G) {0, 4, 7}
G Min / D (D, G, Bb) {7, 10, 2}
F Maj / C (A, C, F) {9, 0, 5}
C Dorian (C, D, Eb, F, G, A, Bb) {0, 2, 3, 5, 7, 9, 10}
D Lydian (D, E, F#, G#, A, B, C#) {2, 4, 6, 8, 8, 10, 1}
C Shang (C, D, F, G, C, Bb) {0, 2, 5, 7, 10}

2. Frequently Used Functions

2.1 Inbuilt Wolfram Language Functions

running-man frequently uses the following basic Wolfram Language functions. For more detailed explanations of these functions, visit the Wolfram Language Reference Site.

  • Range[n] generates the list {1,2,...,n}.
  • Table[f, n] generates the list of values n of function f.
  • With[{a=x, b=y, ...}, exp] specifies that all occurrences of a, b, ... in exp should be replaced by x, y, ...
  • Take[lst, n] gives the first n elements of list.
  • Mod[m, n, o] gives the remainder on division of m by n using an offset o.
  • Map[f, lst ] or f/@exp applies function f to each element in list lst.
  • Flatten[lst] flattens the nested list lst.
  • Differences[lst] gives the differences between each successive element in list lst.
  • LinearRecurrence[ker, int ,n] gives the sequence of length n obtained by iterating the linear recurrence with kernel ker starting with initial values int.

2.2 Integer Sequence Functions

The Wolfram Language provides an extensive selection of inbuilt integer sequence functions. For example, the fourth integer in the Fibonacci sequence (i.e., 1, 1, 2, 3, 4, ...) is given by simply entering:

In[]:= Fibonoacci[4]
Out[]:= 3

running-man uses functions such as Table[] and Range[] to iterate these sequence functions:

In[]:= Fibonacci[Range[12]]
Out[]:= {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144}
In[]:= Table[Fibonacci[x], {x, 1, 12}]
Out[]:= {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144}

The Online Encyclopedia of Interger Sequences provides formulae for integer sequences that are not inbuilt into the Wolfram Language. Some OEIS entries also provide these formulae using inbuilt Wolfram Language functions. For example, the OEIS entry for the square numbers OEIS A000290 includes the following code for generating the square numbers using the Wolfram Language LinearRecurrence[] function:

In[]:= LinearRecurrence[{3, -3, 1}, {0, 1, 4}, 12]
Out[]:= 0,1,4,9,16,25,36,49,64,81,100,121,144

2.3 Moving Window Function

running-man uses a moving window function:

MovingWindow[f_, exp_, n_, o_] := 
  Module[{len = Length[exp], end}, end = Min[n, len] - 1;
   Table[Apply[f, {exp[[i ;; i + end]]}], {i, 1, len - end, o}]];
c.f., Mathematica Cookbook, Sal Mangano: 44

The MovingWindow[f, lst, n, o] function moves a window over lst of function f by groups of n at an offset of o. For example, using MovingWindow[] with function Take[list,n] and offset and group both set to 3 gives:

In[]:= MovingWindow[Take, Fibonacci[Range[9]], 3, 3]
Out[]:={{1, 1, 2}, {3, 5, 8}, {13, 21, 34}}

An offset of 1 gives:

In[]:= MovingWindow[Take, Fibonacci[Range[9]], 3, 1]
Out[]:= {{1, 1, 2}, {1, 2, 3}, {2, 3, 5}, {3, 5, 8}}

An offset of 3 and a group 1 gives:

In[]:=MovingWindow[Take, Fibonacci[Range[9]], 1, 3]
Out[]:={{1}, {3}, {13}}

3. MIDI Event Generating Functions

3.1 The Mono Function

running-man uses the Mono[] function to generate a list of MIDI pitch events from a preselected mode:

Mono[exp_] := 
  With[{arb = exp}, Take[arb, {#}] & /@ Mod[d@F[ln], mB, mI]];
c.f., Programming Avro Part, link
3.1.1 Variables of the Mono Function

The variables of the Mono[] function are nested in Mathematica's Manipulate[] template, because of this fact they are assigned by way of the Manipulate[] template's modest GUI. However, when the running-man notebook is first initialized, the variables of the Mono[] function (e.g., d, F, len, ...) are automatically assigned the following values:

Variable Assignment
mB = 7 The Modular Divisor
mI = 1 The Modular Offset
d = Flatten If d is set to Flatten, pitches are given from successive cardinalities.
If d = Differences, pitches are given from successive differences.
F = Fibonacci[Range[len]] The integer sequence function used to generate pitches with the
Range function nested such that it generates a list instead of single integer.
len = 12 The length of the pitch set to be generated
dor = {0, 2, 3, 5, 7, 9, 10, 0, 2, 3, 5, 7, 9, 10} The Integer Notation of the Dorian mode
In[]:= Mono[dor]
Out[]:= {0, 0, 2, 3, 7, 0, 9, 10, 9, 9, 7, 5}

Change a variable to generate pitches from differences rather than from cardinalities:

In[]:= d = Differences;
In[]:= Mono[dor]
Out[]:= {10, 0, 0, 2, 3, 7, 0, 9, 10, 9, 9}

Following the Fibonacci sequence (1, 1, 2, 3, 5, ...). The 1st element in dor is 0, the 2nd element is 0, the 3rd element is 2, the 4th element is 3, the fifth element is 7, etc.

Function 1 2 3 4 5 6 7 8 9 10 11 12
dor PCs 0 2 3 5 7 9 10 0 2 3 5 7
Fn+1 mod 7 1 1 2 3 5 1 6 7 6 6 5 4
Fn+1 mod 7 /@ dor PCs 0 0 2 3 7 0 9 10 9 9 7 5
Δ Fn+1 mod 7 /@ dor PCs N/A 10 0 0 2 3 7 0 9 10 9 9

3.1 The Harmonize Function

The Harmonize[] function gives a nested sublist (i.e., aggregate) of any three consecutive PCs that constitute a major or a minor triad.

Harmonize[exp_] := 
 With[{n1 = Take[exp, {1}], n2 = Take[exp, {2}], 
   n3 = Take[exp, {3}]},
  If[n2 == (n1 + 0) && n3 == (n1 + 0) || 
    n2 == (n1 + 0) && n3 == (n1 + 3) || 
    n2 == (n1 + 0) && n3 == (n1 + 7) || 
    etc. etc.

3.2 The Poly Function

The Poly[] function runs a MovingWindow[] of Harmonize[] over the lists given by Mono[].

Poly[exp_] := MovingWindow[Harmonize, Mono[m], 3, 3];

In this way, the Poly[] function allows the generation of diatonic, polyphonic, MIDI files from integer sequences.

Future Work

running-man is pretty simple code. I tried messing around with serializing the MIDI event durations (the Y and N buttons on the GUI), but I never figured out a procedure that produced appropriate sounding results. I also tried expanding the Harmonize[] function to include four-voice (e.g., 6ths, 7ths), and even five-voice (e.g., 9ths) harmonies, but that only ended up making the whole program too unmanageable. Please mess around with the code and share! You'll notice that upon initialization (BASE M = 11), the MIDI events are the same as the verse for The Running Man. The structure of The Running Man, from section to section, is simply an adjustment of the BASE M parameter (part a = 2, part b = 4, part c = 5, etc.).

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Mathematica 100.0%