1 # -*- coding: ISO-8859-1 -*-
8 MidiOutstream is Basically an eventhandler. It is the most central
9 class in the Midi library. You use it both for writing events to
10 an output stream, and as an event handler for an input stream.
12 This makes it extremely easy to take input from one stream and
13 send it to another. Ie. if you want to read a Midi file, do some
14 processing, and send it to a midiport.
16 All time values are in absolute values from the opening of a
17 stream. To calculate time values, please use the MidiTime and
18 MidiDeltaTime classes.
24 # the time is rather global, so it needs to be stored
25 # here. Otherwise there would be no really simple way to
26 # calculate it. The alternative would be to have each event
27 # handler do it. That sucks even worse!
28 self
._absolute
_time
= 0
29 self
._relative
_time
= 0
30 self
._current
_track
= 0
31 self
._running
_status
= None
33 # time handling event handlers. They should be overwritten with care
35 def update_time(self
, new_time
=0, relative
=1):
37 Updates the time, if relative is true, new_time is relative,
41 self
._relative
_time
= new_time
42 self
._absolute
_time
+= new_time
44 self
._relative
_time
= new_time
- self
._absolute
_time
45 self
._absolute
_time
= new_time
51 self
._relative
_time
= 0
52 self
._absolute
_time
= 0
55 "Returns the relative time"
56 return self
._relative
_time
59 "Returns the absolute time"
60 return self
._absolute
_time
62 # running status methods
64 def reset_run_stat(self
):
65 "Invalidates the running status"
66 self
._running
_status
= None
68 def set_run_stat(self
, new_status
):
69 "Set the new running status"
70 self
._running
_status
= new_status
72 def get_run_stat(self
):
73 "Set the new running status"
74 return self
._running
_status
76 # track handling event handlers
78 def set_current_track(self
, new_track
):
79 "Sets the current track number"
80 self
._current
_track
= new_track
82 def get_current_track(self
):
83 "Returns the current track number"
84 return self
._current
_track
91 def channel_message(self
, message_type
, channel
, data
):
92 """The default event handler for channel messages"""
96 def note_on(self
, channel
=0, note
=0x40, velocity
=0x40):
100 note, velocity: 0-127
105 def note_off(self
, channel
=0, note
=0x40, velocity
=0x40):
109 note, velocity: 0-127
114 def aftertouch(self
, channel
=0, note
=0x40, velocity
=0x40):
118 note, velocity: 0-127
123 def continuous_controller(self
, channel
, controller
, value
):
127 controller, value: 0-127
132 def patch_change(self
, channel
, patch
):
141 def channel_pressure(self
, channel
, pressure
):
150 def pitch_bend(self
, channel
, value
):
162 #####################
165 def system_exclusive(self
, data
):
168 data: list of values in range(128)
173 #####################
176 def song_position_pointer(self
, value
):
184 def song_select(self
, songNumber
):
192 def tuning_request(self
):
200 def midi_time_code(self
, msg_type
, values
):
208 #########################
209 # header does not really belong here. But anyhoo!!!
211 def header(self
, format
=0, nTracks
=1, division
=96):
214 format: type of midi file in [1,2]
215 nTracks: number of tracks
216 division: timing division
224 End of file. No more events to be processed.
229 #####################
233 def meta_event(self
, meta_type
, data
):
236 Handles any undefined meta events
241 def start_of_track(self
, n_track
=0):
244 n_track: number of track
249 def end_of_track(self
):
252 n_track: number of track
257 def sequence_number(self
, value
):
265 def text(self
, text
):
274 def copyright(self
, text
):
283 def sequence_name(self
, text
):
292 def instrument_name(self
, text
):
300 def lyric(self
, text
):
308 def marker(self
, text
):
316 def cuepoint(self
, text
):
324 def midi_ch_prefix(self
, channel
):
327 channel: midi channel for subsequent data (deprecated in the spec)
332 def midi_port(self
, value
):
335 value: Midi port (deprecated in the spec)
340 def tempo(self
, value
):
344 tempo in us/quarternote
345 (to calculate value from bpm: int(60,000,000.00 / BPM))
350 def smtp_offset(self
, hour
, minute
, second
, frame
, framePart
):
355 second: 3 bytes specifying the hour (0-23), minutes (0-59) and
356 seconds (0-59), respectively. The hour should be
357 encoded with the SMPTE format, just as it is in MIDI
359 frame: A byte specifying the number of frames per second (one
360 of : 24, 25, 29, 30).
361 framePart: A byte specifying the number of fractional frames,
362 in 100ths of a frame (even in SMPTE-based tracks
363 using a different frame subdivision, defined in the
370 def time_signature(self
, nn
, dd
, cc
, bb
):
373 nn: Numerator of the signature as notated on sheet music
374 dd: Denominator of the signature as notated on sheet music
375 The denominator is a negative power of 2: 2 = quarter
376 note, 3 = eighth, etc.
377 cc: The number of MIDI clocks in a metronome click
378 bb: The number of notated 32nd notes in a MIDI quarter note
385 def key_signature(self
, sf
, mi
):
388 sf: is a byte specifying the number of flats (-ve) or sharps
389 (+ve) that identifies the key signature (-7 = 7 flats, -1
390 = 1 flat, 0 = key of C, 1 = 1 sharp, etc).
391 mi: is a byte specifying a major (0) or minor (1) key.
397 def sequencer_specific(self
, data
):
400 data: The data as byte values
407 #####################
410 def timing_clock(self
):
419 def song_start(self
):
437 def song_continue(self
):
446 def active_sensing(self
):
455 def system_reset(self
):
464 if __name__
== '__main__':
466 midiOut
= MidiOutStream()
467 midiOut
.update_time(0,0)
468 midiOut
.note_on(0, 63, 127)
469 midiOut
.note_off(0, 63, 127)