Author Topic: Matlab musical notes dedection  (Read 3578 times)

0 Members and 1 Guest are viewing this topic.

Offline KaramelTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: tr
Matlab musical notes dedection
« on: November 09, 2016, 07:18:20 pm »
Hi everyone,

I am, almost, done in my note dedector project. When I was starting this project, I was so hopeless but now, I had gone so much progress.

I can dedect these notes C4,D4,E4,F4,G4,A4,B4,C5 but, C4 and C5 have a problem. They gives same harmonic peaks. You can copy the codes which are at below and also you are able to compile your matlab. if you have a microphone and musical enstruments (if you have a smart phone, you can install perfect piano I suggest to use it)

You can see these peaks. In fact, C5 must give the first peak around 1000-1100hz but it gives first peak around 520-530hz.

So, my program can not clearly realize between C4 and C5. How can I solve this problem? why does first peak of C5 start from 520-530hz? 

Code: [Select]
clc
clear
 
a = 0; b = 0;

Do1 = 0; Re1 = 0; Mi1 = 0; Fa1 = 0; Sol1 = 0; La1 = 0; Si1 = 0; DoHigh1 = 0;
Do2 = 0; Re2 = 0; Mi2 = 0; Fa2 = 0; Sol2 = 0; La2 = 0; Si2 = 0; DoHigh2 = 0;
Do3 = 0; Re3 = 0; Mi3 = 0; Fa3 = 0; Sol3 = 0; La3 = 0; Si3 = 0; DoHigh3 = 0;
 
