how to remove the data (output of the function 'getaudiodata') from the memory buffer when I record an audio for long time and plot it at the same time?

I record an audio signal from microphone and I plot it in real time. Simply I have:
rObj=audiorecorder(fs, 24, 2);
recordblocking(rObj)
y=getaudiodata(rObj);
data accumulates in samples so it can not do recording for long time. Is it possible to remove data from the memory sometimes?

Answers (1)

No, it is not.
If you do not need to keep all of the data until the end, and the amount of data is not easily handled, then you should not be using audiorecorder: you should be using the Audio System Toolbox, probably with audioDeviceReader()

23 Comments

I dont have license of this toolbox. there is not another solution?
If you have the DSP toolbox, you can use the equivalent DSP function.
I dont have either. If so,what is the equivalent function in this toolbox? and how the memory is flushed in this case?
If you were to use the Audio System Toolbox or the DSP Toolbox, then you would be reading in a buffer of data at a time, which for your purposes here you would plot and then overwrite with the next buffer-full.
Memory does not accumulate for those unless you specifically save the contents, and if you do specifically save them, then you would know how you are keeping track of it and so would know what you would have to do to release it or reuse it according to your own implementation.
audiorecorder() will release accumulated audio data in one circumstance: that you call stop() on the object and then call resume(). This will clear all the accumulated data, and of course with the stop() it stops recording. There is no method of releasing accumulated audio data while you are still recording.
If you do not have enough easily available memory to store the audio data for the entire maximum time period for which you might need to record, then you should not be using audiorecorder(). As usual, there are temporary copies of the audio data made while it is adding on samples, so really you should not use audiorecorder() if you do not have at least twice as much memory as would be needed for the entire maximum time period for which you might record.
Hello, in this conversation I asked you about flashing the memory of recorded data frequently but you told me is not possible with 'audiorecord' function. Now I have DSP toolbox, could you please help me how to clean the memory after some minutes of recording? The samples are accumulated every second and after 20 minutes of recording there is a delay in real time displaying.
Are you using dsp.AudioRecorder() ? If you are then you receive BufferSize samples each time you step() the object, and you can throw away old samples whenever you want.
You might want to use the File Exchange submission https://www.mathworks.com/matlabcentral/fileexchange/52411-circularbuffer
what i was doing is that : I was using the audiorecorder function and a timer function that could fire every one second and plot the data captured in that last one second. Every one second, it grabs all of the samples collected then, we extract those new samples and plot the data on the time domain. On the next call to this function, the data is replaced with the next one second of data. So the samples collected at the buffer is going more and more at each second (48000×2×8 bytes).
As soon as the code runs, we have access to the audio recorder and the timer function to have access to the plots. The recording is started and that executes a function that reads in stereo data from the board and stores it in a MATLAB two column vector. Then the figures are displayed which correspond to the signal recorded. the samples of data are updated every second using this function:
recorder = audiorecorder(FS,24,2);
set(recorder,'TimerPeriod',1,'TimerFcn',{@audioTimer,hObject});
samples = getaudiodata(hObject);
Thta works perfect but the only problem is the memory. Now how can I replace dsp.audiorecorder with 'audiorecorder' function without loosing the real time recording and displaying?
"Now how can I replace dsp.audiorecorder with 'audiorecorder' function without loosing the real time recording and displaying"
You do not seem to be using dsp.audiorecorder now, so I think maybe you meant to ask about replacing audiorecorder with dsp.audiorecorder?
As long as you are using audiorecorder for extended periods you will have memory problems.
When you use dsp.audiorecorder, you can make your buffer size whatever you need, and after each step() you can update your plots .
Yes you are right, for the moment I use audiorecorder. How can I edit my code to define the buffer size?
Example:
H = dsp.AudioRecorder('BufferSizeSource', 'Property', 'BufferSize', 4800, 'SamplesPerFrame', 1200, 'SampleRate', 48000, 'NumChannels', 2);
while true
frame = step(H);
plot(frame);
drawnow();
end
I use GUI, it seems that it s not that easy to modify the code with this function.
my code is:
handles.recorder=audiorecorder(48000,24,2)
set(handles.recorder,'TimerPeriod',1,'TimerFcn',{@audioTimer,hObject});
record(handles.recorder)
...
function audioTimer(hObject,varargin)
hGui = varargin{2};
% get the handles structure to access the plots/axes
handles = guidata(hGui);
% get the audio samples
handles.samples = getaudiodata(hObject);
%processes
handles.X=....
t=...
plot(handles.axes1,t,handles.X)
% store and stopStore callback functions to store the data as wave file and stop storing.
...
% stop callback to stop the recording and GUI.
Now I dont need to timer function and time period and instead of getaudiodata, I have to replace with step(handles.recorder). but nothing is displayed maybe because audiodevice only be opened once.
Also I have warning: Warning: dsp.AudioRecorder will be removed in a future release. Use audioDeviceReader from Audio System Toolbox instead.
another error is for stop(hanldes.recorder) function which I use as stop button is pressed the recording and the figures have to be stopped.but stop does not work for dsp.audiorecorder, does it?
You do not need to stop a dsp.audiorecorder : just delete the variable if you do not wish to use it.
The most important issue is displaying and updating the samples every second, i was doing that with a timer function as i explained already. but with dsp.audiorecorder i get error from matlab that 'set is undeined for dsp.audiorecorder'.
Make the number of samples per frame the same as the sample frequency, so that each time you step() you get one second's worth of data. No timer is needed: it will wait on the step() until it has that much data before it returns.
That is working alone but not working in matlab GUI when I replaced it with 'audiorecorde'in my code. I attach my code ,that would be great if you let me know how it should be modified. I couldnt succeed.
Your forgot to attach the version in which you made the attempt to convert to the dsp function.
I can not find a way to graph the frames of the signal without the process adding latency, as I record and graphic for longer times the latency is getting worse. In my code, I successively graph each frame using "hold on" while assigning its position on the x axis (for example: first frame in the position of x [1 1000], second frame in the x position of [1001 2000], ..with 'SamplePerFrame' = 1000), so I can show the signal on a graph while it is being recorded. this was the only way I could imagine doing it and it works, but clearly there must be a better process that does not add latency and don't have breaks of discontinuity between each frame in the graph (it also has that problem).
Do not use hold on for this purpose. There are two approaches:
  1. plot() once and record the handle of the graphics object. After that, as new data comes in, set the XData and YData of the graphics object to the set of values that is to be plotted; Or
  2. use animatedline and record the handle of the graphics object. After that, as new data comes in, use addpoints() to add additional data. This will automatically keep track of older data. You can configure the animatedline to hold a particular maximum number of points.
