[7d89e61] | 1 | #! /usr/bin/env python |
---|
| 2 | # -*- coding: utf-8 -*- |
---|
[33102ab] | 3 | |
---|
[9b7f238] | 4 | from __future__ import unicode_literals |
---|
| 5 | |
---|
[27ed546] | 6 | from aubio import note2midi, freq2note, note2freq, float_type |
---|
[d554321] | 7 | from nose2.tools import params |
---|
[33102ab] | 8 | import unittest |
---|
| 9 | |
---|
| 10 | list_of_known_notes = ( |
---|
| 11 | ( 'C-1', 0 ), |
---|
| 12 | ( 'C#-1', 1 ), |
---|
| 13 | ( 'd2', 38 ), |
---|
| 14 | ( 'C3', 48 ), |
---|
| 15 | ( 'B3', 59 ), |
---|
| 16 | ( 'B#3', 60 ), |
---|
[3aad0b1] | 17 | ( 'C♯4', 61 ), |
---|
[33102ab] | 18 | ( 'A4', 69 ), |
---|
| 19 | ( 'A#4', 70 ), |
---|
[3aad0b1] | 20 | ( 'A♯4', 70 ), |
---|
| 21 | ( 'A\u266f4', 70 ), |
---|
[f552e9e] | 22 | ( 'Bb4', 70 ), |
---|
[9b7f238] | 23 | ( 'B♭4', 70 ), |
---|
[3aad0b1] | 24 | ( 'B\u266d4', 70 ), |
---|
[33102ab] | 25 | ( 'G8', 115 ), |
---|
[9b7f238] | 26 | ( 'G♯8', 116 ), |
---|
[33102ab] | 27 | ( 'G9', 127 ), |
---|
[9b7f238] | 28 | ( 'A♮2', 45 ), |
---|
[33102ab] | 29 | ) |
---|
| 30 | |
---|
[3aad0b1] | 31 | list_of_known_notes_with_unicode_issues = ( |
---|
| 32 | ('C𝄪4', 62 ), |
---|
| 33 | ('E𝄫4', 62 ), |
---|
| 34 | ) |
---|
| 35 | |
---|
| 36 | list_of_unknown_notes = ( |
---|
| 37 | ( 'G\udd2a2' ), |
---|
| 38 | ( 'B\ufffd2' ), |
---|
| 39 | ( 'B\u266e\u266e2' ), |
---|
| 40 | ( 'B\u266f\u266d3' ), |
---|
| 41 | ( 'B33' ), |
---|
| 42 | ( 'C.3' ), |
---|
| 43 | ( 'A' ), |
---|
| 44 | ( '2' ), |
---|
| 45 | ) |
---|
| 46 | |
---|
[7d89e61] | 47 | class note2midi_good_values(unittest.TestCase): |
---|
[33102ab] | 48 | |
---|
[d554321] | 49 | @params(*list_of_known_notes) |
---|
| 50 | def test_note2midi_known_values(self, note, midi): |
---|
[33102ab] | 51 | " known values are correctly converted " |
---|
[d554321] | 52 | self.assertEqual ( note2midi(note), midi ) |
---|
[33102ab] | 53 | |
---|
[3aad0b1] | 54 | @params(*list_of_known_notes_with_unicode_issues) |
---|
| 55 | def test_note2midi_known_values_with_unicode_issues(self, note, midi): |
---|
| 56 | " known values are correctly converted, unless decoding is expected to fail" |
---|
| 57 | try: |
---|
| 58 | self.assertEqual ( note2midi(note), midi ) |
---|
| 59 | except UnicodeEncodeError as e: |
---|
| 60 | import sys |
---|
| 61 | strfmt = "len(u'\\U0001D12A') != 1, excpected decoding failure | {:s} | {:s} {:s}" |
---|
| 62 | strres = strfmt.format(e, sys.platform, sys.version) |
---|
| 63 | # happens with: darwin 2.7.10, windows 2.7.12 |
---|
| 64 | if len('\U0001D12A') != 1 and sys.version[0] == '2': |
---|
| 65 | self.skipTest(strres + " | upgrade to Python 3 to fix") |
---|
| 66 | else: |
---|
| 67 | raise |
---|
| 68 | |
---|
[7d89e61] | 69 | class note2midi_wrong_values(unittest.TestCase): |
---|
[33102ab] | 70 | |
---|
| 71 | def test_note2midi_missing_octave(self): |
---|
| 72 | " fails when passed only one character" |
---|
| 73 | self.assertRaises(ValueError, note2midi, 'C') |
---|
| 74 | |
---|
| 75 | def test_note2midi_wrong_modifier(self): |
---|
[f552e9e] | 76 | " fails when passed a note with an invalid modifier " |
---|
[33102ab] | 77 | self.assertRaises(ValueError, note2midi, 'C.1') |
---|
| 78 | |
---|
[f552e9e] | 79 | def test_note2midi_another_wrong_modifier_again(self): |
---|
| 80 | " fails when passed a note with a invalid note name " |
---|
[33102ab] | 81 | self.assertRaises(ValueError, note2midi, 'CB-3') |
---|
| 82 | |
---|
| 83 | def test_note2midi_wrong_octave(self): |
---|
[f552e9e] | 84 | " fails when passed a wrong octave number " |
---|
[33102ab] | 85 | self.assertRaises(ValueError, note2midi, 'CBc') |
---|
| 86 | |
---|
| 87 | def test_note2midi_out_of_range(self): |
---|
[6db7600] | 88 | " fails when passed a note out of range" |
---|
[33102ab] | 89 | self.assertRaises(ValueError, note2midi, 'A9') |
---|
| 90 | |
---|
[6db7600] | 91 | def test_note2midi_wrong_note_name(self): |
---|
| 92 | " fails when passed a note with a wrong name" |
---|
| 93 | self.assertRaises(ValueError, note2midi, 'W9') |
---|
| 94 | |
---|
[0b6d23d] | 95 | def test_note2midi_low_octave(self): |
---|
| 96 | " fails when passed a note with a too low octave" |
---|
[6db7600] | 97 | self.assertRaises(ValueError, note2midi, 'C-9') |
---|
| 98 | |
---|
[f552e9e] | 99 | def test_note2midi_wrong_data_type(self): |
---|
| 100 | " fails when passed a non-string value " |
---|
| 101 | self.assertRaises(TypeError, note2midi, 123) |
---|
| 102 | |
---|
[3aad0b1] | 103 | def test_note2midi_wrong_data_too_long(self): |
---|
| 104 | " fails when passed a note with a note name longer than expected" |
---|
| 105 | self.assertRaises(ValueError, note2midi, 'CB+-3') |
---|
| 106 | |
---|
| 107 | @params(*list_of_unknown_notes) |
---|
| 108 | def test_note2midi_unknown_values(self, note): |
---|
| 109 | " unknown values throw out an error " |
---|
| 110 | self.assertRaises(ValueError, note2midi, note) |
---|
[6db7600] | 111 | |
---|
| 112 | class freq2note_simple_test(unittest.TestCase): |
---|
| 113 | |
---|
[4afeac2] | 114 | def test_freq2note_above(self): |
---|
[6db7600] | 115 | " make sure freq2note(441) == A4 " |
---|
[376d5e9] | 116 | self.assertEqual("A4", freq2note(441)) |
---|
[6db7600] | 117 | |
---|
[4afeac2] | 118 | def test_freq2note_under(self): |
---|
| 119 | " make sure freq2note(439) == A4 " |
---|
| 120 | self.assertEqual("A4", freq2note(439)) |
---|
| 121 | |
---|
[e9a4402] | 122 | class note2freq_simple_test(unittest.TestCase): |
---|
| 123 | |
---|
| 124 | def test_note2freq(self): |
---|
| 125 | " make sure note2freq('A3') == 220" |
---|
| 126 | self.assertEqual(220, note2freq("A3")) |
---|
| 127 | |
---|
| 128 | def test_note2freq_under(self): |
---|
| 129 | " make sure note2freq(A4) == 440" |
---|
[27ed546] | 130 | if float_type == 'float32': |
---|
| 131 | self.assertEqual(440, note2freq("A4")) |
---|
| 132 | else: |
---|
| 133 | self.assertLess(abs(note2freq("A4")-440), 1.e-12) |
---|
[e9a4402] | 134 | |
---|
[33102ab] | 135 | if __name__ == '__main__': |
---|
[d554321] | 136 | import nose2 |
---|
| 137 | nose2.main() |
---|