并行计算和记录matlab
Posted
技术标签:
【中文标题】并行计算和记录matlab【英文标题】:Parallel calculation and record matlab 【发布时间】:2015-03-06 13:07:56 【问题描述】:您好,我想计算输入的实时 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 行)Recorder 为空。
parallel_function 中的错误(第 466 行) F(基数, 极限);
par_plotupdate 中的错误(第 25 行)parfor ii=1:2
我该如何解决这个问题,因为当我不使用并行 for 循环时,我没有收到此错误。最后一个错误来自我认为第一次迭代缺乏信息。所以我得到一个同步循环?还是我让它变得困难…… 谢谢
【问题讨论】:
也许您应该使用audiorecorder
切换到非阻塞界面以并行运行记录和更新,而不是使用 parfor。这也可以避免录音中的空白。
我搜索了录制音频并一起播放音频或录制并做其他事情。很多时候我读到录音机应该可以工作。但我无法找到任何地方。 PS 这里的代码块如何工作 recObj = audiorecorder(Fs,16,1,0); % Record disp('开始录制...') record(recObj); for i =1:20 % Get some data... 不知道如何 getaudiodata(recobj) % Proccessing drawnow end disp('done...') 因为我在录制过程中需要来自录制的信息。我怎么得到那个,我得到什么。 PS我如何创建一些代码块
【参考方案1】:
这是一个使用异步录制的实现。这种记录音频数据的方式在后台运行,只有在没有数据可用时才会暂停代码的执行。由于几乎 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.')
【讨论】:
感谢@Daniel,它工作正常!!不是我希望的答案,而是我可以使用的答案!现在找出它为什么起作用! @Jan-Bert:我添加了一些 cmets 和解释,希望现在清楚代码的作用。顺便说一句,如果需要,这个解决方案可以与并行计算工具箱结合使用。以上是关于并行计算和记录matlab的主要内容,如果未能解决你的问题,请参考以下文章
Matlab高级教程_第二篇:Matlab相见恨晚的模块_02_并行运算-2