![]() |
Mozzi
alpha 0.01.1t
sound synthesis library for Arduino
|
00001 #include "mozzi_midi.h" 00002 00013 // code from AF_precision_synthesis sketch, copyright 2009, Adrian Freed. 00014 float mtof(float midival) 00015 { 00016 return 8.1757989156 * pow(2.0, midival/12.0); 00017 } 00018 00019 00020 /* 00021 static float ucmtof(unsigned char midival) 00022 { 00023 return 8.1757989156 * pow(2.0, (float)midival/12.0); 00024 } 00025 */ 00026 00027 00028 00029 // static const float __attribute__(()) fmidiToFreq[128] = 00030 // { 00031 // ucmtof(0), ucmtof(1), ucmtof(2),ucmtof(3), ucmtof(4), ucmtof(5), ucmtof(6), ucmtof(7), 00032 // ucmtof(8),ucmtof(9), ucmtof(10), ucmtof(11), ucmtof(12), ucmtof(13), ucmtof(14), ucmtof(15), 00033 // ucmtof(16), ucmtof(17), ucmtof(18), ucmtof(19), ucmtof(20), ucmtof(21), ucmtof(22), ucmtof(23), 00034 // ucmtof(24), ucmtof(25), ucmtof(26), ucmtof(27), ucmtof(28), ucmtof(29), ucmtof(30), ucmtof(31), 00035 // ucmtof(32), ucmtof(33), ucmtof(34), ucmtof(35), ucmtof(36), ucmtof(37), ucmtof(38), ucmtof(39), 00036 // ucmtof(40), ucmtof(41), ucmtof(42), ucmtof(43), ucmtof(44), ucmtof(45), ucmtof(46), ucmtof(47), 00037 // ucmtof(48), ucmtof(49), ucmtof(50), ucmtof(51), ucmtof(52), ucmtof(53), ucmtof(54), ucmtof(55), 00038 // ucmtof(56), ucmtof(57), ucmtof(58), ucmtof(59), ucmtof(60), ucmtof(61), ucmtof(62), ucmtof(63), 00039 // ucmtof(64), ucmtof(65), ucmtof(66), ucmtof(67), ucmtof(68), ucmtof(69), ucmtof(70), ucmtof(71), 00040 // ucmtof(72), ucmtof(73), ucmtof(74), ucmtof(75), ucmtof(76), ucmtof(77), ucmtof(78), ucmtof(79), 00041 // ucmtof(80), ucmtof(81), ucmtof(82), ucmtof(83), ucmtof(84), ucmtof(85), ucmtof(86), ucmtof(87), 00042 // ucmtof(88), ucmtof(89), ucmtof(90), ucmtof(91), ucmtof(92), ucmtof(93), ucmtof(94), ucmtof(95), 00043 // ucmtof(96),ucmtof(97), ucmtof(98), ucmtof(99), ucmtof(100), ucmtof(101), ucmtof(102), ucmtof(103), 00044 // ucmtof(104),ucmtof(105), ucmtof(106), ucmtof(107), ucmtof(108), ucmtof(109), ucmtof(110), ucmtof(111), 00045 // ucmtof(112),ucmtof(113), ucmtof(114), ucmtof(115), ucmtof(116), ucmtof(117), ucmtof(118), ucmtof(119), 00046 // ucmtof(120), ucmtof(121), ucmtof(122), ucmtof(123), ucmtof(124), ucmtof(125), ucmtof(126), ucmtof(127) 00047 // }; 00048 // 00049 // /** @ingroup midi 00050 // Converts midi note number to frequency. Fast, but only accepts whole note values, no fractions. 00051 // @param midival a midi note number. Unlike the mtof object in Pd, midi values can have fractions. Use mtof() or 00052 // Q16n16_mtof() if you want to convert fractional midi values. 00053 // @return the frequency represented by the input midi note number. 00054 // @todo hard-code fmidiToFreq table instead of generating at startup, and add an interpolating m2f which returns a float. 00055 // */ 00056 // float m2f(unsigned char midival) 00057 // { 00058 // return (float) pgm_read_float(fmidiToFreq+midival); 00059 // } 00060 00061 // static Q16n16 Q16n16_m2f(float midival) 00062 // { 00063 // return float_to_Q16n16(mtof(midival)); 00064 // } 00065 00066 //static const Q16n16 __attribute__((progmem)) midiToFreq[128] = 00067 // { 00068 // Q16n16_m2f(0), Q16n16_m2f(1), Q16n16_m2f(2),Q16n16_m2f(3), Q16n16_m2f(4), Q16n16_m2f(5), Q16n16_m2f(6), Q16n16_m2f(7), 00069 // Q16n16_m2f(8),Q16n16_m2f(9), Q16n16_m2f(10), Q16n16_m2f(11), Q16n16_m2f(12), Q16n16_m2f(13), Q16n16_m2f(14), Q16n16_m2f(15), 00070 // Q16n16_m2f(16), Q16n16_m2f(17), Q16n16_m2f(18), Q16n16_m2f(19), Q16n16_m2f(20), Q16n16_m2f(21), Q16n16_m2f(22), Q16n16_m2f(23), 00071 // Q16n16_m2f(24), Q16n16_m2f(25), Q16n16_m2f(26), Q16n16_m2f(27), Q16n16_m2f(28), Q16n16_m2f(29), Q16n16_m2f(30), Q16n16_m2f(31), 00072 // Q16n16_m2f(32), Q16n16_m2f(33), Q16n16_m2f(34), Q16n16_m2f(35), Q16n16_m2f(36), Q16n16_m2f(37), Q16n16_m2f(38), Q16n16_m2f(39), 00073 // Q16n16_m2f(40), Q16n16_m2f(41), Q16n16_m2f(42), Q16n16_m2f(43), Q16n16_m2f(44), Q16n16_m2f(45), Q16n16_m2f(46), Q16n16_m2f(47), 00074 // Q16n16_m2f(48), Q16n16_m2f(49), Q16n16_m2f(50), Q16n16_m2f(51), Q16n16_m2f(52), Q16n16_m2f(53), Q16n16_m2f(54), Q16n16_m2f(55), 00075 // Q16n16_m2f(56), Q16n16_m2f(57), Q16n16_m2f(58), Q16n16_m2f(59), Q16n16_m2f(60), Q16n16_m2f(61), Q16n16_m2f(62), Q16n16_m2f(63), 00076 // Q16n16_m2f(64), Q16n16_m2f(65), Q16n16_m2f(66), Q16n16_m2f(67), Q16n16_m2f(68), Q16n16_m2f(69), Q16n16_m2f(70), Q16n16_m2f(71), 00077 // Q16n16_m2f(72), Q16n16_m2f(73), Q16n16_m2f(74), Q16n16_m2f(75), Q16n16_m2f(76), Q16n16_m2f(77), Q16n16_m2f(78), Q16n16_m2f(79), 00078 // Q16n16_m2f(80), Q16n16_m2f(81), Q16n16_m2f(82), Q16n16_m2f(83), Q16n16_m2f(84), Q16n16_m2f(85), Q16n16_m2f(86), Q16n16_m2f(87), 00079 // Q16n16_m2f(88), Q16n16_m2f(89), Q16n16_m2f(90), Q16n16_m2f(91), Q16n16_m2f(92), Q16n16_m2f(93), Q16n16_m2f(94), Q16n16_m2f(95), 00080 // Q16n16_m2f(96),Q16n16_m2f(97), Q16n16_m2f(98), Q16n16_m2f(99), Q16n16_m2f(100), Q16n16_m2f(101), Q16n16_m2f(102), Q16n16_m2f(103), 00081 // Q16n16_m2f(104),Q16n16_m2f(105), Q16n16_m2f(106), Q16n16_m2f(107), Q16n16_m2f(108), Q16n16_m2f(109), Q16n16_m2f(110), Q16n16_m2f(111), 00082 // Q16n16_m2f(112),Q16n16_m2f(113), Q16n16_m2f(114), Q16n16_m2f(115), Q16n16_m2f(116), Q16n16_m2f(117), Q16n16_m2f(118), Q16n16_m2f(119), 00083 // Q16n16_m2f(120), Q16n16_m2f(121), Q16n16_m2f(122), Q16n16_m2f(123), Q16n16_m2f(124), Q16n16_m2f(125), Q16n16_m2f(126), Q16n16_m2f(127) 00084 // }; 00085 00086 00087 static const uint32_t __attribute__((progmem)) midiToFreq[128] = 00088 { 00089 535809, 567670, 601425, 637188, 675077, 715219, 757748, 802806, 850544, 901120, 00090 954703, 1011473, 1071618, 1135340, 1202851, 1274376, 1350154, 1430438, 1515497, 00091 1605613, 1701088, 1802240, 1909406, 2022946, 2143236, 2270680, 2405702, 2548752, 00092 2700309, 2860877, 3030994, 3211226, 3402176, 3604479, 3818813, 4045892, 4286472, 00093 4541359, 4811404, 5097504, 5400618, 5721756, 6061988, 6422452, 6804352, 7208959, 00094 7637627, 8091785, 8572945, 9082719, 9622808, 10195009, 10801235, 11443507, 00095 12123974, 12844905, 13608704, 14417917, 15275252, 16183563, 17145888, 18165438, 00096 19245616, 20390018, 21602470, 22887014, 24247948, 25689810, 27217408, 28835834, 00097 30550514, 32367136, 34291776, 36330876, 38491212, 40780036, 43204940, 45774028, 00098 48495912, 51379620, 54434816, 57671668, 61101028, 64734272, 68583552, 72661752, 00099 76982424, 81560072, 86409880, 91548056, 96991792, 102759240, 108869632, 00100 115343336, 122202056, 129468544, 137167104, 145323504, 153964848, 163120144, 00101 172819760, 183096224, 193983648, 205518336, 217739200, 230686576, 244403840, 00102 258937008, 274334112, 290647008, 307929696, 326240288, 345639520, 366192448, 00103 387967040, 411036672, 435478400, 461373152, 488807680, 517874016, 548668224, 00104 581294016, 615859392, 652480576, 691279040, 732384896, 775934592, 822073344 00105 }; 00106 00107 00108 00121 Q16n16 Q16n16_mtof(Q16n16 midival_fractional) 00122 { 00123 Q16n16 diff_fraction; 00124 unsigned char index = midival_fractional >> 16; 00125 unsigned int fraction = (unsigned int) midival_fractional; // keeps low word 00126 Q16n16 freq1 = (Q16n16) pgm_read_dword(midiToFreq + index); 00127 Q16n16 freq2 = (Q16n16) pgm_read_dword(midiToFreq + (index+1)); 00128 Q16n16 difference = freq2 - freq1; 00129 if (difference>=65536) 00130 { 00131 diff_fraction = ((difference>>8) * fraction) >> 8; 00132 } 00133 else 00134 { 00135 diff_fraction = (difference * fraction) >> 16; 00136 } 00137 return (Q16n16) (freq1+ diff_fraction); 00138 } 00139 00145 unsigned int mtof(unsigned char midi_note){ 00146 return (unsigned int) (pgm_read_dword(midiToFreq + midi_note) >> 16); 00147 } 00148 00149 00155 unsigned int mtof(int midi_note){ 00156 return (unsigned int) (pgm_read_dword(midiToFreq + midi_note) >> 16); 00157 }