并行计算和记录matlab

时间:2015-03-06 13:07:56

标签: matlab audio fft audio-recording

您好我想计算输入的实时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循环时,我不会收到此错误。最后一个错误来自于第一次迭代缺乏信息。所以我得到一个同步循环?还是我难以实现...... 感谢

1 个答案:

答案 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.')