Midi to tidalcycles updates

As of 02/28/2022, I added some simple improvements and new features to MIDI to TidalCycles command-line converter (https://github.com/TylerMclaughlin/midi_to_tidalcycles). :octopus:


The tool works with Python 2 and python 3 versions of the midi module (thanks @hellocatfood !)

Trailing zeros for null values (rests) are consolidated, e.g.,0.0!23 is now simplified to 0!23.

Indenting has been improved, so now you can copy the large stacks representing MIDI output by the tool and more effortlessly define these unruly stacks as variables in let statements.

New Features

Two additional functionalities, extracting unique chords and extracting melody sequences are described below (copied from the project's readme):

Extracting chords from MIDI

This functionality allows you to extract a 'library' of chords/voicings from a MIDI passage. The output format is tailored for use in the select TidalCycles function (Conditions | Tidal Cycles).
This command extracts only the chords and ignores the rhythm, sustain, and velocity data of the MIDI file.

Duplicate chords found in the MIDI file are discarded.

The optional command-line argument after the MIDI file specifies the name of the produced library.

This example:

python src/extract_chords.py test_examples/jazz-chords_played-live_quadraphonic_125bpm.mid my_jazz_chord_library

produces the following copyable TidalCycles code:

-- 8 chords
let my_jazz_chord_library p = select p [n "[-8, -12, -5, -3]", n "[-4, -7, -10, -1]", n "[-3, -8, -5, 0]", n "[-4, -1, 2, -7]", n "[-5, -3, 4, 0]", n "[-4, 2, 5, -1]", n "[-3, 7, 0, 4]", n "[-1, 0, 4, 7]"]

where p, the input to select, is a float between 0 and 1 (or a pattern of floats!).

Extracting melodic sequences

This functionality extracts only the notes (and their velocities) in the order in which they are played in the MIDI file. The output format is two monophonic patterns: one for notes and one for amps (MIDI velocity between 0 and 1).

Why output a pattern of notes and a pattern of amplitudes? Patterns are a flexible starting point for composition.
They are a convenient input to the
variants of the nTake and ampTake functions I wrote (below). In addition to accepting patterns instead of a list, these variant functions also allow you to control the total number of notes or amplitudes to take. This can be used to limit the amount of "cross-rhythm chaos" that can happen when using a struct function with N notes and nTake with M != N notes, for example.

let patternToList pat = map value $ sortOn whole $ queryArc pat (Arc 0 1)                                       
    nT name amt p = nTake name (take amt (cycle (patternToList p)))                                             
    aT name amt p = ampTake name (take amt (cycle (patternToList p)))                                           

This example command

python src/extract_melody.py test_examples/simple_legato_monophonic.mid

autogenerates the following copyable TidalCycles code:

nT "notez" 5 "0 2 3 5 2"
# aT "ampz" 5 "0.79 0.79 0.79 0.79 0.79"

Thanks @RTylerMclaughlin ! I was going to go on this mission to write something like this.