Author Topic: Mathlab realtime microphone input  (Read 3899 times)

0 Members and 1 Guest are viewing this topic.

Offline KaramelTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: tr
Mathlab realtime microphone input
« on: October 10, 2016, 07:56:04 pm »
Hi everyone,

I have now a question for you. As you know, I am fresh man at Matlab coding so, I am training. I have plotted graphics, created sinus signals and could take fft of some signals but I did not get datum from microphone in real time. (I can record and play but it is not like what I want)

I want to take real time microphone datum and want to show these datum on graph.

How can I do that?

Best Regards,
Karamel  ^-^
 

Offline KaramelTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: tr
Re: Mathlab realtime microphone input
« Reply #1 on: October 11, 2016, 09:02:40 am »
Nothing?    :-//
 

Online nfmax

  • Super Contributor
  • ***
  • Posts: 1560
  • Country: gb
Re: Mathlab realtime microphone input
« Reply #2 on: October 11, 2016, 09:40:12 am »
You need to create an
Code: [Select]
audiorecorder object, and use its
Code: [Select]
record or
Code: [Select]
recordblocking methods inside a loop. This should let you do rougly what you want, I think.
 

Offline KaramelTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: tr
Re: Mathlab realtime microphone input
« Reply #3 on: October 11, 2016, 02:44:11 pm »
Hi thanks for replying my post. Can you give me some code which are working. I had already searched them yesterday but i did not get anything which what I want.

Actually, I am learning matlab how it works. It looks like c programming but there is a few differences so, I did not really understand working of audiorecorder.

I want that, for example, every 100msn, I want record mic and show it on graph. 

p.s:

I have tried these codes. They work, sampling every one second but, program can not close. I guess, it is not good idea.

Code: [Select]
while(1)
    % Record your voice for 5 seconds.
    recObj = audiorecorder;
    disp('Start speaking.')
    recordblocking(recObj, 1);
    disp('End of Recording.');

    % Store data in double-precision array.
    myRecording = getaudiodata(recObj);

    % Plot the waveform.
    plot(myRecording);
end
« Last Edit: October 11, 2016, 03:00:41 pm by Karamel »
 

Offline AndreasF

  • Frequent Contributor
  • **
  • Posts: 251
  • Country: gb
    • mind-dump.net
Re: Mathlab realtime microphone input
« Reply #4 on: October 12, 2016, 09:38:17 am »
Matlab probably isn't particularly well suited for this, but may work.  It's not really like C other than that it has many of the usual program flow statements (if, else, while, for etc.), but so do almost all languages.

In your code, one thing you should definitely change is to take out the creation of the recObj. There shouldn't be a need to recreate the object each time. It might still work though.

One way to periodically do something with the recorded audio data (e.g. display it) would be to use the built-in timer callback-function property. That way you could start the recording in a non-blocking way, i.e. keep doing other things while it's "recording". However, since you are new to Matlab, you probably don't know what that means. In a way the function is a bit like an interrupt service routine, and the callback-function property is similar to a function pointer.

Create a function and make sure it's in your Matlab path:
Code: [Select]
function audiorecPlot(arObj, ev)

sr = get(arObj,'SampleRate');
tp = get(arObj,'TimerPeriod');
nSamples = get(arObj,'TotalSamples');

allAudio = getaudiodata(arObj);

startIndex = max(0,floor(nSamples-sr*tp));

plot(allAudio(startIndex:nSamples));

end


Then you can do the rest from the Matlab command line if you want:

Code: [Select]
recObj=audiorecorder;     %creates the recorder object

set(recObj,'TimerFcn',@audiorecPlot);   %sets the timer callback function
set(recObj,'TimerPeriod',0.1)        %sets the timer period to 0.1 sec

record(recObj);   %start the recording - the plot should appear and update every 100ms

stop(recObj);  %stop when you want to

I haven't tested this extensively, so it probably needs to be optimised a bit. E.g. you probably want to set the y-axis scaling to a fixed range.
my random ramblings mind-dump.net
 

Online nfmax

  • Super Contributor
  • ***
  • Posts: 1560
  • Country: gb
Re: Mathlab realtime microphone input
« Reply #5 on: October 12, 2016, 09:55:10 am »
Have a search around on the Matlab file exchange: http://uk.mathworks.com/matlabcentral/fileexchange/?utf8=%E2%9C%93&term=audio+input. This one: http://uk.mathworks.com/matlabcentral/fileexchange/46950-liverecording looks like it might be helpful, though I didn't check to see how much it depends on the signal processing toolbox (do you have this toolbox?)
 

Offline KaramelTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: tr
Re: Mathlab realtime microphone input
« Reply #6 on: October 14, 2016, 01:37:23 pm »
Hi

I can now get periodic sample with this approaching from microphone but there is another problem here, fourier output is not correct, actually, it shifted a little bit right side of frequency domain.

I use perfect piano to make A4 sound which must be 440hz in spectrum but I am getting result maximum peak in 457hz and also, other notes are shifted. Why am I getting results like these?  :-\


Code: [Select]
clear all
a=0
b=0

