function ns = neurosound(waveform,Fs,datatype,pbspeed,ampscale)
% NEUROSOUND audio output of coninuous or event-based recording
%
% NS = NEUROSOUND(WAVEFORM,FS,DATATYPE,PBSPEED,AMPSCALE)
% 
%       Inputs:
%       WAVEFORM = the waveform that you want to turn into a sound. This
%       can be a continuous waveform, like an intracellular recording, or a
%       list of event times, like spike times.
%       FS = Sampling frequency of recording (Hz)
%       DATATYPE = Continuous waveform (e.g. intracelluar record), or event
%       based waveform (e.g. extracellular spike times).
%           'cont' - waveform is a continous recording
%           'disc' - waveform is discrete event times
%       PBSPEED = scale factor for the playback speed. May be helpful in
%       detecting patterns that occur on different time scales. Increase to
%       make the playback faster. PBSPEED = 1 is real-time.
%       AMPSCALE = Scale factor to keep sound signal within the dynamic
%       range of your speakers [+-1 volt]. Adjust up to stretch dynamic
%       range over [+-1 volt] (e.g. you can't discriminate events in the
%       recording from background noise) and down if you are getting
%       saturation. This option is available only for
%       continuous waveforms and will be ignored otherwise.
% 
%       Outputs:
%       NS = Neurosound audio object. This oject has the following methods
%       associated with it:
%           play(ns) - play the neurosound 
%           stop(ns) - stop the neurosound 
%           pause(ns) - pause the neurosound
%           resume(ns) - resume the neurosound after a pause
%
%       Created by: Jon Newman (jnewman6 at gatech dot edu)
%       Location: The Georgia Institute of Technology
%       Created on: Apr 24, 2010
%       Last modified: Apr 24, 2010
%
%       Licensed under the GPL: http://www.gnu.org/licenses/gpl.txt

% check number and type of arguments
if( nargin < 2)
    error('Must provide waveform and sampling frequency');
end
if( nargin < 3) || isempty(datatype)
    datatype = 'cont';
end
if( nargin < 4) || isempty(pbspeed)
    pbspeed = 1;
end
if( nargin < 5) || isempty(pbspeed)
    ampscale = 0.1;
elseif strcmp(datatype,'disc')
    ampscale = 1;
end

if strcmp(datatype,'cont')
    
    % Scale waveform so that it is within [-1 1] volt range most of the time
    wave = ampscale*(waveform/(sqrt(mean(waveform.^2))));
    ns = audioplayer(wave,pbspeed*Fs);
    
elseif strcmp(datatype,'disc')
    
    % Create continuous waveform from the discrete events
    sortedtimes = sort(waveform); % sorted times, in seconds, referenced to t=0.
    maxT = sortedtimes(end) + 0.1; % length of sound will be the time of the final event + 100 ms
    N = ceil(Fs*maxT);
    wave = zeros(N,1);
    eventInd = ceil(Fs*sortedtimes);
    wave(eventInd) = 0.3;
    wave(eventInd-1) = -0.3;
    ns = audioplayer(wave,pbspeed*Fs);
    
else
    error('The data type you entered is invalid')
end

% Instructions for use
disp(' ');
disp('You have created a neurosound object with the following properties:');
disp(strcat(['Data type: ' datatype]));
disp(strcat(['Playback speed: ' num2str(pbspeed) ' X real-time']));
disp(strcat(['Amplitude scale factor: ' num2str(ampscale)]));
disp(' ');
disp('Use the following commands to control playback: ');
disp('[1]: "play(ns)" to stop the playback');
disp('[2]: "stop(ns)" to stop the playback');
disp('[3]: "pause(ns)" to pause the playback');
disp('[4]: "resume(ns)" to resume the playback');
disp('Where "ns" is whatever you name the output of the neurosound function');

end



