File: midiListGen.cpp

package info (click to toggle)
yoshimi 2.3.6-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 17,012 kB
  • sloc: cpp: 62,589; xml: 97; sh: 94; python: 45; makefile: 14
file content (100 lines) | stat: -rw-r--r-- 2,580 bytes parent folder | download | duplicates (3)
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;
}