CLI for generating musical compositions from algorithmically generated patterns, based on work by Duncan Lockerby.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
dist
src/nl/igorski/mmg
.gitignore
LICENSE
README.md
build.gradle
gradle.properties
settings.gradle

README.md

Molecular Music Generator

MMG is a simple command-line tool that can generate musical patterns generated by a simple algorithm. The properties of the algorithm can easily be defined in a JSON file (see below), which will then be rendered into a MIDI file, which can in turn be opened in DAW music software or be played back by synthesizers.

If you just want to make music and aren't interested in modifying the source code, no worries, there is a pre-compiled program in this repository (see the /dist-folder) so you can jump straight to the "How to run" and "How to setup the environment properties" sections below, it shouldn't take more than a minute to get running.

About the algorithm

The algorithm is based on "the Molecular Music Box" by Duncan Lockerby.

The rules for the algorithm are as follows :

  • two different note lengths need to be defined, e.g. "4" and "3"
  • a scale needs to be defined, e.g. C major (the white keys on a piano), let's say we start on the E note, the list of notes will then contain : E, F, G, A, B, C
  • a pattern length needs to be defined, e.g. 4 bars

The algorithm will then function like so (keeping the above definitions in mind) :

  • the first note of the scale (E) is played at the length of the first defined note length (4)
  • each time the duration of the played note has ended, the NEXT note in the scale (F) is played
  • once the first pattern length has been reached (4 bars), a new pattern will start
  • the previously "recorded" pattern will loop its contents indefinitely while the new patterns are created / played
  • if a newly played note sounds simultaneously with another note from a PREVIOUS pattern, the note length will change (in above example from 4 to 3).
  • this will be the new note length to use for ALL SUBSEQUENT added notes, until another simultaneously played note is found, leading it to switch back to the previous note length (in above example, back to 4).
  • as the pattern is now played over an existing one, it is likely that notes will be played in unison, leading to the switching of note length
  • as more patterns are accumulated, a perfectly mathematical pattern of notes are weaving in and out of the notes of the other patterns

Experimenting with different note lengths, scales or even time signatures can lead to interesting results!

See https://www.youtube.com/watch?v=3Z8CuAC_-bg for the original video by Duncan Lockerby.

How to build

You will need Gradle to resolve the dependencies (SimpleJSON and the LeffelMania Android MIDI Library, the latter actually being cross platform) and build the project.

The "build" target should suffice to compile and package the .JAR

If however, you are not interested in modifying the source code and just want to create some algorithmic music, use the pre-built .JAR file in the /dist folder.

How to run

MMG is a command line util, and requires a Java Runtime Environment (available by default on most operating systems). You can run it by opening a terminal / command prompt and typing:

java -jar mmg.jar

However, be sure to supply additional arguments to the input JSON file (relative to the location of the mmg.jar-file), like so:

java -jar mmg.jar path/to/input.json

So, assuming you have a file called "composition.json" in the same folder that contains "mmg.jar", you can generate your MIDI file instantly by typing:

java -jar mmg.jar composition.json

The remaining configurations and compositional properties are defined within the JSON file and these are explained below.

How to setup the environment properties

The JSON (JavaScript Object Notation) looks like the following, note that "tempo", "lengths", "patternLength" and "amountOfPatterns" are required and cannot be undefined. Note there is a sample input.json file in the /dist-folder.

{
    "tempo"             : 165.0,
    "lengths"           : [ 4, 3 ],
    "patternLength"     : 4,
    "amountOfPatterns"  : 8,
    "timeSignature"     : [ 4, 4 ],
    "minOctave"         : 2,
    "maxOctave"         : 7,
    "scale"             : [ "C", "D", "E", "F", "G", "A", "B" ],
    "trackPerPattern"   : false,
    "outputFile"        : "output.mid"
}

If you are unfamiliar with the JSON format, you can stick to changing the numerical values with any other numerical value you like, but be sure that "patternLength", "amountOfPatterns", "timeSignature", "startOctave" and "endOctave" only hold rounded values.

"lengths" is a list of two notes that describes the alternate note length/duration to use in the composition. "patternLength" describes the length of a single pattern (in measures). Once the generator has generated notes for the given amount of measures, a new pattern will be created, this process will repeat itself until "amountOfPatterns" has been reached. A configuration with a patternLength of 4 and amountOfPatterns of 8 will result in 32 measures of music.

You can alter the time signature to any exotic meter of your liking, the first number is the upper numeral in a time signature, e.g. the "3" in 3/4, while the second number is the lower numeral, e.g. the "4" in 3/4.

"minOctave" determines the octave at which the composition will start, this cannot be lower than 0. "maxOctave" determines the octave at which the composition will end, this cannot be higher than 8.

The value for "scale" can be changed to any sequence (or length!) of notes you like, meaning you can use exotic scales, or even determine the movement by creating a sequence in thirds, or by re-introducing a previously defined note, etc. Note that the scale will be repeated over the determined octave range. You can create sharps and flats too, e.g.: "Eb", "F#", etc.

"trackPerPattern" can be either 'true' or 'false'. When true, the resulting .MIDI file will have a unique MIDI track for each new pattern, when false, all the patterns are part of the same MIDI track. If amountOfPatterns is high enough for the algorithm to go back down the scale, it is best to have this set to true to avoid conflicts in MIDI notes.

"outputFile" describes the name of the generated MIDI file.