while(1)
    Fs=8000;        %Sampling frequency
   
    T=1;         %record seconds
    recObj = audiorecorder(Fs,8,1);
    recordblocking(recObj, 1);           
    s = getaudiodata(recObj);       % Store Data in Double-Precision Array
 
    for u=1:2000    %Remove Intital Samples of Sound Because of Initial Conditions
        s(u)=0;
    end
 
    F=abs(fft(s,Fs));    % Absolute Fourier Transform of Sound
    F=F(1:Fs/2,1);       % Half of FFT
 
    lf=150;              % Lowest Frequencies
    for i=1:lf           % Remove Low Frequencies Because of Noise and Microphone Limits
        F(i)=0;
    end
 
    for i=lf:Fs/2        % Remove Frequencies Witch are Small, Because of Noise
        if F(i)<4
            F(i)=0;
        end;
    end
   
    [a,b]= max(abs(F));
   
    % fiding peak values of sound and writing
    [pks, locs] = findpeaks(abs(F))
    [m,n] = size(pks);
   
    if m>0
        for i=1:m         
            % for C
            if locs(i,1) >= 520 && locs(i,1) <= 530 
                Do1 = 1;
            end
            if locs(i,1) >= 1045 && locs(i,1) <= 1055 
                Do2 = 1;
            end
            if locs(i,1) >= 1840 && locs(i,1) <= 1860 
                Do3 = 1;
            end
            % for D
            if locs(i,1) >= 580 && locs(i,1) <= 595 
                Re1 = 1;
            end
            if locs(i,1) >= 1170 && locs(i,1) <= 1190 
                Re2 = 1;
            end
            if locs(i,1) >= 1470 && locs(i,1) <= 1485 
                Re3 = 1;
            end
            % for E
            if locs(i,1) >= 660 && locs(i,1) <= 675 
                Mi1 = 1;
            end
            if locs(i,1) >= 985 && locs(i,1) <= 998 
                Mi2 = 1; Mi3 = 1;
            end
            % for F
            if locs(i,1) >= 680 && locs(i,1) <= 700 
                Fa1 = 1;
            end
            if locs(i,1) >= 1045 && locs(i,1) <= 1059 
                Fa2 = 1;
            end
            if locs(i,1) >= 1745 && locs(i,1) <= 1760 
                Fa3 = 1;
            end
            % for G
            if locs(i,1) >= 785 && locs(i,1) <= 795 
                Sol1 = 1;
            end
            if locs(i,1) >= 1175 && locs(i,1) <= 1195
                Sol2 = 1;
            end
            if locs(i,1) >= 1965 && locs(i,1) <= 1985 
                Sol3 = 1;
            end
            % for A
            if locs(i,1) >= 435 && locs(i,1) <= 445
                La1 = 1;
            end
            if locs(i,1) >= 870 && locs(i,1) <= 890
                La2 = 1;
            end
            if locs(i,1) >= 1750 && locs(i,1) <= 1780 
                La3 = 1;
            end
            % for B
            if locs(i,1) >= 490 && locs(i,1) <= 500
                Si1 = 1;
            end
            if locs(i,1) >= 980 && locs(i,1) <= 1000
                Si2 = 1;
            end
            if locs(i,1) >= 1475 && locs(i,1) <= 1498 
                Si3 = 1;
            end
            % for HighC
            if locs(i,1) >= 515 && locs(i,1) <= 530
                DoHigh1 = 1;
            end
            if locs(i,1) >= 1035 && locs(i,1) <= 1055
                DoHigh2 = 1;
            end
            if locs(i,1) >= 2090 && locs(i,1) <= 2120
                DoHigh3 = 1; Do1=0; Do2=0; Do3=0;
            end
     
           
           
        end
    end

    % Plot the waveform.
    subplot(2,1,1);
    plot(s);
   
    subplot(2,1,2);
    plot(abs(F),'r');
   
    if m>0
        if Do1 == 1 && Do2 == 1 && Do3 == 1
            fprintf('Note is "C", ');
        end
        if Re1 == 1 && Re2 == 1 && Re3 == 1
            fprintf('Note is "D", ');
        end
        if Mi1 == 1 && Mi2 == 1 && Mi3 == 1
            fprintf('Note is "E", ');
        end
        if Fa1 == 1 && Fa2 == 1 && Fa3 == 1
            fprintf('Note is "F", ');
        end
        if Sol1 == 1 && Sol2 == 1 && Sol3 == 1
            fprintf('Note is "G", ');
        end
        if La1 == 1 && La2 == 1 && La3 == 1
            fprintf('Note is "A", ');
        end
        if Si1 == 1 && Si2 == 1 && Si3 == 1
            fprintf('Note is "B", ');
        end
        if DoHigh1 == 1 && DoHigh2 == 1 && DoHigh3 == 1
            fprintf('Note is high "C", ');
        end
       
        fprintf('\n');
    end
   
    Do1 = 0; Re1 = 0; Mi1 = 0; Fa1 = 0; Sol1 = 0; La1 = 0; Si1 = 0; DoHigh1 = 0;
    Do2 = 0; Re2 = 0; Mi2 = 0; Fa2 = 0; Sol2 = 0; La2 = 0; Si2 = 0; DoHigh2 = 0;
    Do3 = 0; Re3 = 0; Mi3 = 0; Fa3 = 0; Sol3 = 0; La3 = 0; Si3 = 0; DoHigh3 = 0;
end
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11725
  • Country: us
    • Personal site
Re: Matlab musical notes dedection
« Reply #1 on: November 09, 2016, 07:38:05 pm »
Simplified approach like this will not work in most cases.

Frequency content of the note changes with time, so you can't really get an accurate reading from the averaged FFT values.

Also, C5 is 523.25 Hz with A4 = 440 Hz tuning.

You may get better results if you remove the first part of the note (attack).
« Last Edit: November 09, 2016, 07:39:41 pm by ataradov »
Alex
 

Offline snarkysparky

  • Frequent Contributor
  • **
  • Posts: 418
  • Country: us
Re: Matlab musical notes dedection
« Reply #2 on: November 09, 2016, 08:07:57 pm »
I noticed you do not window your data before FFT.  Try multiplying a hamming window on the data and it might help the spreading of C4 into C5.
 

