#ifndef YAW_SCALE_INCLUDED #define YAW_SCALE_INCLUDED #include #include struct Note { std::string name; double hz; unsigned int number; }; static std::vector defaultNoteNames = { "A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#"}; class Scale { double sampleRate = 48000.0; // freqs in hz, periods in samples std::vector frequencies; std::vector periods; std::vector names; public: void newSampleRate(double rate) { double ratio = rate / sampleRate; sampleRate = rate; for (double ¬e : periods) note *= ratio; }; // Default ctor: 12TET @ 48kHz Scale(double hz = 440.0) { hz /= 64.0; for (int i = 0; i < 12 * 8; ++i) { frequencies.push_back(hz); periods.push_back(sampleRate / hz); names.push_back(defaultNoteNames[i % 12]); hz *= exp2(1.0 / 12.0); } } double getNearestPeriod(double period) { for (auto note : periods) { if (period > note) return note; } // This should NOT happen. return 0; } unsigned int getNearestNoteNumber(double hz) { for ( unsigned int i = 0; i < frequencies.size(); ++i ) { if (hz < frequencies[i]) return i; } return 0; } double getNearestFrequency(double hz) { for (auto note : frequencies) { if (hz < note) return note; } return 0; } // TODO: parse scala files. new ctor that parses arbitrary scales }; #endif