www.gusucode.com > dsp 案例源码程序 matlab代码 > dsp/DetermineAndDecreaseUnderrunExample.m

    %% Determine and Decrease Underrun
% _Underrun_ refers to output signal silence, which occurs when the audio
% stream loop does not keep pace with the output device. Determine the
% underrun of an audio stream loop, add artificial computational load to
% the audio stream loop, and then modify properties of your
% |audioDeviceWriter| System object(TM) to decrease underrun. Your results
% depend on your computer.

%%
% Create a |dsp.AudioFileReader| System object, and specify the file to
% read. Use the |audioinfo| function to return a structure containing
% information about the audio file.
fileReader = dsp.AudioFileReader('speech_dft.mp3');
fileInfo = audioinfo('speech_dft.mp3');

%%
% Create an |audioDeviceWriter| System object. Use the |SampleRate| of the
% file reader as the |SampleRate| of the device writer. Call |setup| to
% reduce the computational load of initialization in an audio stream loop.
deviceWriter = audioDeviceWriter(...
    'SampleRate',fileReader.SampleRate);
setup(deviceWriter,...
    zeros(fileReader.SamplesPerFrame,fileInfo.NumChannels));

%%
% Run your audio stream loop with input from file and output to device.
% Print the total samples underrun and the underrun in seconds.
totalUnderrun = 0;
while ~isDone(fileReader)
    input = fileReader();
    numUnderrun = deviceWriter(input);
    totalUnderrun = totalUnderrun + numUnderrun;
end
fprintf('Total samples underrun: %d.\n',...
    totalUnderrun);
fprintf('Total seconds underrun: %d.\n',...
    double(totalUnderrun)/double(deviceWriter.SampleRate));

%%
% Release your |dsp.AudioFileReader| and |audioDeviceWriter| System objects
% and set your counter variable to zero.
release(fileReader);
release(deviceWriter);
totalUnderrun = 0;

%%
% Use a pause to mimic an algorithm that takes 0.075 seconds to process.
% The pause causes the audio stream loop to go slower than the device,
% which results in periods of silence in the output audio signal.
while ~isDone(fileReader)
    input = fileReader();
    numUnderrun = deviceWriter(input);
    totalUnderrun = totalUnderrun + numUnderrun;
    pause(0.075)
end
fprintf('Total samples underrun: %d.\n',...
    totalUnderrun);
fprintf('Total seconds underrun: %d.\n',...
    double(totalUnderrun)/double(deviceWriter.SampleRate));

%%
% Release your |audioDeviceReader| and |dsp.AudioFileWriter| and set the
% counter variable to zero.
release(fileReader);
release(deviceWriter);
totalUnderrun = 0;

%%
% Set the frame size of your audio stream loop to 2048. Because the
% |SupportVariableSizeInput| property of your |audioDeviceWriter| System
% object is set to |false|, the buffer size of your audio device is the
% same size as the input frame size. Increasing your device buffer size
% decreases underrun.
fileReader = dsp.AudioFileReader('speech_dft.mp3');
fileReader.SamplesPerFrame = 2048;
fileInfo = audioinfo('speech_dft.mp3');

deviceWriter = audioDeviceWriter(...
    'SampleRate',fileReader.SampleRate);
setup(deviceWriter,...
    zeros(fileReader.SamplesPerFrame,fileInfo.NumChannels));

%%
% Calculate the total underrun.
while ~isDone(fileReader)
    input = fileReader();
    numUnderrun = deviceWriter(input);
    totalUnderrun = totalUnderrun + numUnderrun;
    pause(0.075)
end
fprintf('Total samples underrun: %d.\n',...
    totalUnderrun);
fprintf('Total seconds underrun: %d.\n',...
    double(totalUnderrun)/double(deviceWriter.SampleRate));

%%
% The increased frame size reduces the total underrun of your audio stream
% loop. However, increasing the frame size also increases latency. Other
% approaches to reduce underrun include:
%
% * Increase the buffer size independent of input frame size. To increase
% buffer size independent of input frame size, you must first set
% |SupportVariableSizeInput| to |true|. This approach also increases
% latency.
%
% * Decrease the sample rate. Decreasing the sample rate reduces both
% latency and underrun at the cost of signal resolution.
%
% * Choose an optimal driver and device for your system.