Offline KaramelTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: tr
Re: Matlab musical notes dedection
« Reply #3 on: November 09, 2016, 10:21:17 pm »
Simplified approach like this will not work in most cases.

Frequency content of the note changes with time, so you can't really get an accurate reading from the averaged FFT values.

Also, C5 is 523.25 Hz with A4 = 440 Hz tuning.

You may get better results if you remove the first part of the note (attack).

Hi, Can you give more detail? if C5 has a peak where is 523hz so, how can I realize which C note is that?  :-\

I noticed you do not window your data before FFT.  Try multiplying a hamming window on the data and it might help the spreading of C4 into C5.

If I understood clearly to you, I am monitoring my input signal and also, at the same time, I am monitoring absolute output of fft signal? What should I monitor before fft?  :-\
« Last Edit: November 09, 2016, 10:25:16 pm by Karamel »
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11725
  • Country: us
    • Personal site
Re: Matlab musical notes dedection
« Reply #4 on: November 09, 2016, 10:30:16 pm »
Hi, Can you give more detail? if C5 has a peak where is 523hz so, how can I realize which C note is that?  :-\

I don't understand you. Here is a list of all piano keys with corresponding fundamental frequencies https://en.wikipedia.org/wiki/Piano_key_frequencies . This list shows fundamental frequencies, but in a real note spectrum, fundamental frequency does not necessarily has the highest power (or amplitude). So detecting notes by simply looking at their FFT and finding the largest peak is not a universal method.


if I understand clearly to you, I am monitoring my input signal and also, I am monitoring absolute output of fft signal? What should I monitor before fft?  :-\
Read about FFT windows. When you do your 2000 sample removal, you simply zero out samples you don't want. This introduces a sharp transition between the zero part and non-zero part. This transition affects the result of the FFT.

I don't believe this will actually help much, but it will not hurt.


Let's approach it from the other angle - what is your final goal here? There may be an alternative solution.
Alex
 

Offline KaramelTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: tr
Re: Matlab musical notes dedection
« Reply #5 on: November 09, 2016, 11:05:18 pm »
Hi, Can you give more detail? if C5 has a peak where is 523hz so, how can I realize which C note is that?  :-\

I don't understand you. Here is a list of all piano keys with corresponding fundamental frequencies https://en.wikipedia.org/wiki/Piano_key_frequencies . This list shows fundamental frequencies, but in a real note spectrum, fundamental frequency does not necessarily has the highest power (or amplitude). So detecting notes by simply looking at their FFT and finding the largest peak is not a universal method.


if I understand clearly to you, I am monitoring my input signal and also, I am monitoring absolute output of fft signal? What should I monitor before fft?  :-\
Read about FFT windows. When you do your 2000 sample removal, you simply zero out samples you don't want. This introduces a sharp transition between the zero part and non-zero part. This transition affects the result of the FFT.

I don't believe this will actually help much, but it will not hurt.


Let's approach it from the other angle - what is your final goal here? There may be an alternative solution.

Okay. You did not understand me.

Inferentially, you did not examine my codes. They are looking peaks in absolute fft output of input signal. So, if there is some points between my seaching, it says okay. This sound of note is A or B or C whatever.

For example, A note dedection like that.
Code: [Select]
% for A
            if locs(i,1) >= 435 && locs(i,1) <= 445
                La1 = 1;
            end
            if locs(i,1) >= 870 && locs(i,1) <= 890
                La2 = 1;
            end
            if locs(i,1) >= 1750 && locs(i,1) <= 1780
                La3 = 1;
            end

440 first, 880 second and 1760 third harmonics of A4. If there are three points which are approximately in ranges so, program says that it is A. Actually, this program is basic and it works for all other notes. It can be dedecting.

In my frequency searching, C4 has no any harmonic or fundamental frequency output on 261hz. (it looks like wrong but there is no output in this frequency)

This is output of fft of C4:


This is output of fft of C5:


So, as you can see, frequencies are almost same?

