9

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!

YanisM
  • 101
  • 1
  • 4
  • I'd look into Pyserial http://pyserial.sourceforge.net/shortintro.html – That1Guy Apr 02 '13 at 15:45
  • I don't think MIDI is serial. – ninMonkey Apr 02 '13 at 16:39
  • 2
    Can you post sample code? It's really difficult to diagnose a problem without the code. – adahlin Apr 02 '13 at 16:40
  • Yeah I basically downloaded and installed the pygame package and I think it's something you can do with pygame.midi (I've seen youtube videos of guys do it: youtube.com/watch?v=jhNow4cUMV8 ). I don't have any specific code, I played around with most of the functions on here : https://pygame.readthedocs.org/en/latest/ref/midi.html#pygame.midi.Input.read and none of them seems to be what I need.. – YanisM Apr 02 '13 at 16:47
  • 2
    If you show us how you've been using them, we might be able to point something out. Showing someone your code can be scary (especially in an expert community like Stack Overflow), but it'll be worth it for good feedback. – Hannele Apr 02 '13 at 19:07
  • 1
    @monkey MIDI is serial ( http://en.wikipedia.org/wiki/MIDI ) – That1Guy Apr 03 '13 at 04:37

1 Answers1

14

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. :)

Fusselgesicht
  • 189
  • 2
  • 6