问题
I'd like to listen to the port having my midi output device (a piano) with my RPi, running on Debian. I've looked into pygame.midi, I managed to listen to the port, but somehow can not extract all midi information. Please find code below [edited code snippet]
EDIT: Fixed, thanks a lot!
回答1:
First of all you need to find out which device-id your keyboard has inside pygame. I wrote this little function to find out:
import pygame.midi
def print_devices():
for n in range(pygame.midi.get_count()):
print (n,pygame.midi.get_device_info(n))
if __name__ == '__main__':
pygame.midi.init()
print_devices()
It looks something like this:
(0, ('MMSystem', 'Microsoft MIDI Mapper', 0, 1, 0))
(1, ('MMSystem', '6- Saffire 6USB', 1, 0, 0))
(2, ('MMSystem', 'MK-249C USB MIDI keyboard', 1, 0, 0))
(3, ('MMSystem', 'Microsoft GS Wavetable Synth', 0, 1, 0))
From the pygame manual you can learn that the first One inside this info-tuple determines this device as a suitable Input-Device. So let's read some data from it in an endless-loop:
def readInput(input_device):
while True:
if input_device.poll():
event = input_device.read(1)
print (event)
if __name__ == '__main__':
pygame.midi.init()
my_input = pygame.midi.Input(2) #only in my case the id is 2
readInput(my_input)
That shows:
[[[144, 24, 120, 0], 1321]]
that we have a list of a list with 2 items:
- A list of midi-data and
- a timestamp
The second value is the one you're interested in. So we print it out as a note:
def number_to_note(number):
notes = ['c', 'c#', 'd', 'd#', 'e', 'f', 'f#', 'g', 'g#', 'a', 'a#', 'b']
return notes[number%12]
def readInput(input_device):
while True:
if input_device.poll():
event = input_device.read(1)[0]
data = event[0]
timestamp = event[1]
note_number = data[1]
velocity = data[2]
print (number_to_note(note_number), velocity)
I hope this helped. It's my first answer, I hope it's not too long. :)
来源:https://stackoverflow.com/questions/15768066/reading-piano-notes-on-python