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