Find closest value in C ++ with nonlinear progression

It is a bit complicated, but carrying with me. I am trying to create a map that links the names of musical notes with their respective frequencies. Then I want to write a function that, provided that a random frequency returns the note closest to that frequency.

The problem is that note frequencies are not generated by a linear formula, so the frequency, which is the exact medium between each note, is also not linear. (This basically means that the midpoint between the notes is not quite in the middle, so finding the midpoint with conventional methods does not work.)

Example code used to create a note map:

// Ordered starting with "B" so notes line up with frequencies vector<string> names = { "B", "C", "C#/Db", "D", "D#/Eb", "E", "F", "F#/Gb", "G", "G#/Ab", "A", "A#/Bb" }; double f0 = 440; map<string, map<int, double> > notes; // Map notes to their corresponding frequencies for (int octave = 0; octave < 10; ++octave) { for (int index = 0; index < names.size(); ++index) { // Get the exact frequency of the musical note double frequency = f0*pow(pow(2, 1.0/12), index - 10)*pow(pow(2, 1.0/12), 12*(octave + 1 - 5)); // Get the exact frequency between this note and the next (I'm not doing anything with this yet, but I feel like this is on the right track.) double frequency_between_notes = f0*pow(pow(2, 1.0/12), index + 0.5 - 10)*pow(pow(2, 1.0/12), 12*(octave + 1 - 5)); notes[names[index]][octave] = frequency; } } 

I want to write a function that, at a random frequency, will return the note closest to that frequency.

 Note& find_note(double frequency) { // Provided a random frequency find the ACTUAL nearest note using the non-linear formula that notes are calculated from. // Create the note object and return it. } 

The Note class looks something like this:

 class Note { public: Note(string name, int octave, double frequency) { name_ = name; octave_ = octave; frequency_ = frequency; } const string& get_name() const { return name_; } const int& get_octave() const { return octave_; } const double& get_frequency() const { return frequency_; } private: string name_; int octave_; double frequency_; }; 

The equation used to calculate note frequencies is taken from https://pages.mtu.edu/~suits/NoteFreqCalcs.html .

How to find the nearest note at a random frequency?

+7
c ++ dictionary math algorithm music
source share
1 answer

The logarithm of the halftone frequencies is evenly distributed. To find the closest note to a given frequency, simply take the frequency log and find the closest note frequency log.

Here is a simple function that takes a frequency in Hz and returns the nearest semitone, since the number of semitones is higher (positive) or lower (negative) A4 (440 Hz)

 const double LOG_SEMITONE = log(2.0)/12.0; int getNote(double f) { double note = log(f/440.0) / LOG_SEMITONE; return (int)round(note); } 
+6
source share

All Articles