Package toon :: Module midi
[hide private]
[frames] | no frames]

Source Code for Module toon.midi

  1  #!/usr/bin/env python 
  2  """ 
  3  MIDI input using pygame and twisted. 
  4  """ 
  5  import sys 
  6  import os 
  7   
  8  import pygame 
  9  import pygame.midi 
 10  from pygame.locals import * 
 11   
 12  from twisted.internet import reactor 
 13  from twisted.internet import task 
 14   
15 -class NotConnectedError(Exception):
16 """ 17 Raised when trying to start the simple midi input when not connected. 18 """ 19 pass
20
21 -class SimpleMidiInput(object):
22 """ 23 MIDI input using pygame.midi. 24 """
25 - def __init__(self, input_id=None, verbose=True):
26 if input_id == -1: 27 input_id = None # -1 is an alias for None 28 self.input_id = input_id 29 self.midi_input = None 30 self.is_connected = False 31 self.verbose = verbose 32 self._use_dummy_display = False # for tests. 33 self.convert_to_pygame_event = False 34 self.callbacks = [] 35 36 # initiate MIDI 37 self._setup_input() 38 self._looping_call = task.LoopingCall(self.poll)
39
40 - def print_devices_info(self, input_only=True):
41 """ 42 Prints infos on all MIDI input devices. 43 """ 44 if input_only: 45 print("MIDI input devices:") 46 for i in range(pygame.midi.get_count()): 47 r = pygame.midi.get_device_info(i) 48 (interf, name, input, output, opened) = r 49 in_out = "" 50 if input: 51 in_out = "(input)" 52 if output: 53 in_out = "(output)" 54 if input_only is False or input: 55 print("%2i: interface :%s:, name :%s:, opened :%s: %s" % (i, interf, name, opened, in_out))
56
57 - def _verb(self, txt):
58 """ 59 Prints INFO messages 60 """ 61 if self.verbose: 62 print(txt)
63
64 - def _setup_input(self):
65 if self.convert_to_pygame_event: 66 pygame.fastevent.init() 67 pygame.midi.init() 68 #if self.verbose: 69 self.print_devices_info() 70 self._verb("MIDIIN event : %s" % (str(pygame.midi.MIDIIN))) 71 if self.input_id is None: 72 self.input_id = pygame.midi.get_default_input_id() 73 self._verb("Using input_id :%s:" % (self.input_id)) 74 try: 75 self.midi_input = pygame.midi.Input(self.input_id) 76 self.is_connected = True 77 except pygame.midi.MidiException, e: 78 print(e.message) 79 self.is_connected = False 80 if self._use_dummy_display: # for tests 81 pygame.display.set_mode((1, 1))
82
83 - def start(self):
84 """ 85 Starts polling 86 Returns a deferred whose callback will be invoked with self when self.stop is called, 87 or whose errback will be invoked when the function raises an exception or returned a 88 deferred that has its errback invoked. 89 """ 90 if self.is_connected: 91 interval = 0.05 92 return self._looping_call.start(interval) 93 else: 94 raise NotConnectedError("We are not connected to any MIDI device !")
95
96 - def poll(self):
97 #try: 98 #while going: 99 # if self.convert_to_pygame_event: 100 # events = pygame.fastevent.get() 101 # for e in events: 102 # if e.type in [QUIT]: 103 # going = False 104 # if e.type in [KEYDOWN]: 105 # going = False 106 # if e.type in [pygame.midi.MIDIIN]: 107 # print (e) 108 if self.midi_input.poll(): 109 midi_events = self.midi_input.read(10) 110 # convert them into pygame events. 111 midi_events = pygame.midi.midis2events(midi_events, self.midi_input.device_id) 112 for midi_event in midi_events: 113 self._verb("GOT MIDI EVENT: %s" % (midi_event)) 114 self._call_callbacks(midi_event) 115 if self.convert_to_pygame_event: 116 pygame.fastevent.post(midi_event)
117
118 - def register_callback(self, callback):
119 if callback not in self.callbacks: 120 self.callbacks.append(callback)
121
122 - def _call_callbacks(self, event):
123 """ 124 Called when a MIDI event occurs. 125 """ 126 for cb in self.callbacks: 127 cb(event)
128
129 - def __del__(self):
130 del self.midi_input 131 pygame.midi.quit()
132 133 if __name__ == '__main__':
134 - def _cb(event):
135 if event.status == 144: # MIDI note 136 print("MIDI note: Pitch: %s Velocity: %s" % (event.data1, event.data2)) 137 elif event.status == 176: # MIDI control 138 print("MIDI control: ID: %s Value: %s" % (event.data1, event.data2))
139 140 try: 141 device_id = int(sys.argv[-1]) 142 except: 143 device_id = None 144 pygame.init() 145 midi_input_manager = SimpleMidiInput(device_id) 146 midi_input_manager.register_callback(_cb) 147 midi_input_manager.start() 148 try: 149 reactor.run() 150 except KeyboardInterrupt: 151 print "quit." 152