MATLAB: How to use MATLAB to search through inputs and return an answer

note analysis

This is probably a really bad way to ask this question. I am not even really sure what it would be called besides a goal seek. I have written a code to analyze a frequency played on a phone or musical instrument, really anything. I have it so it will return what frequency is played but I want it to return what note is being played instead. Is there a better way to do this than just a bunch of if statements? I have included a sample of my code. It shows the name of the input, the transform, how to get the frequency, and some of the values for the frequencies.
myrecording = getaudiodata(recobj); %analyzes the recording
n=length(myrecording)-1; f=0:fs/n:fs;
A=abs(fft(myrecording)); figure(2) plot(f,A)
[X,Y] = max(A);
F = (Y/3)-(0.497);
fprintf('The frequency in hertz is %.2f\n',F)
C2 = 65.41; D2 = 69.30; E2 = 73.42; F2 = 87.31; G2 = 98; A2 = 110; B2 = 123.47; C3 = 130.81; D3 = 146.83; E3 = 164.81; F3 = 174.61; G3 = 196; A3 = 220; B3 = 246.94;

Best Answer

  • Rather than thinking about each note as being its own individual variable, this is much simpler when we realize that they are all instances of one set of data "notes", so they should be stored together. So keep the data in two vectors, one numeric for the frequencies and one cell for the note strings, with corresponding entries:
    freq_vec = [65.41, 69.30, 73.42, 87.31, ...];
    note_vec = { 'C2', 'D2', 'E2', 'F2', ...};
    then you can simply locate the closest frequency to a sample frequency by using min:
    freq_val = 70;
    [~,idx] = min(abs(freq_vec - freq_val));
    and you can simply get the note string:
    >> note_vec{idx}
    ans = 'D2'
    Putting the numeric values together in one vector will make any operation that you care to attempt much easier, from numeric or arithmetic operations, to searches and matching.