I would remind you that you are wanting to plot one second at a time at 48000 sampling frequency, which is 48000 points, which is undoubtedly far far wider than your display is. You should reconsider plotting every point.
Merc for your answer but, first one is the way that I am doing for the moment, it is not clear for me how to adopt them with the 'dsp.audiorecorder' and step() functions.
ok, that's is my problem, I don't want define previously the number of point that I will plot. I just want to record and show the waveform until the moment I decide to stop the recording as any audio recording program (protools, audacity, etc). This is what I have so far, with the limitation I mentioned.
H=dsp.AudioRecorder('BufferSizeSource','Property','BufferSize',1,'SamplesPerFrame',1000,'SampleRate',48000,'NumChannels',1);
A=animatedline;
S=H.SamplesPerFrame;
m=0;
while true
frame=step(H);
M=[m:(m+(S-1))];
addpoints(A,M,frame)
drawnow()
m=m+S;
end
That BufferSize is too small, should be at least as large as SamplesPerFrame.
You should probably be telling animatedline to limit the number of points it displays.
I am trying to modify my code in GUI. I dont use audiotimer function now. In 'OutputFcn' I write the dsp.audiorecorder and step functions and display the signal. I get this error when it reaches the line of 'step' function :
A given audio device may only be opened once.

Sign in to comment.

Asked:

on 13 Jun 2018

Commented:

on 23 Jul 2018

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!