History

python/demos/demo_wav2midi.py: add simple midi file writer using mido (closes: #134)

Paul Brossier committed 9 years ago

Commit 3c6a3c41 parent 34ce7151 file · +81 −0Browse files

Showing the changes to python (1 of 1 file). Show all

Unified · Split

python/demos/demo_wav2midi.py+81−0
@@ -0,0 +1,81 @@
1+#! /usr/bin/env python
2+
3+# Simple demo to extract notes from a sound file, and store them in a midi file
4+# using mido.
5+#
6+# Install mido: `pip instal mido`
7+#
8+# Documentation: https://mido.readthedocs.io/
9+
10+import sys
11+from aubio import source, notes
12+from mido import Message, MetaMessage, MidiFile, MidiTrack, second2tick, bpm2tempo
13+
14+if len(sys.argv) < 3:
15+ print("Usage: %s <filename> <output> [samplerate]" % sys.argv[0])
16+ sys.exit(1)
17+
18+filename = sys.argv[1]
19+midioutput = sys.argv[2]
20+
21+downsample = 1
22+samplerate = 44100 // downsample
23+if len( sys.argv ) > 3: samplerate = int(sys.argv[3])
24+
25+win_s = 512 // downsample # fft size
26+hop_s = 256 // downsample # hop size
27+
28+s = source(filename, samplerate, hop_s)
29+samplerate = s.samplerate
30+
31+tolerance = 0.8
32+
33+notes_o = notes("default", win_s, hop_s, samplerate)
34+
35+print("%8s" % "time","[ start","vel","last ]")
36+
37+# create a midi file
38+mid = MidiFile()
39+track = MidiTrack()
40+mid.tracks.append(track)
41+
42+ticks_per_beat = mid.ticks_per_beat # default: 480
43+bpm = 120 # default midi tempo
44+
45+tempo = bpm2tempo(bpm)
46+track.append(MetaMessage('set_tempo', tempo=tempo))
47+track.append(MetaMessage('time_signature', numerator=4, denominator=4))
48+
49+def frames2tick(frames, samplerate=samplerate):
50+ sec = frames / float(samplerate)
51+ tick = int(second2tick(sec, ticks_per_beat, tempo))
52+ return tick
53+
54+sec = 7
55+previous_note = None
56+
57+last_time = 0
58+
59+# total number of frames read
60+total_frames = 0
61+while True:
62+ samples, read = s()
63+ new_note = notes_o(samples)
64+ if (new_note[0] != 0):
65+ note_str = ' '.join(["%.2f" % i for i in new_note])
66+ print("%.6f" % (total_frames/float(samplerate)), new_note)
67+ delta = frames2tick(total_frames) - last_time
68+ if new_note[2] > 0:
69+ track.append(Message('note_off', note=int(new_note[2]),
70+ velocity=127, time=0)
71+ )
72+ track.append(Message('note_on',
73+ note=int(new_note[0]),
74+ velocity=int(new_note[1]),
75+ time=delta)
76+ )
77+ last_time = frames2tick(total_frames)
78+ total_frames += read
79+ if read < hop_s: break
80+
81+mid.save(midioutput)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t