This file is indexed.

/usr/share/psychtoolbox-3/PsychBasic/Snd.m is in psychtoolbox-3-common 3.0.14.20170103+git6-g605ff5c.dfsg1-1build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
function err = Snd(command,signal,rate,sampleSize)
% err = Snd(command,[signal],[rate],[sampleSize])
%
% Old Sound driver for Psychtoolbox. USE OF THIS DRIVER IS DEPRECATED FOR
% ALL BUT THE MOST TRIVIAL PURPOSES!
%
% Have a look at the help for PsychPortAudio ("help PsychPortAudio" and
% "help InitializePsychSound") for an introduction into the new sound
% driver, which is recommended for most purposes.
%
% Snd() is a rather dumb and primitive wrapper around the PsychPortAudio()
% driver. It uses PsychPortAudio's most basic functionality to achieve
% "sort of ok" sound playback. The driver is used in high-latency,
% low-timing precision mode, so Snd()'s audio playback timing will likely
% be very unreliable.
%
% Alternatively you can create an empty file named 'Snd_use_oldstyle.txt' in
% the PsychtoolboxConfigDir() folder, ie., [PsychtoolboxConfigDir 'Snd_use_oldstyle.txt']
% This will enable the old-style implementation of Snd(), which is equally
% shoddy and works as follows:
%
% While Snd used to use a special purpose low level driver on MacOS-9 which
% was well suited for cognitive science, Snd for all other operating
% systems (Windows, MacOS-X, Linux) just calls into Matlab's Sound()
% function which is of varying - but usually pretty poor - quality in most
% implementations of Matlab. There are many bugs, latency- and timing
% problems associated with the use of Snd.
%
% GNU/OCTAVE: If you don't use the PsychPortAudio based Snd() functin, then
% you must install the optional octave "audio" package from Octave-Forge,
% as of Octave 3.0.5, otherwise the required sound() function won't be
% available and this function will fail!
%
%
% Supported functions:
% --------------------
%
% Snd('Play', signal [, rate][, sampleSize]) plays a sound.
%
% rate=Snd('DefaultRate') returns the default sampling rate in Hz, which
% currently is 22254.5454545454 Hz on all platforms for the old style sound
% implementation, and the default device sampling rate if PsychPortAudio is
% used. This default may change in the future, so please either specify a
% rate, or use this function to get the default rate. (This default is
% suboptimal on any system except MacOS-9, but kept for backwards
% compatibility!)
%
% The optional 'sampleSize' argument used with Snd('Play') is only retained
% for backwards compatibility and has no meaning, unless you opt in to use
% the old-style implementation on Matlab with some operating systems. - It
% is checked for correctness, but other than that it is ignored. Allowable
% values are either 8 or 16.
%
% Snd('Open') opens the channel, which stays open until you call
% Snd('Close'). Snd('Play',...) automatically opens the channel if it isn't
% already open. In reality 'Open' does nothing in the current
% implementation and is silently ignored .
%
% Snd('Close') immediately stops all sound and closes the channel.
%
% Snd('Wait') waits until the sound is done playing.
%
% isPlaying=Snd('IsPlaying') returns true if any sound is playing, and
% false (0) otherwise.
%
% Snd('Quiet') stops the sound currently playing and flushes the queue, but
% leaves the channel open.
%
% "signal" must be a numeric array of samples.
%
% Your "signal" data should lie between -1 and 1 (smaller to play more
% softly). If the "signal" array has one row then it's played monaurally,
% through both speakers. If it has two rows then it's played in stereo.
% (Snd has no provision for changing which speaker(s), or the volume, used
% by a named snd resource, so use READSND to get the snd into an array,
% and supply the appropriately modified array to Snd.)
%
% "rate" is the rate (in Hz) at which the samples in "signal" should be
% played. We suggest you always specify the "rate" parameter. If not
% specified, the sample "rate", on all platforms, defaults to OS9's
% standard hardware sample rate of 22254.5454545454 Hz. That value is
% returned by Snd('DefaultRate'). Other values can be specified.
%
% OSX & WIN: "samplesize". Snd accepts the sampleSize argument and passes
% it to the Matlab SOUND command.  SOUND (and therefore Snd also) obeys the
% specified sampleSize value, either 8 or 16, only if it is supported by
% your computer hardware.
%
% Snd('Play',sin(0:10000)); % play 22 KHz/(2*pi)=3.5 kHz tone
% Snd('Play',[sin(1:20000) zeros(1,10000);zeros(1,10000) sin(1:20000)]); % stereo
% Snd('Wait');         		% wait until end of all sounds currently in channel
% Snd('Quiet');        		% stop the sound and flush the queue
%
% For most of the commands, the returned value is zero when successful, and
% a nonzero error number when Snd fails.
%
% Snd('Play', signal) takes some time to open the channel, if it isn't
% already open, and allocate a snd structure for your sound. This overhead
% of the call to Snd, if you call it in the middle of a movie, may be
% perceptible as a pause in the movie, which would be bad. However, the
% actual playing of the sound, asynchronously, is a background process that
% usually has very little overhead. So, even if you want a sound to begin
% after the movie starts, you should create a soundtrack for your entire
% movie duration (possibly including long silences), and call Snd to set
% the sound going before you start your movie. (Thanks to Liz Ching for
% raising the issue.)
%
% NOTE: We suggest you always specify the "rate" parameter. If not
% specified, the sample rate, on all platforms, defaults to OS9's
% standard hardware sample rate of 22254.5454545454 Hz. That value is returned
% by Snd('DefaultRate').
%
% See also PsychPortAudio, Beeper, AUDIOPLAYER, PLAY, MakeBeep, READSND, and WRITESND.

