# Better version of this https://paste.sr.ht/~jasper/59b874bc90e521ef100e7691204ef82cd55cabbc
#
# .. many possible variations on this, just edit the code.
#
# (obvious)Ideas:
# * output to a synthesizer.
# * like drawing it as it goes would be good.
# Played the midi with:
# Ran fluidsynth
# `fluidsynth -is -a pulseaudio -m alsa_seq -r 48000 "$SOME_SOUNDFONT.sf"`
# `/usr/share/soundfonts/FluidR3_GM.sf2` was on my disc, not ideal.
# Look for ports with `aplaymidi -l`
# `aplaymidi --port $PORT $FILE.mid`
from midiutil import MIDIFile # These two lines are dependencies
import pygraphviz
import sys, random, os
inp_file= sys.argv[1] # Graphviz .dot file.
def midi_graph_shared(midi, g, start=None, max_t=1000,
duration=1, volume=100, track=0, channel=0, dt=1):
cur = random.choice(list(g.iternodes())) if start is None is None else start
cnts = dict()
opts = list(g.iterneighbors(cur)) # NOTE: assuming its constant.
t = 0
while t < max_t:
cnt = cnts.get(cur, 0)
cnts[cur] = cnt + 1
cur = opts[(cnt - 1)%len(opts)]
next_opts = list(g.iterneighbors(cur))
n_overlap = len(set(next_opts).intersection(opts))
midi.addNote(track, channel, 52 + len(opts) + 8*n_overlap, t, duration, volume)
opts = next_opts
t += dt
midi = MIDIFile(1)
midi.addTempo(0, 0, 240)
g = pygraphviz.AGraph(filename=inp_file)
print("generate midi")
midi_graph_shared(midi, g)
print(f"write midi {inp_file}.mid")
with open(f"{inp_file}.mid", "wb") as output_file:
midi.writeFile(output_file)
midi.close()
print(f"Graphviz image `{inp_file}.png` of midi for good measure")
os.execvp('dot', ['dot', inp_file, '-Tpng', '-o', inp_file + ".png"])