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).
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
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
Two additional functionalities, extracting unique chords and extracting melody sequences are described below (copied from the project's readme):
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.
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]"]
p, the input to
select, is a float between 0 and 1 (or a pattern of floats!).
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
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"