Mozzi  version v1.1.0
sound synthesis library for Arduino
mozzi_midi.cpp
1 #include "mozzi_midi.h"
2 
3 /** @ingroup midi
4 Converts midi note number to frequency. Caution: this can take up to 400
5 microseconds to run. It can seriously mess up the audio output if you use it in
6 updateControl() or updateAudio(). This is a good choice in setup(), or where you
7 need precise midi-pitch conversion and aren't doing much other audio
8 calculation.
9 @note Beware this returns an invalid result for midi note 0.
10 @note Timing: ~350 us
11 @param midival a midi note number, 1.0 or greater. Like the mtof object in Pd, midi values can have fractions.
12 @return the frequency represented by the input midi note number..
13  */
14 
15 
16 #include "mozzi_pgmspace.h"
17 
18 float mtof(float midival)
19 {
20  // http://en.wikipedia.org/wiki/Note
21  // f = pow(2,(p-69/12) * 440Hz
22  // return pow(2.0,(midival-69.0/12.0) * 440.0;
23 
24  // code from AF_precision_synthesis sketch, copyright 2009, Adrian Freed.
25  float f = 0.0;
26  if(midival) f = 8.1757989156 * pow(2.0, midival/12.0);
27  return f;
28 }
29 
30 
31 /*
32 static float ucmtof(uint8_t midival)
33 {
34  return 8.1757989156 * pow(2.0, (float)midival/12.0);
35 }
36 */
37 
38 
39 
40 // static const float __attribute__(()) fmidiToFreq[128] =
41 // {
42 // ucmtof(0), ucmtof(1), ucmtof(2),ucmtof(3), ucmtof(4), ucmtof(5), ucmtof(6), ucmtof(7),
43 // ucmtof(8),ucmtof(9), ucmtof(10), ucmtof(11), ucmtof(12), ucmtof(13), ucmtof(14), ucmtof(15),
44 // ucmtof(16), ucmtof(17), ucmtof(18), ucmtof(19), ucmtof(20), ucmtof(21), ucmtof(22), ucmtof(23),
45 // ucmtof(24), ucmtof(25), ucmtof(26), ucmtof(27), ucmtof(28), ucmtof(29), ucmtof(30), ucmtof(31),
46 // ucmtof(32), ucmtof(33), ucmtof(34), ucmtof(35), ucmtof(36), ucmtof(37), ucmtof(38), ucmtof(39),
47 // ucmtof(40), ucmtof(41), ucmtof(42), ucmtof(43), ucmtof(44), ucmtof(45), ucmtof(46), ucmtof(47),
48 // ucmtof(48), ucmtof(49), ucmtof(50), ucmtof(51), ucmtof(52), ucmtof(53), ucmtof(54), ucmtof(55),
49 // ucmtof(56), ucmtof(57), ucmtof(58), ucmtof(59), ucmtof(60), ucmtof(61), ucmtof(62), ucmtof(63),
50 // ucmtof(64), ucmtof(65), ucmtof(66), ucmtof(67), ucmtof(68), ucmtof(69), ucmtof(70), ucmtof(71),
51 // ucmtof(72), ucmtof(73), ucmtof(74), ucmtof(75), ucmtof(76), ucmtof(77), ucmtof(78), ucmtof(79),
52 // ucmtof(80), ucmtof(81), ucmtof(82), ucmtof(83), ucmtof(84), ucmtof(85), ucmtof(86), ucmtof(87),
53 // ucmtof(88), ucmtof(89), ucmtof(90), ucmtof(91), ucmtof(92), ucmtof(93), ucmtof(94), ucmtof(95),
54 // ucmtof(96),ucmtof(97), ucmtof(98), ucmtof(99), ucmtof(100), ucmtof(101), ucmtof(102), ucmtof(103),
55 // ucmtof(104),ucmtof(105), ucmtof(106), ucmtof(107), ucmtof(108), ucmtof(109), ucmtof(110), ucmtof(111),
56 // ucmtof(112),ucmtof(113), ucmtof(114), ucmtof(115), ucmtof(116), ucmtof(117), ucmtof(118), ucmtof(119),
57 // ucmtof(120), ucmtof(121), ucmtof(122), ucmtof(123), ucmtof(124), ucmtof(125), ucmtof(126), ucmtof(127)
58 // };
59 //
60 // /** @ingroup midi
61 // Converts midi note number to frequency. Fast, but only accepts whole note values, no fractions.
62 // @param midival a midi note number. Unlike the mtof object in Pd, midi values can have fractions. Use mtof() or
63 // Q16n16_mtof() if you want to convert fractional midi values.
64 // @return the frequency represented by the input midi note number.
65 // @todo hard-code fmidiToFreq table instead of generating at startup, and add an interpolating m2f which returns a float.
66 // */
67 // float m2f(uint8_t midival)
68 // {
69 // return (float) pgm_read_float(fmidiToFreq+midival);
70 // }
71 
72 // static Q16n16 Q16n16_m2f(float midival)
73 // {
74 // return float_to_Q16n16(mtof(midival));
75 // }
76 
77 //static CONSTTABLE_STORAGE(Q16n16) midiToFreq[128] =
78 // {
79 // Q16n16_m2f(0), Q16n16_m2f(1), Q16n16_m2f(2),Q16n16_m2f(3), Q16n16_m2f(4), Q16n16_m2f(5), Q16n16_m2f(6), Q16n16_m2f(7),
80 // Q16n16_m2f(8),Q16n16_m2f(9), Q16n16_m2f(10), Q16n16_m2f(11), Q16n16_m2f(12), Q16n16_m2f(13), Q16n16_m2f(14), Q16n16_m2f(15),
81 // Q16n16_m2f(16), Q16n16_m2f(17), Q16n16_m2f(18), Q16n16_m2f(19), Q16n16_m2f(20), Q16n16_m2f(21), Q16n16_m2f(22), Q16n16_m2f(23),
82 // Q16n16_m2f(24), Q16n16_m2f(25), Q16n16_m2f(26), Q16n16_m2f(27), Q16n16_m2f(28), Q16n16_m2f(29), Q16n16_m2f(30), Q16n16_m2f(31),
83 // Q16n16_m2f(32), Q16n16_m2f(33), Q16n16_m2f(34), Q16n16_m2f(35), Q16n16_m2f(36), Q16n16_m2f(37), Q16n16_m2f(38), Q16n16_m2f(39),
84 // Q16n16_m2f(40), Q16n16_m2f(41), Q16n16_m2f(42), Q16n16_m2f(43), Q16n16_m2f(44), Q16n16_m2f(45), Q16n16_m2f(46), Q16n16_m2f(47),
85 // Q16n16_m2f(48), Q16n16_m2f(49), Q16n16_m2f(50), Q16n16_m2f(51), Q16n16_m2f(52), Q16n16_m2f(53), Q16n16_m2f(54), Q16n16_m2f(55),
86 // Q16n16_m2f(56), Q16n16_m2f(57), Q16n16_m2f(58), Q16n16_m2f(59), Q16n16_m2f(60), Q16n16_m2f(61), Q16n16_m2f(62), Q16n16_m2f(63),
87 // Q16n16_m2f(64), Q16n16_m2f(65), Q16n16_m2f(66), Q16n16_m2f(67), Q16n16_m2f(68), Q16n16_m2f(69), Q16n16_m2f(70), Q16n16_m2f(71),
88 // Q16n16_m2f(72), Q16n16_m2f(73), Q16n16_m2f(74), Q16n16_m2f(75), Q16n16_m2f(76), Q16n16_m2f(77), Q16n16_m2f(78), Q16n16_m2f(79),
89 // Q16n16_m2f(80), Q16n16_m2f(81), Q16n16_m2f(82), Q16n16_m2f(83), Q16n16_m2f(84), Q16n16_m2f(85), Q16n16_m2f(86), Q16n16_m2f(87),
90 // Q16n16_m2f(88), Q16n16_m2f(89), Q16n16_m2f(90), Q16n16_m2f(91), Q16n16_m2f(92), Q16n16_m2f(93), Q16n16_m2f(94), Q16n16_m2f(95),
91 // Q16n16_m2f(96),Q16n16_m2f(97), Q16n16_m2f(98), Q16n16_m2f(99), Q16n16_m2f(100), Q16n16_m2f(101), Q16n16_m2f(102), Q16n16_m2f(103),
92 // Q16n16_m2f(104),Q16n16_m2f(105), Q16n16_m2f(106), Q16n16_m2f(107), Q16n16_m2f(108), Q16n16_m2f(109), Q16n16_m2f(110), Q16n16_m2f(111),
93 // Q16n16_m2f(112),Q16n16_m2f(113), Q16n16_m2f(114), Q16n16_m2f(115), Q16n16_m2f(116), Q16n16_m2f(117), Q16n16_m2f(118), Q16n16_m2f(119),
94 // Q16n16_m2f(120), Q16n16_m2f(121), Q16n16_m2f(122), Q16n16_m2f(123), Q16n16_m2f(124), Q16n16_m2f(125), Q16n16_m2f(126), Q16n16_m2f(127)
95 // };
96 
97 
98 static CONSTTABLE_STORAGE(uint32_t) midiToFreq[128] =
99  {
100  0, 567670, 601425, 637188, 675077, 715219, 757748, 802806, 850544, 901120,
101  954703, 1011473, 1071618, 1135340, 1202851, 1274376, 1350154, 1430438, 1515497,
102  1605613, 1701088, 1802240, 1909406, 2022946, 2143236, 2270680, 2405702, 2548752,
103  2700309, 2860877, 3030994, 3211226, 3402176, 3604479, 3818813, 4045892, 4286472,
104  4541359, 4811404, 5097504, 5400618, 5721756, 6061988, 6422452, 6804352, 7208959,
105  7637627, 8091785, 8572945, 9082719, 9622808, 10195009, 10801235, 11443507,
106  12123974, 12844905, 13608704, 14417917, 15275252, 16183563, 17145888, 18165438,
107  19245616, 20390018, 21602470, 22887014, 24247948, 25689810, 27217408, 28835834,
108  30550514, 32367136, 34291776, 36330876, 38491212, 40780036, 43204940, 45774028,
109  48495912, 51379620, 54434816, 57671668, 61101028, 64734272, 68583552, 72661752,
110  76982424, 81560072, 86409880, 91548056, 96991792, 102759240, 108869632,
111  115343336, 122202056, 129468544, 137167104, 145323504, 153964848, 163120144,
112  172819760, 183096224, 193983648, 205518336, 217739200, 230686576, 244403840,
113  258937008, 274334112, 290647008, 307929696, 326240288, 345639520, 366192448,
114  387967040, 411036672, 435478400, 461373152, 488807680, 517874016, 548668224,
115  581294016, 615859392, 652480576, 691279040, 732384896, 775934592, 822073344
116  };
117 
118 
119 
120 /** @ingroup midi
121 Converts midi note number to frequency with speed and accuracy. Q16n16_mtofLookup() is a fast
122 alternative to (float) mtof(), and more accurate than (uint8_t) mtof(),
123 using Q16n16 fixed-point format instead of floats or uint8_t values. Q16n16_mtof()
124 uses cheap linear interpolation between whole midi-note frequency equivalents
125 stored in a lookup table, so is less accurate than the float version, mtof(),
126 for non-whole midi values.
127 @note Timing: ~8 us.
128 @param midival_fractional a midi note number in Q16n16 format, for fractional values.
129 @return the frequency represented by the input midi note number, in Q16n16
130 fixed point fractional integer format, where the lower word is a fractional value.
131 */
132 Q16n16 Q16n16_mtof(Q16n16 midival_fractional)
133 {
134  Q16n16 diff_fraction;
135  uint8_t index = midival_fractional >> 16;
136  uint16_t fraction = (uint16_t) midival_fractional; // keeps low word
137  Q16n16 freq1 = (Q16n16) FLASH_OR_RAM_READ<const uint32_t>(midiToFreq + index);
138  Q16n16 freq2 = (Q16n16) FLASH_OR_RAM_READ<const uint32_t>((midiToFreq + 1) + index);
139  Q16n16 difference = freq2 - freq1;
140  if (difference>=65536)
141  {
142  diff_fraction = ((difference>>8) * fraction) >> 8;
143  }
144  else
145  {
146  diff_fraction = (difference * fraction) >> 16;
147  }
148  return (Q16n16) (freq1+ diff_fraction);
149 }
150 
151 /** @ingroup midi
152 A good choice if you're using whole note values, want speed and simplicity, and accuracy isn't important.
153 @param midi_note a midi note number.
154 @return an integer approximation of the midi note's frequency.
155 */
156 int mtof(uint8_t midi_note){
157  return (FLASH_OR_RAM_READ<const uint32_t>(midiToFreq + midi_note) >> 16);
158 }
159 
160 
161 /** @ingroup midi
162 A good choice if you're using whole note values, want speed and simplicity, and accuracy isn't important.
163 @param midi_note a midi note number.
164 @return an integer approximation of the midi note's frequency.
165 */
166 int mtof(int midi_note){
167  return (FLASH_OR_RAM_READ<const uint32_t>(midiToFreq + midi_note) >> 16);
168 }
Q16n16 Q16n16_mtof(Q16n16 midival)
Converts midi note number to frequency with speed and accuracy.
Definition: mozzi_midi.cpp:132
float mtof(float x)
Converts midi note number to frequency.
Definition: mozzi_midi.cpp:18
#define CONSTTABLE_STORAGE(X)
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535...
Definition: mozzi_fixmath.h:46
int mtof(int midi_note)
A good choice if you&#39;re using whole note values, want speed and simplicity, and accuracy isn&#39;t import...
Definition: mozzi_midi.cpp:166