123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385 |
- import unittest
- import os
- import sys
- import time
- import pygame
- import pygame.midi
- import pygame.compat
- from pygame.locals import *
- class MidiInputTest(unittest.TestCase):
- def setUp(self):
- pygame.midi.init()
- in_id = pygame.midi.get_default_input_id()
- if in_id != -1:
- self.midi_input = pygame.midi.Input(in_id)
- else:
- self.midi_input = None
- def tearDown(self):
- if self.midi_input:
- self.midi_input.close()
- pygame.midi.quit()
- def test_Input(self):
- """|tags: interactive|
- """
- i = pygame.midi.get_default_input_id()
- if self.midi_input:
- self.assertEqual(self.midi_input.device_id, i)
- # try feeding it an input id.
- i = pygame.midi.get_default_output_id()
- # can handle some invalid input too.
- self.assertRaises(pygame.midi.MidiException, pygame.midi.Input, i)
- self.assertRaises(pygame.midi.MidiException, pygame.midi.Input, 9009)
- self.assertRaises(pygame.midi.MidiException, pygame.midi.Input, -1)
- self.assertRaises(TypeError, pygame.midi.Input, "1234")
- self.assertRaises(OverflowError, pygame.midi.Input, pow(2, 99))
- def test_poll(self):
- if not self.midi_input:
- self.skipTest('No midi Input device')
- self.assertFalse(self.midi_input.poll())
- # TODO fake some incoming data
- pygame.midi.quit()
- self.assertRaises(RuntimeError, self.midi_input.poll)
- # set midi_input to None to avoid error in tearDown
- self.midi_input = None
- def test_read(self):
- if not self.midi_input:
- self.skipTest('No midi Input device')
- read = self.midi_input.read(5)
- self.assertEqual(read, [])
- # TODO fake some incoming data
- pygame.midi.quit()
- self.assertRaises(RuntimeError, self.midi_input.read, 52)
- # set midi_input to None to avoid error in tearDown
- self.midi_input = None
- def test_close(self):
- if not self.midi_input:
- self.skipTest('No midi Input device')
- self.assertIsNotNone(self.midi_input._input)
- self.midi_input.close()
- self.assertIsNone(self.midi_input._input)
- class MidiOutputTest(unittest.TestCase):
- def setUp(self):
- pygame.midi.init()
- m_out_id = pygame.midi.get_default_output_id()
- if m_out_id != -1:
- self.midi_output = pygame.midi.Output(m_out_id)
- else:
- self.midi_output = None
- def tearDown(self):
- if self.midi_output:
- self.midi_output.close()
- pygame.midi.quit()
- def test_Output(self):
- """|tags: interactive|
- """
- i = pygame.midi.get_default_output_id()
- if self.midi_output:
- self.assertEqual(self.midi_output.device_id, i)
- # try feeding it an input id.
- i = pygame.midi.get_default_input_id()
- # can handle some invalid input too.
- self.assertRaises(pygame.midi.MidiException, pygame.midi.Output, i)
- self.assertRaises(pygame.midi.MidiException, pygame.midi.Output, 9009)
- self.assertRaises(pygame.midi.MidiException, pygame.midi.Output, -1)
- self.assertRaises(TypeError, pygame.midi.Output,"1234")
- self.assertRaises(OverflowError, pygame.midi.Output, pow(2,99))
- def test_note_off(self):
- """|tags: interactive|
- """
- if self.midi_output:
- out = self.midi_output
- out.note_on(5, 30, 0)
- out.note_off(5, 30, 0)
- with self.assertRaises(ValueError) as cm:
- out.note_off(5, 30, 25)
- self.assertEqual(str(cm.exception), "Channel not between 0 and 15.")
- with self.assertRaises(ValueError) as cm:
- out.note_off(5, 30, -1)
- self.assertEqual(str(cm.exception), "Channel not between 0 and 15.")
- def test_note_on(self):
- """|tags: interactive|
- """
- if self.midi_output:
- out = self.midi_output
- out.note_on(5, 30, 0)
- out.note_on(5, 42, 10)
- with self.assertRaises(ValueError) as cm:
- out.note_on(5, 30, 25)
- self.assertEqual(str(cm.exception), "Channel not between 0 and 15.")
- with self.assertRaises(ValueError) as cm:
- out.note_on(5, 30, -1)
- self.assertEqual(str(cm.exception), "Channel not between 0 and 15.")
- def test_set_instrument(self):
- if not self.midi_output:
- self.skipTest('No midi device')
- out = self.midi_output
- out.set_instrument(5)
- out.set_instrument(42, channel=2)
- with self.assertRaises(ValueError) as cm:
- out.set_instrument(-6)
- self.assertEqual(str(cm.exception), "Undefined instrument id: -6")
- with self.assertRaises(ValueError) as cm:
- out.set_instrument(156)
- self.assertEqual(str(cm.exception), "Undefined instrument id: 156")
- with self.assertRaises(ValueError) as cm:
- out.set_instrument(5, -1)
- self.assertEqual(str(cm.exception), "Channel not between 0 and 15.")
- with self.assertRaises(ValueError) as cm:
- out.set_instrument(5, 16)
- self.assertEqual(str(cm.exception), "Channel not between 0 and 15.")
- def test_write(self):
- if not self.midi_output:
- self.skipTest('No midi device')
- out = self.midi_output
- out.write([[[0xc0, 0, 0], 20000]])
- # is equivalent to
- out.write([[[0xc0], 20000]])
- # example from the docstring :
- # 1. choose program change 1 at time 20000 and
- # 2. send note 65 with velocity 100 500 ms later
- out.write([
- [[0xc0, 0, 0], 20000],
- [[0x90, 60, 100], 20500]
- ])
- out.write([])
- verrry_long = [[[0x90, 60, i % 100], 20000 + 100 * i] for i in range(1024)]
- out.write(verrry_long)
- too_long = [[[0x90, 60, i % 100], 20000 + 100 * i] for i in range(1025)]
- self.assertRaises(IndexError, out.write, too_long)
- # test wrong data
- with self.assertRaises(TypeError) as cm:
- out.write('Non sens ?')
- error_msg = "unsupported operand type(s) for &: 'str' and 'int'"
- self.assertEqual(str(cm.exception), error_msg)
- with self.assertRaises(TypeError) as cm:
- out.write(["Hey what's that?"])
- self.assertEqual(str(cm.exception), error_msg)
- def test_write_short(self):
- """|tags: interactive|
- """
- if not self.midi_output:
- self.skipTest('No midi device')
- out = self.midi_output
- # program change
- out.write_short(0xc0)
- # put a note on, then off.
- out.write_short(0x90, 65, 100)
- out.write_short(0x80, 65, 100)
- out.write_short(0x90)
- def test_write_sys_ex(self):
- if not self.midi_output:
- self.skipTest('No midi device')
- out = self.midi_output
- out.write_sys_ex(pygame.midi.time(),
- [0xF0, 0x7D, 0x10, 0x11, 0x12, 0x13, 0xF7])
- def test_pitch_bend(self):
- # FIXME : pitch_bend in the code, but not in documentation
- if not self.midi_output:
- self.skipTest('No midi device')
- out = self.midi_output
- with self.assertRaises(ValueError) as cm:
- out.pitch_bend(5, channel=-1)
- self.assertEqual(str(cm.exception), "Channel not between 0 and 15.")
- with self.assertRaises(ValueError) as cm:
- out.pitch_bend(5, channel=16)
- with self.assertRaises(ValueError) as cm:
- out.pitch_bend(-10001, 1)
- self.assertEqual(str(cm.exception), "Pitch bend value must be between "
- "-8192 and +8191, not -10001.")
- with self.assertRaises(ValueError) as cm:
- out.pitch_bend(10665, 2)
- def test_close(self):
- if not self.midi_output:
- self.skipTest('No midi device')
- self.assertIsNotNone(self.midi_output._output)
- self.midi_output.close()
- self.assertIsNone(self.midi_output._output)
- def test_abort(self):
- if not self.midi_output:
- self.skipTest('No midi device')
- self.assertEqual(self.midi_output._aborted, 0)
- self.midi_output.abort()
- self.assertEqual(self.midi_output._aborted, 1)
- class MidiModuleTest(unittest.TestCase):
- def setUp(self):
- pygame.midi.init()
- def tearDown(self):
- pygame.midi.quit()
- def test_MidiException(self):
- def raiseit():
- raise pygame.midi.MidiException('Hello Midi param')
- with self.assertRaises(pygame.midi.MidiException) as cm:
- raiseit()
- self.assertEqual(cm.exception.parameter, 'Hello Midi param')
- def test_get_count(self):
- c = pygame.midi.get_count()
- self.assertIsInstance(c, int)
- self.assertTrue(c >= 0)
- def test_get_default_input_id(self):
- midin_id = pygame.midi.get_default_input_id()
- # if there is a not None return make sure it is an int.
- self.assertIsInstance(midin_id, int)
- self.assertTrue(midin_id >= -1)
- pygame.midi.quit()
- self.assertRaises(RuntimeError, pygame.midi.get_default_output_id)
- def test_get_default_output_id(self):
- c = pygame.midi.get_default_output_id()
- self.assertIsInstance(c, int)
- self.assertTrue(c >= -1)
- pygame.midi.quit()
- self.assertRaises(RuntimeError, pygame.midi.get_default_output_id)
- def test_get_device_info(self):
- an_id = pygame.midi.get_default_output_id()
- if an_id != -1:
- interf, name, input, output, opened = pygame.midi.get_device_info(an_id)
- self.assertEqual(output, 1)
- self.assertEqual(input, 0)
- self.assertEqual(opened, 0)
- an_in_id = pygame.midi.get_default_input_id()
- if an_in_id != -1:
- r = pygame.midi.get_device_info(an_in_id)
- # if r is None, it means that the id is out of range.
- interf, name, input, output, opened = r
- self.assertEqual(output, 0)
- self.assertEqual(input, 1)
- self.assertEqual(opened, 0)
- out_of_range = pygame.midi.get_count()
- for num in range(out_of_range):
- self.assertIsNotNone(pygame.midi.get_device_info(num))
- info = pygame.midi.get_device_info(out_of_range)
- self.assertIsNone(info)
- def test_init(self):
- pygame.midi.quit()
- self.assertRaises(RuntimeError, pygame.midi.get_count)
- # initialising many times should be fine.
- pygame.midi.init()
- pygame.midi.init()
- pygame.midi.init()
- pygame.midi.init()
- self.assertTrue(pygame.midi.get_init())
- def test_midis2events(self):
- midi_data = ([[0xc0, 0, 1, 2], 20000],
- [[0x90, 60, 100, 'blablabla'], 20000]
- )
- events = pygame.midi.midis2events(midi_data, 2)
- self.assertEqual(len(events), 2)
- for eve in events:
- # pygame.event.Event is a function, but ...
- self.assertEqual(eve.__class__.__name__, 'Event')
- self.assertEqual(eve.vice_id, 2)
- # FIXME I don't know what we want for the Event.timestamp
- # For now it accepts it accepts int as is:
- self.assertIsInstance(eve.timestamp, int)
- self.assertEqual(eve.timestamp, 20000)
- self.assertEqual(events[1].data3, 'blablabla')
- def test_quit(self):
- # It is safe to call this more than once.
- pygame.midi.quit()
- pygame.midi.init()
- pygame.midi.quit()
- pygame.midi.quit()
- pygame.midi.init()
- pygame.midi.init()
- pygame.midi.quit()
- self.assertFalse(pygame.midi.get_init())
- def test_get_init(self):
- # Already initialized as pygame.midi.init() was called in setUp().
- self.assertTrue(pygame.midi.get_init())
- def test_time(self):
- mtime = pygame.midi.time()
- self.assertIsInstance(mtime, int)
- # should be close to 2-3... since the timer is just init'd.
- self.assertTrue(0 <= mtime < 100)
- def test_conversions(self):
- """ of frequencies to midi note numbers and ansi note names.
- """
- from pygame.midi import (
- frequency_to_midi, midi_to_frequency, midi_to_ansi_note
- )
- self.assertEqual(frequency_to_midi(27.5), 21)
- self.assertEqual(frequency_to_midi(36.7), 26)
- self.assertEqual(frequency_to_midi(4186.0), 108)
- self.assertEqual(midi_to_frequency(21), 27.5)
- self.assertEqual(midi_to_frequency(26), 36.7)
- self.assertEqual(midi_to_frequency(108), 4186.0)
- self.assertEqual(midi_to_ansi_note(21), 'A0')
- self.assertEqual(midi_to_ansi_note(102), 'F#7')
- self.assertEqual(midi_to_ansi_note(108), 'C8')
- if __name__ == '__main__':
- unittest.main()
|