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 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
|
"""MIDI output.
This module contains a class implementing a MIDI output device.
"""
__author__ = 'Florian Krause <florian@expyriment.org>, \
Oliver Lindemann <oliver@expyriment.org>'
__version__ = '0.7.0'
__revision__ = '55a4e7e'
__date__ = 'Wed Mar 26 14:33:37 2014 +0100'
import _midiout_defaults as defaults
import expyriment
from expyriment.io._input_output import Output
try:
from pygame import midi as _midi
_midi.init()
except:
_midi = None
class MidiOut(Output):
"""A class implementing a MIDI output.
**EXPERIMENTAL!**
Due to a bug in Pygame's midi module, closing a MidiOut (or the programme)
will cause an error message. Until this is fixed in Pygame, MidiOut will
stay in extras.
"""
@staticmethod
def get_devices():
"""Get a list of all MIDI output devices connected to the system."""
if _midi is None:
return
outdevices = []
all_ids = _midi.get_count()
for device_id in all_ids:
info = _midi.get_device_info(device_id)
if info[3] == 1:
outdevices.add([device_id, info[1]])
return outdevices
def __init__(self, device, latency=None, buffer_size=None):
"""Create a MIDI output.
Parameters
----------
device : int or str
id or name of the MIDI device
latency : int, optional
delay in ms applied to timestamp
buffer_size : int, optional
number of events to be buffered
"""
import types
if type(_midi) is not types.ModuleType:
raise ImportError("""Sorry, MIDI output is not supported on this computer.""")
if not expyriment._active_exp.is_initialized:
raise RuntimeError(
"Cannot create MidiOut before expyriment.initialize()!")
_midi.init()
Output.__init__(self)
self._id = device
if buffer_size is None:
buffer_size = defaults.midiout_buffer_size
self._buffer_size = buffer_size
if latency is None:
latency = defaults.midiout_latency
self._latency = latency
self.output = _midi.Output(device, latency, buffer_size)
@property
def id(self):
"""Getter for id."""
return self._id
@property
def buffer_size(self):
"""Getter for buffer_size."""
return self._buffer_size
@property
def latency(self):
"""Getter for latency."""
return self._latency
def close(self, abort=False):
"""Close the MIDI interface.
Parameters
----------
abort : bool, optional
abort messages in the buffer (default=True)
"""
if abort:
self.output.abort()
self.output.close()
def abort(self):
"""Terminates outgoing messages immediately."""
self.output.abort()
def send(self, event_list):
"""Send a list of MIDI events.
Each event should have the following format:
[status, data1, data2, data3], timestamp]
Notes
-----
The data fields are optional.
Parameters
----------
event_list : list
list of events to send
"""
self.output.write(event_list)
def send_short(self, status, data1=0, data2=0):
"""Send MIDI events of 3 bytes or less.
Parameters
----------
status : int
status of the event to send
data1 : int, optional
data1 of the event to send
data2 : int, optional
data2 of the event to send
"""
self.output.write_short(status, data1, data2)
def send_sysex(self, timestamp, message):
"""Send a System Exlusive message.
Parameters
----------
timestamp : int
when (in ms) to send the message
message : sit or list
message to send
"""
self.output.wirte_sys_ex(timestamp, message)
def select_instrument(self, instrument_id, channel=0):
"""Select an instrument.
Parameters
----------
instrument_id : int
id (0-127) of the instrument
channel : int, optional
MIDI channel for the instrument (default=0)
"""
self.output.set_instrument(instrument_id, channel)
def send_note_on(self, note, velocity=None, channel=0):
"""Send a note-on event.
Parameters
----------
note : int
note value
velocity : int, optional
velocity of the note
channel : int, optional
MIDI channel of the note (default=0)
"""
self.output.note_on(note, velocity, channel)
def send_note_off(self, note, velocity=None, channel=0):
"""Send a note-off event.
Parameters
----------
note : int
note value
velocity : int, optional
velocity of the note
channel : int, optional
MIDI channel of the note (default=0)
"""
self.output.note_off(note, velocity, channel)
|