while(1)

    recObj = audiorecorder;
    recordblocking(recObj, 0.05);

    myRecording = getaudiodata(recObj);

    nfft = length(myRecording);
    nfft2 = 2^nextpow2(nfft);
    ff = fft(myRecording, nfft2);
   
    a=0; b=0;
   
    for i = 1:512
       if ff(i,1) >= a
           a = ff(i,1);
           b=i;
       end
    end
   
    fprintf('Frequency: %i and Max value: %i\n', b, a);
   
    % Plot the waveform.
    subplot(2,1,1);
    plot(myRecording);
   
    subplot(2,1,2);
    plot(abs(ff),'r');
   
    if ff(457,1) >= 2
        disp('Note is "A"')
    end
   
end

P.s: I can realize maximum values with variable of a and b. When I press A4 note from my phone, fourier transform gives max. value in 457hz :/
« Last Edit: October 14, 2016, 02:27:53 pm by Karamel »
 

Offline AndreasF

  • Frequent Contributor
  • **
  • Posts: 251
  • Country: gb
    • mind-dump.net
Re: Mathlab realtime microphone input
« Reply #7 on: October 14, 2016, 02:32:34 pm »
Your fft frequency bins do not have a 1 Hz width/resolution. In your case they will be 20Hz. You would need a full second of recording to get a 1 Hz resolution.

http://electronics.stackexchange.com/questions/12407/what-is-the-relation-between-fft-length-and-frequency-resolution

Also relevant for you might be this:
http://math.stackexchange.com/questions/9416/extracting-exact-frequencies-from-fft-output


And, by the way
Code: [Select]
    a=0; b=0;
   
    for i = 1:512
       if ff(i,1) >= a
           a = ff(i,1);
           b=i;
       end
    end

can simply be written as:

Code: [Select]
[a,b]= max(abs(ff));
my random ramblings mind-dump.net
 

Offline KaramelTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: tr
Re: Mathlab realtime microphone input
« Reply #8 on: October 14, 2016, 02:53:32 pm »
I understood it so, is there any way to make sampling 50msn and getting correct result?

1 second sampling is too much for me  :-\
 

Offline KaramelTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: tr
Re: Mathlab realtime microphone input
« Reply #9 on: October 21, 2016, 01:29:13 pm »
Hi everyone,

I am able to recognize notes with these codes, at below, now. So, at the moment, I want to improve my codes.

Briefly, quick issues are these,

- I have treshold values which determines notes and them harmonics. So, fourier output depends on micropone input magnetude. I am meaning that, If microphone volume is higher, fourier transform result is higher or vice versa. If sound generator, piano-guitar etc., neraly the microphone. There is no any problem but, if source is a little bit far of microphone, sometimes, it can not dedect notes. How can I solve this problem?

- My codes can dedect some notes between C4-C5 (center notes at piano) there is no any problem for C5, B4, A4, G4 etc. but, C4 and especially D4 has more harmonics which nearly other harmonics of notes. Thus, sometimes, when I try to dedect D4, program can be dedecting D4, and for example, G4 etc. So, there is a little bit confusing problem for my codes. How can I improve it?

- Last question is that I want to dedect musical cords which are located between C4-C5. For example "Dm or Cm" In this case, my question looks like my second question. If there is two, three or more than three notes, program is absuletely confusing. Because, harmonics of notes and actual frequencies are mixing and locating nearly each other. I have no idea how can I solve it because, I must firstly decide that is it harmonic? or actual note?  :scared:

Code: [Select]
clc
clear
 
a = 0;
b = 0;
 
T1 = 6;  % our tresholds
T2 = 5;
T3 = 4;
 
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));   
    fprintf('Frequency: %i and Max value: %i\n', b, a);
   
    [val H1]=max(F);     % Find Max
   
    % Plot the waveform.
    subplot(2,1,1);
    plot(s);
   
    subplot(2,1,2);
    plot(abs(F),'r');
   
   
    if F(261*2,1) >= T1 && F(261*3,1) >= T2 && F(261*4,1) >= T3
        fprintf('Note is "C", ')
    end
    if F(294*2,1) >= T1 && F(294*3,1) >= T2 && F(294*4,1) >= T3
        fprintf('Note is "D", ')
    end
    if F(329*2,1) >= T1 && F(329*3,1) >= T2 && F(329*4,1) >= T3
        fprintf('Note is "E", ')
    end
    if F(349*2,1) >= T1 && F(349*3,1) >= T2 && F(349*4,1) >= T3
        fprintf('Note is "F", ')
    end
    if F(392*2,1) >= T1 && F(392*3,1) >= T2 && F(392*4,1) >= T3
        fprintf('Note is "G", ')
    end
    if F(440*2,1) >= T1 && F(440*3,1) >= T2 && F(440*4,1) >= T3
        fprintf('Note is "A", ')
    end
    if F(494*2,1) >= T1 && F(494*3,1) >= T2 && F(494*4,1) >= T3
        fprintf('Note is "B", ')
    end
    if F(523*2,1) >= T1 && F(523*3,1) >= T2 && F(523*4,1) >= T3
        fprintf('Note is high "C", ')
    end
       
    fprintf('\n');
end
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf