Mozzi  version v2.0
sound synthesis library for Arduino
mozzi_midi.h
1 /*
2  * mozzi_midi.h
3  *
4  * This file is part of Mozzi.
5  *
6  * Copyright 2012-2024 Tim Barrass and the Mozzi Team
7  *
8  * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
9  *
10  */
11 
12 #ifndef MOZZI_MIDI_H_
13 #define MOZZI_MIDI_H_
14 
15 #include "mozzi_fixmath.h"
16 #include "FixMath.h"
17 
18 #include "mozzi_pgmspace.h"
19 
24 private:
25  friend int mtof(uint8_t);
26  friend int mtof(int);
27  friend Q16n16 Q16n16_mtof(Q16n16);
28  template<int8_t NI, uint64_t RANGE>
29  friend UFix<16,16> mtof(UFix<NI,0,RANGE>);
30 
31  template<int8_t NI, uint64_t RANGE>
32  friend UFix<16,16> mtof(SFix<NI,0,RANGE>);
33 
34  static CONSTTABLE_STORAGE(uint32_t) midiToFreq[128];
35 };
36 
37 
38 CONSTTABLE_STORAGE(uint32_t) MidiToFreqPrivate::midiToFreq[128] =
39  {
40  0, 567670, 601425, 637188, 675077, 715219, 757748, 802806, 850544, 901120,
41  954703, 1011473, 1071618, 1135340, 1202851, 1274376, 1350154, 1430438, 1515497,
42  1605613, 1701088, 1802240, 1909406, 2022946, 2143236, 2270680, 2405702, 2548752,
43  2700309, 2860877, 3030994, 3211226, 3402176, 3604479, 3818813, 4045892, 4286472,
44  4541359, 4811404, 5097504, 5400618, 5721756, 6061988, 6422452, 6804352, 7208959,
45  7637627, 8091785, 8572945, 9082719, 9622808, 10195009, 10801235, 11443507,
46  12123974, 12844905, 13608704, 14417917, 15275252, 16183563, 17145888, 18165438,
47  19245616, 20390018, 21602470, 22887014, 24247948, 25689810, 27217408, 28835834,
48  30550514, 32367136, 34291776, 36330876, 38491212, 40780036, 43204940, 45774028,
49  48495912, 51379620, 54434816, 57671668, 61101028, 64734272, 68583552, 72661752,
50  76982424, 81560072, 86409880, 91548056, 96991792, 102759240, 108869632,
51  115343336, 122202056, 129468544, 137167104, 145323504, 153964848, 163120144,
52  172819760, 183096224, 193983648, 205518336, 217739200, 230686576, 244403840,
53  258937008, 274334112, 290647008, 307929696, 326240288, 345639520, 366192448,
54  387967040, 411036672, 435478400, 461373152, 488807680, 517874016, 548668224,
55  581294016, 615859392, 652480576, 691279040, 732384896, 775934592, 822073344
56  };
57 
58 
75 inline float mtof(float midival)
76 {
77  // http://en.wikipedia.org/wiki/Note
78  // f = pow(2,(p-69/12) * 440Hz
79  // return pow(2.0,(midival-69.0/12.0) * 440.0;
80 
81  // code from AF_precision_synthesis sketch, copyright 2009, Adrian Freed.
82  float f = 0.0;
83  if(midival) f = 8.1757989156 * pow(2.0, midival/12.0);
84  return f;
85 };
86 
87 
93 inline int mtof(uint8_t midi_note){
94  return (FLASH_OR_RAM_READ<const uint32_t>(MidiToFreqPrivate::midiToFreq + midi_note) >> 16);
95 };
96 
102 inline int mtof(int midi_note){
103  return (FLASH_OR_RAM_READ<const uint32_t>(MidiToFreqPrivate::midiToFreq + midi_note) >> 16);
104 };
105 
106 
119 inline Q16n16 Q16n16_mtof(Q16n16 midival_fractional)
120 {
121  Q16n16 diff_fraction;
122  uint8_t index = midival_fractional >> 16;
123  uint16_t fraction = (uint16_t) midival_fractional; // keeps low word
124  Q16n16 freq1 = (Q16n16) FLASH_OR_RAM_READ<const uint32_t>(MidiToFreqPrivate::midiToFreq + index);
125  Q16n16 freq2 = (Q16n16) FLASH_OR_RAM_READ<const uint32_t>((MidiToFreqPrivate::midiToFreq + 1) + index);
126  Q16n16 difference = freq2 - freq1;
127  if (difference>=65536)
128  {
129  diff_fraction = ((difference>>8) * fraction) >> 8;
130  }
131  else
132  {
133  diff_fraction = (difference * fraction) >> 16;
134  }
135  return (Q16n16) (freq1+ diff_fraction);
136 };
137 
142 template <uint64_t RANGE>
143 inline UFix<16,16> mtof(UFix<16,16,RANGE> midival)
144 {
145  return UFix<16,16>::fromRaw(Q16n16_mtof(midival.asRaw()));
146 };
147 
152 template<int8_t NI, int8_t NF, uint64_t RANGE>
153 inline UFix<16,16> mtof(UFix<NI,NF,RANGE> midival)
154 {
155  return UFix<16,16>::fromRaw(Q16n16_mtof(UFix<16,16>(midival).asRaw()));
156 };
157 
162 template<int8_t NI, int8_t NF, uint64_t RANGE>
163 inline UFix<16,16> mtof(SFix<NI,NF,RANGE> midival)
164 {
165  return UFix<16,16>::fromRaw(Q16n16_mtof(UFix<16,16>(midival).asRaw()));
166 };
167 
171 template<int8_t NI, uint64_t RANGE>
172 inline UFix<16,16> mtof(UFix<NI,0,RANGE> midival)
173 {
174  return UFix<16,16>::fromRaw((FLASH_OR_RAM_READ<const uint32_t>(MidiToFreqPrivate::midiToFreq + midival.asRaw())));
175 };
176 
180 template<int8_t NI, uint64_t RANGE>
181 inline UFix<16,16> mtof(SFix<NI,0,RANGE> midival)
182 {
183  return UFix<16,16>::fromRaw((FLASH_OR_RAM_READ<const uint32_t>(MidiToFreqPrivate::midiToFreq + midival.asUFix().asRaw())));
184 };
185 
186 #endif /* MOZZI_MIDI_H_ */
friend Q16n16 Q16n16_mtof(Q16n16)
Converts midi note number to frequency with speed and accuracy.
Definition: mozzi_midi.h:119
friend int mtof(uint8_t)
A good choice if you're using whole note values, want speed and simplicity, and accuracy isn't import...
Definition: mozzi_midi.h:93
#define CONSTTABLE_STORAGE(X)
Declare a variable such that it will be stored in flash memory, instead of RAM, on platforms where th...
uint32_t Q16n16
unsigned fractional number using 16 integer bits and 16 fractional bits, represents 0 to 65535....
Definition: mozzi_fixmath.h:52
Q16n16 Q16n16_mtof(Q16n16 midival_fractional)
Converts midi note number to frequency with speed and accuracy.
Definition: mozzi_midi.h:119
float mtof(float midival)
Converts midi note number to frequency.
Definition: mozzi_midi.h:75