Giter Club home page Giter Club logo

melody.py's Introduction

melody.py

melody.py generates random 10-note first species counterpoint melodies by first finding a random cantus firmus melody that matches a set of heuristics and then finding an appropriate counterpoint melody. A total of 16 heuristics are used for each individual melody and 4 heuristics are used to match two melodies in counterpoint. Results are outputted as MIDI files using Pyknon and then played using Timidity.

Table of Contents

1. Try It Now! 2. Video Demonstration 3. Usage 3.1. Installation 3.1.1. Ubuntu / Debian 3.1.2. Other 3.2. Running melody.py 3.2.1. Command-line interface 3.2.2. Web interface 4. Heuristics Used 4.1. For each individual melody 4.2. To match cantus firmus melody to first species melody 5. Wish List

1. Try It Now!

I've spun up an Amazon EC2 instance.

2. Video Demonstration

Link to Youtube video

3. Usage

You can use melody.py through the command-line or by running a small web server. The advantage of the latter is that you'll also be able to see generated sheet music.

3.1. Installation

3.1.1. Ubuntu / Debian
sudo apt-get install python3-pip timidity
pip3 install git+https://github.com/kroger/pyknon.git

If you wish to use the web interface, also run

pip3 install flask

3.1.2. Other

Install Pyknon and Timidity.

If you wish to use the web interface, also install Flask. If you're using Internet Explorer (which supports MP3 but not WAV audio sources), make sure FFmpeg is installed.

3.2. Running melody.py

3.2.1. Command-line interface
python melody.py

will loop forever, generating new melodies continuously. Mash Ctrl-C a few times to stop it.

3.2.2. Web interface
python app.py

Then go to localhost:5000 (or whatever port is chosen).

4. Heuristics Used

4.1. For each individual melody

Both the cantus firmus and the first species must satisfy the following rules:

  1. No repeated notes in cantus firmus (one repetition allowed in first species).
  2. No leaps that are an octave or larger.
  3. No dissonant leaps.
  4. Between two and four leaps in total.
  5. Has a climax (highest note) that is not on the tonic or leading tone.
  6. Changes direction at least two times.
  7. No note repeated more than 3 times.
  8. Final note approached by a step (not a leap).
  9. Leaps larger than M3 must be followed by a change of direction.
  10. The leading tone must always be followed by the tonic.
  11. No more than two consecutive leaps in the same direction.
  12. The same interval cannot occur twice in a row.
  13. No noodling (that is, patterns such as N1 N2 N1 N2, for some notes N1 and N2).
  14. No runs of more than four consecutive notes.
  15. No unresolved melodic tension (that is, the start and end note of each run must be consonant together).
  16. No repeated three-note patterns.

4.2. To match cantus firmus melody to first species melody

Together, the cantus firmus and the first species must satisfy the following:

  1. No dissonant vertical intervals.
  2. No vertical intervals larger than a 12th (P8 + P5).
  3. No parallel fifths or octaves.
  4. No parallel three-note chains.

5. Wish List

  • minor key support
  • support for other kinds of counterpoint
  • support for melodies of other lengths (with rules tuned appropriately)
  • ability to import existing cantus firmus (as MIDI or note array)
  • minor: treating repeated notes as a single note of double duration rather than two separate notes

melody.py's People

Contributors

alexnisnevich avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

melody.py's Issues

`changes_direction_several_times` is wrong.

Hi there

Your checking function changes_direction_several_times is incorrect.

Current state

	def changes_direction_several_times():
		directional_changes = [intervals[i+1] - intervals[i] for i in range(len(m) - 2)]
		if len([x for x in directional_changes if x < 0]) >= 2:
			return True
		else:
			if verbose: print 'fail: changes_direction_several_times in ' + str(m)

Consider the melodies [0,5,7] and [0,-3,2], which produce intervals [5,2] and [-3,5] respectively. Then the directional_changes are [-3] and [8], so the first melody will record a directional change and the second one will not. Both of those are wrong conclusions.

You probably want to count the number of times contiguous directions are different.

Integration from the 8 years into the future!

Hi Alex!
I have started work on my own generative stuff and was wondering what I would best be able to do to utilize your counterpoint generator. My ideal state would be to set it to the CMaj scale and pass it through MelodicFlow to transpose it. As of now, I only randomly choose MIDI pitches, but I do write out the durations to an array of numbers - but I just do single notes. However, I do create song parts (as regions) and I am able to write that whole thing out to Reaper

If you are still around, please let me know!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.