plotting the recorded sound while recording
6 次查看(过去 30 天)
显示 更早的评论
Hi,
Is it possible to record speech from microphone and plot it continuously?
I tried to use "audiorecorder" but, it plots the results after recording. What I want to do is, for instance I want to record for 5 sec. While recording I want to see what is recorded in every sec. X-axis (time) should be between 0 and 5 at the end of the recording and the whole record must be shown on one plot.
Thanks...
采纳的回答
Geoff Hayes
2014-11-26
编辑:Geoff Hayes
2014-11-26
Huseyin - yes, you can do what you want using the audiorecorder and a timer function that could fire every one second and process/plot the data captured in that last one second. See How to record and analyze audio in real-time for an idea of how to proceed.
See also How to trigger the microphone to record via a GUI pushbutton for an example that provides information.
47 个评论
Geoff Hayes
2014-11-27
Huseyin's answer moved here
Geoff, thanks for the answer but I couldn't figure it out about how to implement that line. I tried something like that, but didnt work
recObj = audiorecorder(5000,16,1);
set(recObj,'TimerPeriod',1,'TimerFcn',{@audioTimer});
recordblocking(recObj, T); %all the parameters are known which are not included in this part of the code
seg = getaudiodata(recObj);
fftMag =abs(fft(seg,nfft));
subplot(121);plot(t,seg);
subplot(122);plot(f,fftMag(1:numUniq));
Geoff Hayes
2014-11-27
Huseyin - perhaps the attached will be more useful as it doesn't rely on a GUI (since you might not have been using one). It is a simple function that you call as
myAudioRecording(Fs,durationSecs,N)
where Fs is the sample rate (Hz), durationSecs is the duration of the recording (seconds), and N is the FFT block size. So you may call the function as
myAudioRecording(5000,5,5000)
The code does the following - it creates some local variables and the recorder as
% add an extra half-second so that we get the full duration in our
% processing
durationSecs = durationSecs + 0.5;
% index of the last sample obtained from our recording
lastSampleIdx = 0;
% start time of the recording
atTimSecs = 0;
% create the audio recorder
recorder = audiorecorder(Fs,8,1);
% assign a timer function to the recorder
set(recorder,'TimerPeriod',1,'TimerFcn',@audioTimerCallback);
We are going to nest our callback within the main function, myAudioRecording, so that the callback has access to the above local variables. The audio recorder is created with the sample rate Fs and a timer callback is assigned to it so that it fires every one second.
We then create the figure with two subplots, and start the recording for durationSecs
% create a figure with two subplots
hFig = figure;
hAxes1 = subplot(2,1,1);
hAxes2 = subplot(2,1,2);
% create the graphics handles to the data that will be plotted on each
% axes
hPlot1 = plot(hAxes1,NaN,NaN);
hPlot2 = plot(hAxes2,NaN,NaN);
drawnow;
% start the recording
record(recorder,durationSecs);
We will be using the handles to the plot graphics objects, hPlot1 and hPlot2, to update the plot data whenever we get a new second of data (rather than repotting the data).
The callback looks like
% define the timer callback
function audioTimerCallback(hObject,eventdata)
% get the sample data
samples = getaudiodata(hObject);
% skip if not enough data
if length(samples)<lastSampleIdx+1+Fs
return;
end
% extract the samples that we have not performed an FFT on
X = samples(lastSampleIdx+1:lastSampleIdx+Fs);
% compute the FFT
Y = fft(X,N);
% plot the data
t = linspace(0,1-1/Fs,Fs) + atTimSecs;
set(hPlot1,'XData',t,'YData',X);
f = 0:Fs/N:(Fs/N)*(N-1);
set(hPlot2,'XData',f,'YData',abs(Y));
% increment the last sample index
lastSampleIdx = lastSampleIdx + Fs;
% increment the time in seconds "counter"
atTimSecs = atTimSecs + 1;
end
Every one second, it grabs all of the samples collected so far, and checks to make sure that we have a new second's worth of data. If we do, then we extract those new samples and compute the FFT, and then plots the data on the time domain data and the frequency domain data on the two subplots. On the next call to this function, the data is replaced with the next one second's worth of data. This isn't quite what you want, as you want to display all 5 seconds worth of data, so you can modify the code as you see fit.
The final line is
waitfor(hFig);
which prevents the function from exiting until the user has deleted/closed the figure that is displaying the two plots.
Geoff Hayes
2018-4-27
Hi I am using this code. I connect a microphone using a special card to my pc and I am doing signal processing on that like FFT and some filtering issues.
I want to use 2 channel at the same time with two separate figures. but when I change the number of channel from 1 to 2 it does not work.
That would be great if you could help me to be able to detect two channels.
Geoff Hayes
2018-4-27
Hoda - please don't use the answer "field" to ask questions.
As for your it does not work, please clarify what you mean by this? Are you observing any errors? If so, what are they?
hoda kazemzadeh
2018-5-11
Hi
Is it possible to store audio data before firing in a matrix? (samples which are collected every second)
hoda kazemzadeh
2018-5-11
My first problem is that according to your code, I want to store "samples" or "X" and "Y (fft of X)"-which are collected every second- in a matrix and in an excel file as well.I add this line:
samples = getaudiodata(hObject); Smatrix(:,atTimSecs+1)=samples; % all samples stored in this matrix
But all the values of the matrix are zero except last column.
My second problem is that I can not arrive to record audio data from audio card with 2 channel. I use recorder = audiorecorder(Fs,24,2) in my code and I connect two microphones through an audio card to my PC but in the second channel I see only the noise.
I would be grateful if you help me to fix them.
hoda kazemzadeh
2018-5-28
Geoff- I mean this code: myAudioRecording.m
As I know octave does not support handles, I can not get the signal in real time which updates every one second (exactly the same as in matlab).
Geoff Hayes
2018-5-28
hoda - unfortunately, I don't use octave so can't comment on how best to extract the samples...
hoda kazemzadeh
2018-5-28
Geoff- how can I creat a demo to be able to record and demonstrate the plot results via pushing start button and then stop recording?
Geoff Hayes
2018-5-28
hoda - in Octave or MATLAB? If the latter, then you would call the myAudioRecording function from your start button callback.
hoda kazemzadeh
2018-5-29
In Matlab. for the start button I call the main function, what should I do for stop button in stop-callback part?
Geoff Hayes
2018-5-29
Well you are going to have to call stop on the audio recorder. Unfortunately, I don't know how you have setup your code...but you will need to make the audio recorder available to both the stop and start callbacks (perhaps nest your callbacks in a main function?).
hoda kazemzadeh
2018-5-30
In fact I call myAudioRecording.m in the start callback. The function exits when the figure is closed. How can I manage it with stop button in GUI?
Geoff Hayes
2018-5-30
编辑:Geoff Hayes
2018-5-30
Well you are going to have to change that (calling myAudioRecording as is) from your start callback. The audio recorder object will have to be "shared" or "known" for the start and stop callbacks.
How have you created your GUI? Using GUIDE, App Designer, or programmatically?
hoda kazemzadeh
2018-5-30
编辑:Walter Roberson
2018-5-30
Thank you for your answer. I am using GUIDE. My code is as following: the start button does not work, if it works I can edit the part for stop button.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function demo6_OpeningFcn(hObject, ~, handles, varargin)
handles.output = hObject;
handles.Fs=48000;
handles.recorder = audiorecorder(handles.Fs,24,1);
set(handles.recorder,'TimerPeriod',1,'TimerFcn',{@audioTimer,hObject});
guidata(hObject, handles);
function varargout = demo6_OutputFcn(hObject, ~, handles)
varargout{1} = handles.output;
function pushbutton1_Callback(hObject, ~, handles)
record(handles.recorder)
handles.lastSampleIdx = 0;
handles.atTimSecs = 0;
function audioTimer(hObject,varargin)
hFigure = varargin{2};
handles = guidata(hFigure);
samples = getaudiodata(hObject);
X = samples(handles.lastSampleIdx+1:handles.lastSampleIdx+(handles.Fs),1);
t1 = linspace(0,1-1/handles.Fs,handles.Fs) + handles.atTimSecs;
set(hPlot1,'XData',t1,'YData',X);
title(hAxes1,'Audio Signal');
handles.lastSampleIdx = handles.lastSampleIdx + handles.Fs;
handles.atTimSecs = handles.atTimSecs + 1;
% --- Executes on button press in stopbutton.
function stopbutton_Callback(hObject, eventdata, handles)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Geoff Hayes
2018-5-30
Hoda - please clarify what you mean by it does not work. Are there any errors? If so, what are they?
The start button code is in the
function pushbutton1_Callback(hObject, ~, handles)
Is the name of your start button pushbutton1?
hoda kazemzadeh
2018-5-30
the name of start button is pushbutton1. yes there is error: Error occurred while executing the listener callback for event Executing defined for class internal.IntervalTimer: Error using demo6>audioTimer (line 102) Reference to non-existent field 'lastSampleIdx'.
Geoff Hayes
2018-5-30
right..this makes sense since in your start button callback
function pushbutton1_Callback(hObject, ~, handles)
record(handles.recorder)
handles.lastSampleIdx = 0;
handles.atTimSecs = 0;
you are updating the handles structure but not saving the changes to the structure... You need to call guidata to save the updated structure so that other callbacks can make use of the updated structure.
function pushbutton1_Callback(hObject, ~, handles)
handles.lastSampleIdx = 0;
handles.atTimSecs = 0;
guidata(hObject, handles);
record(handles.recorder)
hoda kazemzadeh
2018-5-31
编辑:hoda kazemzadeh
2018-5-31
Geoff- Thank you very much. last point is plotting the results. In which function should I put these lines?
hFigure = figure;
hAxes1 = subplot(3,1,1);
hPlot1 = plot(hAxes1,NaN,NaN,'Color','b');
if I write them in audiotimer function, demonstration is not in real time, that means when I close the figure, another figure appears and so on. But they are not updated every seond in the same figure as it should. And if I write out of this function I get this error:
Undefined hPlot
Thank you in advance for your kindly answers.
Geoff Hayes
2018-5-31
k. The code you posted
hFigure = figure;
hAxes1 = subplot(3,1,1);
hPlot1 = plot(hAxes1,NaN,NaN,'Color','b');
would only be valid if you were running the original script outside of a GUI. In your case, you probably want to add an axes to your GUI and plot your signal there.
hoda kazemzadeh
2018-5-31
You are right. In want to plot my signal (and two other filters as fft,thirdoctave) at the same figure of demo ie at the background of demo figure in which there are stopbutton and startbutton, how I can manage three handles.axes for three different plot?
Geoff Hayes
2018-5-31
Well the handle to each of the three axes should be in the handles structure...so in the audio recorder callback, you would update each of those three axes/subplots.
hoda kazemzadeh
2018-5-31
Sorry.. but still not working. I add axes(handles.axes1); in start_callback function just after record.
handles.lastSampleIdx = 0;
handles.atTimSecs = 0;
guidata(hObject, handles);
record(handles.recorder)
handles.figure1=figure1;
axes(handles.axes1);
axes(handles.axes2);
axes(handles.axes3);
second issue is to plot in the same figure of demo.
Geoff Hayes
2018-5-31
but what do you mean by still not working? You don't want to do the axes(handles.axes1) in the start_callback but when you are ready to plot data to that axes...which should be in your audio recorder timer callback, audioTimer. So in this function, once you have the new data and done your FFT (or whatever) you would do
axes(handles.axes1);
% plot data to axes 1
axes(handles.axes2);
% plot data to axes 2
axes(handles.axes3);
% plot data to axes 3
Alternatively, you don't have to do the above and just specify in your call to plot which axes you want to put the data in. If you've done something similar to
hAxes1 = subplot(3,1,1);
hPlot1 = plot(hAxes1,NaN,NaN,'Color','b');
then you just need to update the x- and y-data of hPlot1 and not worry about setting "focus" to the axes.
You may need to show more of your code because there is too much guessing (of what you have written) to be able to provide more help.
hoda kazemzadeh
2018-5-31
I upload my code.. that would be easier. In this code I didnt take account "handles.axes".(I would like to include it in the code)
when I run this code, the plot appears at the background of demo.figure as desired but as the same time there is an error: Undefined function or variable 'figure1'.
many thanks in advance..
Geoff Hayes
2018-5-31
I don't understand why you have
handles.lastSampleIdx = 0;
handles.atTimSecs = 0;
guidata(hObject, handles);
record(handles.recorder)
handles.figure1=figure1;
in the demo_OutputFcn... I would consider removing this code.
Geoff Hayes
2018-5-31
And in
function audioTimer(hObject,varargin)
F = [ 50 63 80,100 125 160, 200 250 315, 400 500 630, 800 1000 1250, ...
1600 2000 2500, 3150 4000 5000 6300 8000 10000,125000 16000 20000 ];
handles.figure1 = varargin{2};
Why are you doing this assignment handles.figure1 = varargin{2};? varargin{2} should be the handle to the figure/GUI and so you would do
hGui = varargin{2};
handles = guidata(hGui);
hoda kazemzadeh
2018-6-1
编辑:hoda kazemzadeh
2018-6-1
In fact I should have nested those lines in the openning function since I dont want to have start button, what I want is as soon as I run the code the plot displays. The following code is what I had at the beginning but it is not what I want because another figure appears when I run but I want to have the demonstartion at the demo.figure in which there are the buttons.
function demo_OpeningFcn(hObject, ~, handles, varargin)
handles.output = hObject;
handles.FS=FS;
handles.recorder = audiorecorder(handles.FS,24,1);
set(handles.recorder,'TimerPeriod',1,'TimerFcn',{@audioTimer,hObject});
guidata(hObject, handles);
handles.lastSampleIdx = 0;
handles.atTimSecs = 0;
guidata(hObject, handles);
record(handles.recorder)
function varargout = demo_OutputFcn(hObject, ~, handles)
varargout{1} = handles.output;
That is what I can not handle..
Geoff Hayes
2018-6-1
why are you calling record(handles.recorder) in the OpeningFcn? Shouldn't you be calling this from the start button callback?
I think that you need to attach your code (m file and fig file).
hoda kazemzadeh
2018-6-1
I dont have any start button because I want to display the results (plots) as soon as I RUN the code and not using pusshbutton to start recording. I can add startbutton later, this is not my point. For the moment my issue is that, I want to display the plots in the background of demo figure (where I have store and stop buttons)and not on another figure.
I attach the code.
Geoff Hayes
2018-6-1
hoda - you need to add three axes objects to your GUI and then plot the data against those axes. For example, if the three axes are named axes1, axes2, and axes3, then your audioTimer callback will use these axes to plot the data on
%%Plot
t1 = linspace(0,1-1/handles.FS,handles.FS) + handles.atTimSecs;
plot(handles.axes1, t1,handles.X)
title('Audio Signal');
freq =linspace(0,handles.FS,4096);
maxFreq = 4096/8;
plot(handles.axes2, freq(1:maxFreq),abs(FFT(1:maxFreq)),'g');
bar(handles.axes3, data,0.6,'r');
set(handles.axes3,'XTick',[2:3:27,37:40]);
set(handles.axes3,'XTickLabel',{F(2:3:length(F)) ,'leqA','leqC','mC','mZ'});
xlabel(handles.axes3, 'Frequency band [Hz]'); ylabel('Power [dB]');
title(handles.axes3, '1/3 octave band, LeqA, LeqC, PeakC, PeakX');
hoda kazemzadeh
2018-6-1
I add these lines in timer callback:
axes(handles.axes1);
axes(handles.axes2);
axes(handles.axes3);
what else I have to do? I get this error in plot part :
Reference to non-existent field 'axes1
Geoff Hayes
2018-6-1
hoda - you don't need these lines
axes(handles.axes1);
axes(handles.axes2);
axes(handles.axes3);
As for the error message, have you added the three axes to your GUI? And by that I mean, have you used the GUIDE GUI editor to update your demo.fig file with the three axes named axes1, axes2, and axes3?
hoda kazemzadeh
2018-6-1
How I should add the axes to GUI? I use guide GUI editor. I am lost now, I posted my code already. I dont know exactly what I have to do.
Geoff Hayes
2018-6-1
See https://www.mathworks.com/help/matlab/creating_guis/about-the-simple-guide-gui-example.html for details on how to add an axes. I had assumed since you added the buttons then it would be clear on how to add an axes....
hoda kazemzadeh
2018-6-3
I got it. it was my first time that I was using creating GUI. Thanks a lot.
hoda kazemzadeh
2018-6-5
Geoff- I want to store FFT samples in a csv file when I push store button and stop storing when I push StopStore button. (for axample I push store button in 4th second of recording and I push Stop button in 10th second, I want to save fft for 6 seconds (4s-10s) in csv file).
Could you please help me how to do that. I tried some solutions but not succeed.
Geoff Hayes
2018-6-5
hoda - please post a new question rather than commenting in this question (which has nothing to do with your new request).
hoda kazemzadeh
2018-6-13
Geoff- I have an important issue, I posted new question but I ask you again here because my code is always this one that we disscused in this post. I want to continue recording for long time (one hour for example), but the data accumulates in samples and after a while I need to remove data from memory otherwise Matlab would end because of memory problem. How is it possible to flush data of samples sometimes?
samples=getaudiodata(hObject)
Walter Roberson
2018-6-13
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Graphics Performance 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!发生错误
由于页面发生更改,无法完成操作。请重新加载页面以查看其更新后的状态。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
- América Latina (Español)
- Canada (English)
- United States (English)
欧洲
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
亚太
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)