% 6/6/96    dgp Wrote SndPlay.
% 6/1/97    dgp Polished help text.
% 12/10/97  dhb Updated help.
% 2/4/98    dgp Wrote Snd, based on major update of VideoToolbox SndPlay1.c.
% 3/8/00    emw Added PC notes and code.
% 7/23/00   dgp Added notes about controlling volume of named snd, and updated
%               broken link to ResEdit.
% 4/13/02   dgp Warn that the two platforms have different default sampling rate,
%               and suggest that everyone routinely specify sampling rate to
%               make their programs platform-independent.
% 4/13/02   dgp Enhanced both OS9 and WIN versions so that 'DefaultRate'
%               returns the default sampling rate in Hz.
% 4/13/02   dgp Changed WIN code, so that sampling rate is now same on both platforms.
% 4/15/02   awi fixed WIN code.
% 5/30/02   awi Added sampleSize argument and documented.
%               SndTest would crash Matlab but the problem mysteriously vanished while editing
%               the Snd.m and SndTest.m files.  I've been unable to reproduce the error.
% 3/10/05   dgp Make it clear that the Snd mex is only available for OS9.
%               Mention AUDIOPLAYER, as suggested by Pascal Mamassian.
% 5/20/08    mk Explain that Snd() is deprecated --> Point to PsychPortAudio!
% 1/12/09    mk Make sure that 'signal' is a 2-row matrix in stereo, not 2
%               column.
% 6/01/09    mk Add compatibility with Octave-3.
% 9/03/12    mk Add new implementation via PsychPortAudio(), which is used
%               by default unless user opts out. Cleanup online help by
%               removal of obsolete and outdated information.
% 7/20/15    mk Make commands case insensitive, white-space cleanup, try to
%               make Snd('Open'); Snd('Close'); sequences work to avoid problems
%               like in PTB forum message #19284 on Linux or Windows.
% 1/19/16    mk Make more robust against failing InitializePsychSound. Fallback to sound().

persistent ptb_snd_oldstyle;
persistent pahandle;

persistent endTime;
if isempty(endTime)
    endTime = 0;
end

% Default return value:
err = 0;

% Already defined if we shall use the new-style or old-style
% implementation?
if isempty(ptb_snd_oldstyle)
    % Nope, check if the special "old style" marker file exists:
    if exist([PsychtoolboxConfigDir 'Snd_use_oldstyle.txt'], 'file')
        % User explicitely wants old-style implementation via
        % Matlab/Octave sound() function:
        ptb_snd_oldstyle = 1;

        fprintf('Snd(): Using Matlab/Octave sound() function for sound output.\n');
    else
        % User wants new-style PsychPortAudio variant:
        ptb_snd_oldstyle = 0;

        fprintf('Snd(): Initializing PsychPortAudio driver for sound output.\n');

        % Low-Latency preinit. Not that we'd need it, but doesn't hurt:
        try
            InitializePsychSound(1);
        catch
            fprintf('Snd(): ERROR!\n');
            ple;
            psychlasterror('reset');
            fprintf('Snd(): PsychPortAudio initialization failed - See error messages above. Trying to use old sound() fallback instead.\n');
            ptb_snd_oldstyle = 1;
        end
    end
end

if nargin == 0
    error('Wrong number of arguments: see Snd.');
end

% Don't use PsychPortAudio backend if already a PPA device open on Linux or
% Windows, as that device will often have exclusive access, so we would
% fail here:
if ~(strcmpi(command,'Open') || strcmpi(command,'Quiet') || strcmpi(command,'Close')) && ...
    isempty(pahandle) && ~ptb_snd_oldstyle && ~IsOSX && (PsychPortAudio('GetOpenDeviceCount') > 0)
    fprintf('Snd(): PsychPortAudio already in use. Using old sound() fallback instead...\n');
    ptb_snd_oldstyle = 1;
end

