您好我想计算输入的实时FFT图。使用以下代码我创建一个记录和计算。关键是计算需要花费很多时间才能获得更好的情节更新。
Fs = 44100; % sampling frequency in Hz
T = 1/5; % length of one interval signal in sec
t = 0:1/Fs:T-1/Fs; % time vector
nfft = 2^nextpow2(Fs); % n-point DFT
f = (0:nfft/2)'*Fs/nfft; % Frequency vector
%# prepare plots
figure
hrec(1) = subplot(211);
tplot(1) = plot(t, nan(size(t)), 'Color','b', 'Parent',hrec(1));
xlabel('Time [s]'), ylabel('Amplitude')
hrec(2) = subplot(212);
spec(2) = semilogx(f,nan(size(f)),'Color','b', 'Parent',hrec(2));
xlabel('Frequency [Hz]'), ylabel('Magnitude [dB]'), %XScale('log');
set(hrec, 'Box','on', 'XGrid','on', 'YGrid','on');set(hrec(2), 'XScale','log', 'Xlim',[20 20000]);
% specgram(sig, nfft, Fs);
% prepare audio recording
recObj = audiorecorder(Fs,16,1,0);
% Record
disp('Start Recording...')
for i=1:20
recordblocking(recObj, T);
%# get data and compute FFT
sig = getaudiodata(recObj);
fftMag = 20*log10( abs(fft(sig,nfft)) ); fftMag = fftMag(1:ceil((nfft+1)/2));
% update plots
set(tplot(1),'YData',sig);
set(spec(2), 'YData', fftMag);
title(hrec(1), num2str(i,'Interval = %d'))
drawnow % force MATLAB to flush any queued displays
end
disp('Done.')
所以我创建了一个并行计算的计算:
% Record for 10 intervals of 1sec each
disp('Start speaking...')
for i =1:20
parfor ii=1:2
if ii == 1
recordblocking(recObj, T);
elseif ii == 2
%# get data and compute FFT
sig = getaudiodata(recObj);
fftMag = 20*log10( abs(fft(sig,nfft)) ); fftMag = fftMag(1:ceil((nfft+1)/2));recordblocking(recObj, T);
% update plots
set(tplot(1),'YData',sig);
set(spec(2), 'YData', fftMag);
title(hrec(1), num2str(i,'Interval = %d'))
drawnow %# force MATLAB to flush any queued displays
end
end
end
disp('Done.')
我现在得到错误:
使用audiorecorder / getaudiodata出错(第742行)记录器为空。
parallel_function中的错误(第466行) F(基数,限制);
par_plotupdate(第25行)中的错误parfor ii = 1:2
如何解决此问题,因为当我不使用并行for循环时,我不会收到此错误。最后一个错误来自于第一次迭代缺乏信息。所以我得到一个同步循环?还是我难以实现...... 感谢
答案 0 :(得分:0)
这是一个使用异步录制的实现。这种记录音频数据的方式在后台运行,并且只有在没有数据可用时才暂停执行代码。由于几乎100%的cpu时间可用于处理数据,因此可以比实时更快地处理。这就是为什么我没有使用并行计算工具箱来进一步加速这个过程。
Fs = 44100; % sampling frequency in Hz
T = 1/5; % length of one interval signal in sec
t = 0:1/Fs:T-1/Fs; % time vector
nfft = 2^nextpow2(Fs); % n-point DFT
f = (0:nfft/2)'*Fs/nfft; % Frequency vector
%# prepare plots
figure
hrec(1) = subplot(211);
tplot(1) = plot(t, nan(size(t)), 'Color','b', 'Parent',hrec(1));
xlabel('Time [s]'), ylabel('Amplitude')
hrec(2) = subplot(212);
spec(2) = semilogx(f,nan(size(f)),'Color','b', 'Parent',hrec(2));
xlabel('Frequency [Hz]'), ylabel('Magnitude [dB]'), %XScale('log');
set(hrec, 'Box','on', 'XGrid','on', 'YGrid','on');set(hrec(2), 'XScale','log', 'Xlim',[20 20000]);
% specgram(sig, nfft, Fs);
% prepare audio recording
recObj = audiorecorder(Fs,16,1,0);
N=20;
% Record
disp('Start Recording...')
%set up one continuous recording for all N loops. Each loop processes T seconds of data
recObj.record(N*T);
%avoid empty recorder;
pause(.1);
for idx=1:N
%we are continuously recording and this iteration of the loop should process the data from startindex to endindex
startindex=1+(idx-1)*Fs*T;
endindex=(idx)*Fs*T;
audioData=recObj.getaudiodata();
%if not enough data is available, wait.
while size(audioData,1)<endindex
%amount of missing data can be caluclated, wait that time
pause((endindex-size(audioData,1))/Fs);
audioData=recObj.getaudiodata();
end
fprintf('processing index %d to %d\n',startindex,endindex);
%# get data and compute FFT
sig =audioData(startindex:endindex,:);
%If you want to use parallel computing, submit the next line to a worker (http://www.mathworks.com/help/distcomp/createtask.html). Keep in mind that workers can not update your UI, you have to get the results back from the workers.
fftMag = 20*log10( abs(fft(sig,nfft)) ); fftMag = fftMag(1:ceil((nfft+1)/2));
% update plots
set(tplot(1),'YData',sig);
set(spec(2), 'YData', fftMag);
title(hrec(1), num2str(idx,'Interval = %d'))
drawnow % force MATLAB to flush any queued displays
end
disp('Done.')