1 | #! /usr/bin/env python |
---|
2 | # -*- coding: utf-8 -*- |
---|
3 | |
---|
4 | from __future__ import unicode_literals |
---|
5 | |
---|
6 | from aubio import note2midi, freq2note, note2freq, float_type |
---|
7 | from numpy.testing import TestCase |
---|
8 | from _tools import parametrize, assert_raises, skipTest |
---|
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 ), |
---|
17 | ( 'C♯4', 61 ), |
---|
18 | ( 'A4', 69 ), |
---|
19 | ( 'A#4', 70 ), |
---|
20 | ( 'A♯4', 70 ), |
---|
21 | ( 'A\u266f4', 70 ), |
---|
22 | ( 'Bb4', 70 ), |
---|
23 | ( 'B♭4', 70 ), |
---|
24 | ( 'B\u266d4', 70 ), |
---|
25 | ( 'G8', 115 ), |
---|
26 | ( 'G♯8', 116 ), |
---|
27 | ( 'G9', 127 ), |
---|
28 | ( 'A♮2', 45 ), |
---|
29 | ) |
---|
30 | |
---|
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 | |
---|
47 | class Test_note2midi_good_values(object): |
---|
48 | |
---|
49 | @parametrize('note, midi', list_of_known_notes) |
---|
50 | def test_note2midi_known_values(self, note, midi): |
---|
51 | " known values are correctly converted " |
---|
52 | assert note2midi(note) == midi |
---|
53 | |
---|
54 | @parametrize('note, midi', list_of_known_notes_with_unicode_issues) |
---|
55 | def test_note2midi_known_values_with_unicode_issues(self, note, midi): |
---|
56 | " difficult values are correctly converted unless expected failure " |
---|
57 | try: |
---|
58 | assert note2midi(note) == midi |
---|
59 | except UnicodeEncodeError as e: |
---|
60 | # platforms with decoding failures include: |
---|
61 | # - osx: python <= 2.7.10 |
---|
62 | # - win: python <= 2.7.12 |
---|
63 | import sys |
---|
64 | strmsg = "len(u'\\U0001D12A') != 1, expected decoding failure" |
---|
65 | strmsg += " | upgrade to Python 3 to fix" |
---|
66 | strmsg += " | {:s} | {:s} {:s}" |
---|
67 | if len('\U0001D12A') != 1 and sys.version[0] == '2': |
---|
68 | skipTest(strmsg.format(repr(e), sys.platform, sys.version)) |
---|
69 | else: |
---|
70 | raise |
---|
71 | |
---|
72 | class note2midi_wrong_values(TestCase): |
---|
73 | |
---|
74 | def test_note2midi_missing_octave(self): |
---|
75 | " fails when passed only one character" |
---|
76 | self.assertRaises(ValueError, note2midi, 'C') |
---|
77 | |
---|
78 | def test_note2midi_wrong_modifier(self): |
---|
79 | " fails when passed a note with an invalid modifier " |
---|
80 | self.assertRaises(ValueError, note2midi, 'C.1') |
---|
81 | |
---|
82 | def test_note2midi_another_wrong_modifier_again(self): |
---|
83 | " fails when passed a note with a invalid note name " |
---|
84 | self.assertRaises(ValueError, note2midi, 'CB-3') |
---|
85 | |
---|
86 | def test_note2midi_wrong_octave(self): |
---|
87 | " fails when passed a wrong octave number " |
---|
88 | self.assertRaises(ValueError, note2midi, 'CBc') |
---|
89 | |
---|
90 | def test_note2midi_out_of_range(self): |
---|
91 | " fails when passed a note out of range" |
---|
92 | self.assertRaises(ValueError, note2midi, 'A9') |
---|
93 | |
---|
94 | def test_note2midi_wrong_note_name(self): |
---|
95 | " fails when passed a note with a wrong name" |
---|
96 | self.assertRaises(ValueError, note2midi, 'W9') |
---|
97 | |
---|
98 | def test_note2midi_low_octave(self): |
---|
99 | " fails when passed a note with a too low octave" |
---|
100 | self.assertRaises(ValueError, note2midi, 'C-9') |
---|
101 | |
---|
102 | def test_note2midi_wrong_data_type(self): |
---|
103 | " fails when passed a non-string value " |
---|
104 | self.assertRaises(TypeError, note2midi, 123) |
---|
105 | |
---|
106 | def test_note2midi_wrong_data_too_long(self): |
---|
107 | " fails when passed a note with a note name longer than expected" |
---|
108 | self.assertRaises(ValueError, note2midi, 'CB+-3') |
---|
109 | |
---|
110 | class Test_note2midi_unknown_values(object): |
---|
111 | |
---|
112 | @parametrize('note', list_of_unknown_notes) |
---|
113 | def test_note2midi_unknown_values(self, note): |
---|
114 | " unknown values throw out an error " |
---|
115 | assert_raises(ValueError, note2midi, note) |
---|
116 | |
---|
117 | class freq2note_simple_test(TestCase): |
---|
118 | |
---|
119 | def test_freq2note_above(self): |
---|
120 | " make sure freq2note(441) == A4 " |
---|
121 | self.assertEqual("A4", freq2note(441)) |
---|
122 | |
---|
123 | def test_freq2note_under(self): |
---|
124 | " make sure freq2note(439) == A4 " |
---|
125 | self.assertEqual("A4", freq2note(439)) |
---|
126 | |
---|
127 | class note2freq_simple_test(TestCase): |
---|
128 | |
---|
129 | def test_note2freq(self): |
---|
130 | " make sure note2freq('A3') == 220" |
---|
131 | self.assertEqual(220, note2freq("A3")) |
---|
132 | |
---|
133 | def test_note2freq_under(self): |
---|
134 | " make sure note2freq(A4) == 440" |
---|
135 | if float_type == 'float32': |
---|
136 | self.assertEqual(440, note2freq("A4")) |
---|
137 | else: |
---|
138 | self.assertLess(abs(note2freq("A4")-440), 1.e-12) |
---|
139 | |
---|
140 | if __name__ == '__main__': |
---|
141 | from _tools import run_module_suite |
---|
142 | run_module_suite() |
---|