i am trying to make a spectrogram in matlab, here is my code:
% Record your voice for 100 seconds.
recObj = audiorecorder;
disp(\'Start speaking.\')
recordb
The most obvious thing to do is place your code in a loop to keep updating the figure. But be aware that Matlab is not really designed for this sort of task, so I don't know how much success you'll have. Have you tried Googling for free software which does this for you? I'd be surprised if there was nothing out there which didn't do this already.
Here is one possible implementation. The main problem was that you forget to call DRAWNOW at the end of each loop:
Fs = 8000; %# sampling frequency in Hz
T = 1; %# length of one interval signal in sec
t = 0:1/Fs:T-1/Fs; %# time vector
nfft = 2^nextpow2(Fs); %# n-point DFT
numUniq = ceil((nfft+1)/2); %# half point
f = (0:numUniq-1)'*Fs/nfft; %'# frequency vector (one sided)
%# prepare plots
figure
hAx(1) = subplot(211);
hLine(1) = line('XData',t, 'YData',nan(size(t)), 'Color','b', 'Parent',hAx(1));
xlabel('Time (s)'), ylabel('Amplitude')
hAx(2) = subplot(212);
hLine(2) = line('XData',f, 'YData',nan(size(f)), 'Color','b', 'Parent',hAx(2));
xlabel('Frequency (Hz)'), ylabel('Magnitude (dB)')
set(hAx, 'Box','on', 'XGrid','on', 'YGrid','on')
%#specgram(sig, nfft, Fs);
%# prepare audio recording
recObj = audiorecorder(Fs,8,1);
%# Record for 10 intervals of 1sec each
disp('Start speaking...')
for i=1:10
recordblocking(recObj, T);
%# get data and compute FFT
sig = getaudiodata(recObj);
fftMag = 20*log10( abs(fft(sig,nfft)) );
%# update plots
set(hLine(1), 'YData',sig)
set(hLine(2), 'YData',fftMag(1:numUniq))
title(hAx(1), num2str(i,'Interval = %d'))
drawnow %# force MATLAB to flush any queued displays
end
disp('Done.')
I simply display the frequency components in each iteration. You should be able to modify that to show the spectrogram if you want...
MATLAB is intrinsically single-threaded. Only one thing can happen at a time. This makes real time tasks somewhat difficult. As you noted, recordblocking
does not return control to your script until those 100 seconds have elapsed. The key is in the word blocking.
The way around this is with callbacks and non-blocking functions. The audiorecorder object has a few methods and properties that enable this kind of behavior.
The audiorecorder properties:
- StartFcn
: Set a function that will execute upon starting an asynchronous recording
- StopFcn
: The function to be executed upon stopping a recording
- TimerFcn
: The function to be executed every TimerPeriod
seconds during a recording.
Then the record method will start the recording and process in the background, calling the above functions as directed.
By regularly updating your data in the callback function, you may update your plot. Unfortunately, this is similarly not trivial to do in an efficient manner that allows for live updates. But this should get you started.