Spaces:
Runtime error
Runtime error
File size: 4,804 Bytes
e775f6d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
import mido
mido.set_backend('mido.backends.pygame')
from mido import Message, MidiFile, MidiTrack
import time
import pynput
import sys
sys.path.append('../../')
from src.music.config import SYNTH_RECORDED_MIDI_PATH
from datetime import datetime
#TODO: debug this with other cable, keyboard and sound card
global KEY_PRESSED
KEY_PRESSED = None
def on_press(key):
global KEY_PRESSED
try:
KEY_PRESSED = key.name
except:
pass
def on_release(key):
global KEY_PRESSED
KEY_PRESSED = None
def is_pressed(key):
global KEY_PRESSED
return KEY_PRESSED == key
# keyboard listener
listener = pynput.keyboard.Listener(on_press=on_press, on_release=on_release)
listener.start()
LEN_MIDI_RECORDINGS = 30
class MidiRecorder:
def __init__(self, place='', len_midi_recordings=LEN_MIDI_RECORDINGS):
self.place = place
self.len_midi_recordings = len_midi_recordings
self.port = mido.open_input(mido.get_input_names()[0])
def get_filename(self):
now = datetime.now()
return self.place + '_' + now.strftime("%b_%d_%Y_%Hh%Mm%Ss") + '.mid'
def read_last_midi_msgs(self):
return list(self.port.iter_pending())
def live_read(self):
while not is_pressed('esc'):
for msg in self.read_last_midi_msgs():
print(msg)
def check_if_recording_started(self, msgs, t_init):
started = False
if len(msgs) > 0:
for m in msgs:
if m.type == 'note_on':
started = True
t_init = time.time()
return started, t_init
def create_empty_midi(self):
mid = MidiFile()
track = MidiTrack()
mid.tracks.append(track)
track.append(Message('program_change', program=0, time=0))
return mid, track
def record_next_N_seconds(self, n=None, saving_path=None):
if saving_path is None:
saving_path = SYNTH_RECORDED_PATH + self.get_filename()
if n is None:
n = self.len_midi_recordings
print(f'Recoding the next {n} secs.'
f'\n\tRecording starts when the first key is pressed;'
f'\n\tPress Enter to end the recording;'
f'\n\tPress BackSpace (<--) to cancel the recording;'
f'\n\tSaving to {saving_path}')
try:
mid, track = self.create_empty_midi()
started = False
backspace_pressed = False
t_init = time.time()
while not is_pressed('enter') and (time.time() - t_init) < n:
msgs = self.read_last_midi_msgs()
if not started:
started, t_init = self.check_if_recording_started(msgs, t_init)
if started:
print("\n\t--> First note pressed, it's on!")
for m in msgs:
print(m)
if m.type == 'note_on' and m.velocity == 0:
m_off = Message(type='note_off', velocity=127, note=m.note, channel=m.channel, time=m.time)
track.append(m_off)
track.append(m)
if is_pressed('backspace'):
backspace_pressed = True
print('\n \t--> Recording cancelled! (you pressed BackSpace)')
break
# save the file
if not backspace_pressed and len(mid.tracks[0]) > 0:
mid.save(saving_path)
print(f'\n--> Recording saved, duration: {mid.length:.2f} secs, {len(mid.tracks[0])} events.')
except:
print('\n --> The recording failed.')
def run(self):
# with pynput.Listener(
# on_press=self.on_press) as listener:
# listener.join()
ready_msg = False
print('Starting the recording loop!\n\tPress BackSpace to cancel the current recording;\n\tPress Esc to quit the loop (only works while not recording)')
while True:
if not ready_msg:
print('-------\nReady to record!')
print('Press space to start a recording\n')
ready_msg = True
if is_pressed('space'):
self.record_next_N_seconds()
ready_msg = False
if is_pressed('esc'):
print('End of the recording session. See you soon!')
break
midi_recorder = MidiRecorder(place='home')
midi_recorder.live_read()
# midi_recorder.run()
# try:
# controls[msg.control] = msg.value
# except:
# notes.append(msg.note)
# port = mido.open_input()
# while True:
# for msg in port.iter_pending():
# print(msg)
#
# print('start pause')
# time.sleep(5)
# print('stop pause') |