if strcmpi(command,'Play')
    if nargin > 4
        error('Wrong number of arguments: see Snd.');
    end

    if nargin == 4
        if isempty(sampleSize)
            sampleSize = 16;
        elseif ~((sampleSize == 8) || (sampleSize == 16))
            error('sampleSize must be either 8 or 16.');
        end
    else
        sampleSize = 16;
    end

    if nargin < 3
        rate = [];
    end

    if nargin < 2
        error('Wrong number of arguments: see Snd.');
    end

    if size(signal,1) > size(signal,2)
        error('signal must be a 2 rows by n column matrix for stereo sounds.');
    end

    if isempty(rate)
        if ptb_snd_oldstyle
            % Old MacOS-9 style default:
            rate = 22254.5454545454;
        else
            % Let PPA decide itself:
            rate = [];
        end
    end

    if ptb_snd_oldstyle
        % Old-Style implementation via sound() function:

        WaitSecs(endTime-GetSecs); % Wait until any ongoing sound is done.

        % Octave special-case:
        if IsOctave
            if exist('sound') %#ok<EXIST>
                sound(signal',rate);
            else
                % Unavailable: Try to load the package, assuming its
                % installed but not auto-loaded:
                try
                    pkg('load','audio');
                catch %#ok<CTCH>
                end

                % Retry...
                if exist('sound') %#ok<EXIST>
                    sound(signal',rate);
                else
                    warning('Required Octave command sound() is not available. Install and "pkg load audio" the "audio" package from Octave-Forge!'); %#ok<WNTAG>
                end
            end
        else
            sound(signal',rate,sampleSize);
        end

        % Estimate 'endTime' for playback:
        endTime=GetSecs+length(signal)/rate;
    else
        % New-Style via PsychPortAudio:
        if ~isempty(pahandle)
            % PPA playback device already open.

            % Wait blocking until end of its playback:
            PsychPortAudio('Stop', pahandle, 1, 1);

            % Correct sampling rate set?
            props = PsychPortAudio('GetStatus', pahandle);
            if ~isempty(rate) && (abs(props.SampleRate - rate) > 1.0)
                % Device sampleRate not within tolerance of 1 Hz to
                % requested samplingrate. Close it, so it can get reopened
                % with proper rate:
                PsychPortAudio('Close', pahandle);
                pahandle = [];
            end
        end

        if isempty(pahandle)
            % Be silent during driver/device init:
            oldverbosity = PsychPortAudio('Verbosity', 2);

            % Open our own 'pahandle' sound device: Auto-Selected output
            % device [], playback only (1),
            % high-latency/low-timing-precision mode (0), at given
            % samplerate (rate), in stereo (2):
            pahandle = PsychPortAudio('Open', [], 1, 0, rate, 2);

            % Restore standard level of verbosity:
            PsychPortAudio('Verbosity', oldverbosity);

            if ~IsOSX
                fprintf('Snd(): PsychPortAudio will be blocked for use by your own code until you call Snd(''Close'');\n');
                fprintf('Snd(): If you want to use PsychPortAudio and Snd in the same session, make sure to open your\n');
                fprintf('Snd(): stimulation sound device via calls to PsychPortAudio(''Open'', ...); *before* the first\n');
                fprintf('Snd(): call to Snd() or any function that might use Snd(), e.g., Beeper() and the Eyelink functions.\n\n');
            end
        end

        % Make signal stereo if it isn't already:
        if size(signal, 1) < 2
            sndbuff = [signal ; signal];
        else
            sndbuff = signal;
        end

        % Play it:
        PsychPortAudio('FillBuffer', pahandle, sndbuff);
        PsychPortAudio('Start', pahandle, 1, 0, 1);
    end

elseif strcmpi(command,'Wait')
    if nargin>1
        error('Wrong number of arguments: see Snd.');
    end

    if ~isempty(pahandle)
        % Wait blocking until end of playback:
        PsychPortAudio('Stop', pahandle, 1, 1);
    else
        WaitSecs(endTime-GetSecs); % Wait until any ongoing sound is done.
    end
    err=0;

elseif strcmpi(command,'IsPlaying')
    if nargin>1
        error('Wrong number of arguments: see Snd.');
    end

    if ~isempty(pahandle)
        props = PsychPortAudio('GetStatus', pahandle);
        err = props.Active;
    else
        if endTime>GetSecs
            err=1;
        else
            err=0;
        end
    end

elseif strcmpi(command,'Quiet') || strcmpi(command,'Close')
    if nargin>1
        error('Wrong number of arguments: see Snd.');
    end

    if ~isempty(pahandle)
        % Stop playback asap, wait for stop:
        PsychPortAudio('Stop', pahandle, 2, 1);

        % Close command?
        if strcmpi(command,'Close')
            % Close it:
            PsychPortAudio('Close', pahandle);
            pahandle = [];
        end
    else
        if ~IsOctave
            clear playsnd; % Stop any ongoing sound.
        end
    end
    endTime=0;
    err=0;

elseif strcmpi(command,'DefaultRate')
    if nargin>1
        error('Wrong number of arguments: see Snd.');
    end

    if ptb_snd_oldstyle
        % Old style - old hard-coded default:
        err = 22254.5454545454; % default sampling rate in Hz.
    else
        % Audio device open?
        if isempty(pahandle)
            % No: Fake it - Use the most common sampling rate:
            err = 44100;
        else
            % Yes: Query its default sampling rate:
            s = PsychPortAudio('GetStatus', pahandle);
            di = PsychPortAudio('GetDevices', [], s.OutDeviceIndex);
            err = di.DefaultSampleRate;
        end
    end

elseif strcmpi(command,'Open')
    endTime=0;
else
    PsychPortAudio('Close');
    pahandle = [];
    error(['unknown command "' command '"']);
end

return;