Mathlab realtime microphone input - Page 1
Forum section: electronics / beginners

author: Karamel
author_rank: Regular Contributor
timestamp: October 10, 2016, 07:56:04 pm
content: 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

author: Karamel
author_rank: Regular Contributor
timestamp: October 11, 2016, 09:02:40 am
content: Nothing?

author: nfmax
author_rank: Super Contributor
timestamp: October 11, 2016, 09:40:12 am
content: You need to create anCode:audiorecorderobject, and use itsCode:recordorCode:recordblockingmethods inside a loop. This should let you do rougly what you want, I think.

author: Karamel
author_rank: Regular Contributor
timestamp: October 11, 2016, 02:44:11 pm
content: 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: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

author: AndreasF
author_rank: Frequent Contributor
timestamp: October 12, 2016, 09:38:17 am
content: 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: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));endThen you can do the rest from the Matlab command line if you want:Code:recObj=audiorecorder; %creates the recorder objectset(recObj,'TimerFcn',@audiorecPlot); %sets the timer callback functionset(recObj,'TimerPeriod',0.1) %sets the timer period to 0.1 secrecord(recObj); %start the recording - the plot should appear and update every 100msstop(recObj); %stop when you want toI 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.

author: nfmax
author_rank: Super Contributor
timestamp: October 12, 2016, 09:55:10 am
content: 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-liverecordinglooks 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?)

author: Karamel
author_rank: Regular Contributor
timestamp: October 14, 2016, 01:37:23 pm
content: HiI 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:clear alla=0b=0while(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:512if ff(i,1) >= aa = ff(i,1);b=i;endendfprintf('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) >= 2disp('Note is "A"')endendP.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 :/

author: AndreasF
author_rank: Frequent Contributor
timestamp: October 14, 2016, 02:32:34 pm
content: 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-resolutionAlso relevant for you might be this:http://math.stackexchange.com/questions/9416/extracting-exact-frequencies-from-fft-outputAnd, by the wayCode:a=0; b=0;for i = 1:512if ff(i,1) >= aa = ff(i,1);b=i;endendcan simply be written as:Code:[a,b]= max(abs(ff));

author: Karamel
author_rank: Regular Contributor
timestamp: October 14, 2016, 02:53:32 pm
content: I understood it so, is there any way to make sampling 50msn and getting correct result?1 second sampling is too much for me

author: Karamel
author_rank: Regular Contributor
timestamp: October 21, 2016, 01:29:13 pm
content: 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?Code:clccleara = 0;b = 0;T1 = 6; % our tresholdsT2 = 5;T3 = 4;while(1)Fs=8000; %Sampling frequencyT=1; %record secondsrecObj = audiorecorder(Fs,8,1);recordblocking(recObj, 1);s = getaudiodata(recObj); % Store Data in Double-Precision Arrayfor u=1:2000 %Remove Intital Samples of Sound Because of Initial Conditionss(u)=0;endF=abs(fft(s,Fs)); % Absolute Fourier Transform of SoundF=F(1:Fs/2,1); % Half of FFTlf=150; % Lowest Frequenciesfor i=1:lf % Remove Low Frequencies Because of Noise and Microphone LimitsF(i)=0;endfor i=lf:Fs/2 % Remove Frequencies Witch are Small, Because of Noiseif F(i)<4F(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) >= T3fprintf('Note is "C", ')endif F(294*2,1) >= T1 && F(294*3,1) >= T2 && F(294*4,1) >= T3fprintf('Note is "D", ')endif F(329*2,1) >= T1 && F(329*3,1) >= T2 && F(329*4,1) >= T3fprintf('Note is "E", ')endif F(349*2,1) >= T1 && F(349*3,1) >= T2 && F(349*4,1) >= T3fprintf('Note is "F", ')endif F(392*2,1) >= T1 && F(392*3,1) >= T2 && F(392*4,1) >= T3fprintf('Note is "G", ')endif F(440*2,1) >= T1 && F(440*3,1) >= T2 && F(440*4,1) >= T3fprintf('Note is "A", ')endif F(494*2,1) >= T1 && F(494*3,1) >= T2 && F(494*4,1) >= T3fprintf('Note is "B", ')endif F(523*2,1) >= T1 && F(523*3,1) >= T2 && F(523*4,1) >= T3fprintf('Note is high "C", ')endfprintf('\n');end