gusucode.com > audiovideo工具箱matlab源码程序 > audiovideo/@audioplayer/play.m
function play(obj, varargin) %PLAY Plays audio samples in audioplayer object. % % PLAY(OBJ) plays the audio samples from the beginning. % % PLAY(OBJ, START) plays the audio samples from the START sample. % % PLAY(OBJ, [START STOP]) plays the audio samples from the START sample % until the STOP sample. % % Use the PLAYBLOCKING method for synchronous playback. % % Example: Load snippet of Handel's Hallelujah Chorus and play back % only the first three seconds. % % load handel; % p = audioplayer(y, Fs); % play(p, [1 (get(p, 'SampleRate') * 3)]); % % See also AUDIOPLAYER, AUDIODEVINFO, AUDIOPLAYER/GET, % AUDIOPLAYER/SET, AUDIOPLAYER/PLAYBLOCKING. % SM % Copyright 2003-2015 The MathWorks, Inc. import audiovideo.internal.audio.Converter; if obj.hasNoAudioHardware() return; end % If more than two arguments are specified, error is thrown narginchk(1,2); % Return if the player is 'On' if obj.isplaying() return; end startIndex = 1; endIndex = obj.TotalSamples; if ~isempty(varargin) % Check there are at most two arguments in Index vector and they are % numeric if (nargin == 2) && ... (~isnumeric(varargin{1}) || ... (numel(varargin{1}) > 2 ) || ... (isempty(varargin{1}))) error(message('MATLAB:audiovideo:audioplayer:invalidIndex')); end % Second elements of the vector specifies the upper bound of the % sample being played. if size(varargin{1}, 2) == 2 % Syntax used is play(obj, [start stop]) startIndex = varargin{1}(1); endIndex = varargin{1}(2); else % Play from the indexed position to the end of the file. % Syntax used is play(obj, start) startIndex = varargin{1}(1); endIndex = obj.TotalSamples; end if startIndex <= 0 || startIndex >= endIndex || endIndex > obj.TotalSamples warning(message('MATLAB:audiovideo:audioplayer:invalidselection')); startIndex = 1; endIndex = obj.TotalSamples; end end % Any buffered data from previous play session should be cleaned % before sending the new data. obj.Channel.OutputStream.flush(); % The number of samples sent to the audio device must be an exact multiple % of the buffer size. See g1130462 for details. bufferSize = double(Converter.secondsToSamples( obj.DesiredLatency,... obj.SampleRate )); samplesUntilDone = endIndex - startIndex + 1; extraSamples = rem(samplesUntilDone, bufferSize); actEndIndex = endIndex + bufferSize - extraSamples; obj.StartIndex = startIndex; obj.EndIndex = actEndIndex; % Feed Data to the asyncio Channel in chunks % Note: This is done instead of one call to OutputStream.write % to avoid extra memory usage while the OutputStream is segmenting % the audio and sending it to the device. curPos = obj.StartIndex; chunkSize = bufferSize * 100; % send 100 'buffers' at a time while(curPos <= obj.EndIndex) endChunk = curPos + chunkSize - 1; if (endChunk > obj.EndIndex) % This code path is hit for the last chunk or buffer being played % back. % As the EndIndex property includes the padding to ensure a full % buffer, copy only the suitable amount of data from that supplied % by the user. endChunk = obj.EndIndex; dataToWrite = zeros( endChunk - curPos + 1, ... obj.NumberOfChannels, ... class(obj.AudioData) ); dataToWrite(1:endIndex - curPos + 1, 1:obj.NumberOfChannels) = ... obj.Audiodata(curPos:endIndex,1:obj.NumberOfChannels); obj.Channel.OutputStream.write(dataToWrite, bufferSize); else obj.Channel.OutputStream.write( ... obj.Audiodata(curPos:endChunk,1:obj.NumberOfChannels), ... bufferSize); end curPos = endChunk + 1; end obj.resume(); end