I am just working for education. I am reading oppenheim's book(signals and systems) and working a project. This is not commercial.

And my teacher said that program is almost okay but you should solve the C4-C5 problem. I am, therefore, looking for a solving method for this issue.
« Last Edit: November 09, 2016, 11:18:50 pm by Karamel »
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11725
  • Country: us
    • Personal site
Re: Matlab musical notes dedection
« Reply #6 on: November 09, 2016, 11:18:35 pm »
It is pretty clear that your C4 is missing fundamental frequency, but frequencies of harmonics are spaced apart at around 260 Hz (C4 fundamental frequency). Why it is missing- hard to tell from screenshots. It is often less pronounced, but it should be there. You may also want to plot logarithmic graph, it will probably reveal it.


Your best bet for detecting the note is to find 5-10 local maximums in FFT and take the average frequency difference between them. This value is going to be your fundamental frequency regardless of absolute level of those harmonics.
« Last Edit: November 09, 2016, 11:20:35 pm by ataradov »
Alex
 

Offline KaramelTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: tr
Re: Matlab musical notes dedection
« Reply #7 on: November 09, 2016, 11:30:36 pm »
This is the missing point, now, you understood clearly to me.

I am getting microphone sound, it has 8000 sample. I am clearing the first 2000 for inital noises and taking absolute fft finally I am eliminating lower frequency output of fft and eliminating low outputs less than four.(I do them because, otherwise, signal does not show clearly on graph)

I also tried without these codes which are eliminating noises. There is no any peak output around 260hz.

Code: [Select]
Fs=8000;        %Sampling frequency
   
    T=1;         %record seconds
    recObj = audiorecorder(Fs,8,1);
    recordblocking(recObj, 1);           
    s = getaudiodata(recObj);       % Store Data in Double-Precision Array
 
    for u=1:2000    %Remove Intital Samples of Sound Because of Initial Conditions
        s(u)=0;
    end
 
    F=abs(fft(s,Fs));    % Absolute Fourier Transform of Sound
    F=F(1:Fs/2,1);       % Half of FFT
 
    lf=150;              % Lowest Frequencies
    for i=1:lf           % Remove Low Frequencies Because of Noise and Microphone Limits
        F(i)=0;
    end
 
    for i=lf:Fs/2        % Remove Frequencies Witch are Small, Because of Noise
        if F(i)<4
            F(i)=0;
        end;
    end
« Last Edit: November 09, 2016, 11:33:05 pm by Karamel »
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11725
  • Country: us
    • Personal site
Re: Matlab musical notes dedection
« Reply #8 on: November 09, 2016, 11:34:37 pm »
I don't really understand what the problem is. Yes, real recordings can have weird properties. That specific sample your source plays happens to be this way. It is not unusual. You see the same result, because that piano app just plays the same wave file. Take some other recording of the C4 note and you will see that fundamental frequency is present there. It sounds fine because all higher number harmonics are still where they should be.

My proposed algorithm will deal with it nicely.
« Last Edit: November 09, 2016, 11:36:49 pm by ataradov »
Alex
 

Offline KaramelTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: tr
Re: Matlab musical notes dedection
« Reply #9 on: November 14, 2016, 06:03:31 pm »
Hi ataradow,

I solved this problem. Infact, there was no any problem in my program. I tried it with signal generator and I generated 260hz sound then, it realized.

I changed my piano program and new program is okay. This is :bullshit: problem (:)) which is hard to realize where is the problem. Because I always though that, problem must be in my program.

Thank you so much for helping to me  ^-^
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11725
  • Country: us
    • Personal site
Re: Matlab musical notes dedection
« Reply #10 on: November 14, 2016, 06:07:11 pm »
I changed my piano program and new program is okay.
It is not the new program that is OK, it just has a different sample library.

In a real world with a real piano your program will fail randomly the same way as it did with the first program.
Alex
 
The following users thanked this post: Dave3


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf