source: python/demos/demo_wav2midi.py @ 3c6a3c4

feature/autosinkfeature/cnnfeature/cnn_orgfeature/constantqfeature/crepefeature/crepe_orgfeature/pitchshiftfeature/pydocstringsfeature/timestretchfix/ffmpeg5
Last change on this file since 3c6a3c4 was 3c6a3c4, checked in by Paul Brossier <piem@piem.org>, 7 years ago

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

  • Property mode set to 100755
File size: 2.1 KB
Line 
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
10import sys
11from aubio import source, notes
12from mido import Message, MetaMessage, MidiFile, MidiTrack, second2tick, bpm2tempo
13
14if len(sys.argv) < 3:
15    print("Usage: %s <filename> <output> [samplerate]" % sys.argv[0])
16    sys.exit(1)
17
18filename = sys.argv[1]
19midioutput = sys.argv[2]
20
21downsample = 1
22samplerate = 44100 // downsample
23if len( sys.argv ) > 3: samplerate = int(sys.argv[3])
24
25win_s = 512 // downsample # fft size
26hop_s = 256 // downsample # hop size
27
28s = source(filename, samplerate, hop_s)
29samplerate = s.samplerate
30
31tolerance = 0.8
32
33notes_o = notes("default", win_s, hop_s, samplerate)
34
35print("%8s" % "time","[ start","vel","last ]")
36
37# create a midi file
38mid = MidiFile()
39track = MidiTrack()
40mid.tracks.append(track)
41
42ticks_per_beat = mid.ticks_per_beat # default: 480
43bpm = 120 # default midi tempo
44
45tempo = bpm2tempo(bpm)
46track.append(MetaMessage('set_tempo', tempo=tempo))
47track.append(MetaMessage('time_signature', numerator=4, denominator=4))
48
49def frames2tick(frames, samplerate=samplerate):
50    sec = frames / float(samplerate)
51    tick = int(second2tick(sec, ticks_per_beat, tempo))
52    return tick
53
54sec = 7
55previous_note = None
56
57last_time = 0
58
59# total number of frames read
60total_frames = 0
61while 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
81mid.save(midioutput)
Note: See TracBrowser for help on using the repository browser.