27 lines
920 B
C++
27 lines
920 B
C++
#pragma once
|
|
|
|
#include <cmath>
|
|
#include <algorithm>
|
|
|
|
// Applicable for standard (even temperament) MIDI tuning only.
|
|
// The formula connecting the MIDI note number and the base frequency assume equal tuning based
|
|
// on A4 = 440 Hz.
|
|
constexpr int NUM_MIDI_KEYS = 128; // Also inclusive of 0 & 128, apparently.
|
|
constexpr double A4_FREQUENCY = 440.0; // Hz
|
|
constexpr int A4_MIDI_KEY = 69; // Hehe
|
|
constexpr int KEYS_PER_OCTAVE = 12;
|
|
|
|
// Template parameter allows for (non-standard) fractional keys.
|
|
template <typename T>
|
|
constexpr double MidiKeyToFrequency(T key) {
|
|
return A4_FREQUENCY * std::pow(2, (key - A4_MIDI_KEY) / KEYS_PER_OCTAVE);
|
|
}
|
|
|
|
constexpr double frequencyToMidiKey(double f) {
|
|
return ((KEYS_PER_OCTAVE * std::log2(f / A4_FREQUENCY)) + A4_MIDI_KEY);
|
|
}
|
|
|
|
constexpr int frequencyToNearestMidiKey(double f) {
|
|
return std::clamp(static_cast<int>(std::round(frequencyToMidiKey(f))), 0, NUM_MIDI_KEYS);
|
|
}
|