1 /*
2 * High accuracy program to create HTML formatted
3 * list of musical note names, MIDI note numbers
4 * and actual frequencies.
5 * Only covers the useful range of note numbers
6 * not the full range.
7 *
8 * Note:
9 * you can get an approximation of 12root2 with:
10 * 196 / 185
11 * this gives:
12 * 1.05946
13 *
14 * 07/08/2021
15 *
16 * g++ -Wall midiListGen.cpp -o midiListGen
17 *
18 */
19 #include <math.h>
20 #include <limits>
21 #include <iostream>
22 #include <fstream>
23 #include <string>
24 #include <vector>
25 #include <sstream>
26 #include <cstring>
27 #include <regex>
28
29 using namespace std;
30
asLongString(double n,size_t digits)31 std::string asLongString(double n, size_t digits)
32 {
33 std::ostringstream oss;
34 oss.precision(digits);
35 oss.width(digits);
36 oss << n;
37 std::string value = oss.str();
38 value = std::regex_replace(value, std::regex("^ +"), "");
39
40 if (value.find('.') == std::string::npos)
41 value += '.';
42 while (value.length() <= digits)
43 value += '0';
44 return value;
45 }
46
47
main(void)48 int main(void)
49 { // we use doubles for greatest accuracy then reduce the result.
50 // this minimises accumulated errors from repeated multiplication
51 double twelfth = 12.0;
52 double two = 2.0;
53 double multiplier;
54 multiplier = pow(two, 1 / twelfth);
55 std::cout.precision(10);
56 std::cout << "twelfth root of two = " << multiplier << std::endl;
57
58 static std::string names [] = {
59 "A", "#", "B", "C", "#", "D", "#", "E", "F", "#", "G", "#"
60 };
61 int stringcount = 0;
62 int octave = 0;
63 double result = 27.5;
64 int precision = 6;
65 std::string currentNote;
66 std::string fullString;
67 std::vector <std::string> ourlist;
68 for (int i = 21; i < 109; ++i) // practical MIDI note range
69 {
70 currentNote = names[stringcount];
71 if (currentNote == "C")
72 ++ octave;
73 if (currentNote != "#")
74 currentNote += std::to_string(octave);
75 ++ stringcount;
76 if (stringcount >= 12)
77 stringcount = 0;
78 fullString = " <td>" + currentNote + "</td><td>" + std::to_string(i) + "</td><td>" + asLongString(result, precision) + "</td>";
79 ourlist.push_back(" </tr>");
80 ourlist.push_back(fullString);
81 ourlist.push_back(" <tr align=\"center\">");
82 result *= multiplier;
83 }
84 size_t idx = ourlist.size();
85 ofstream midiList;
86 midiList.open("midiList.txt");
87 if (!midiList.is_open())
88 {
89 std::cout << "Failed to open midiList.txt" << std::endl;
90 return 0;
91 }
92 while (idx > 0)
93 {
94 --idx;
95 midiList << ourlist[idx] << endl;
96 }
97 midiList.close();
98 return 0;
99 }
100