This file is indexed.

/usr/share/psychtoolbox-3/PsychDemos/BasicSoundFeedbackDemo.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
function BasicSoundFeedbackDemo(reqlatency, duplex)
% BasicSoundFeedbackDemo([reqlatency=7.5 ms] [,duplex=0])
%
% Demonstrates very basic usage of the new Psychtoolbox sound driver
% PsychPortAudio() for audio feedback. For a more complex solution
% which provides much more precise audio feedback timing for control
% of audio feedback delay, look at DelayedSoundFeedbackDemo instead.
%
% Sound is captured from the default recording device and then - with a
% selectable delay - played back via the default output device.
%
% By default, feedback is tried with a latency of 7.5 ms plus hardware and
% system inherent delay, but you can ask for a specific latency in msecs by
% providing the optional parameter 'reqlatency'. Achievable latency will be
% constrained by the capabilities of your hardware. Choosing too low of a
% value will create audible artifacts in the sound and the driver may
% output warning about 'buffer underflows during streaming refill...'.
%
% Depending on your sound hardware you'll have to either leave 'duplex' at
% its default of zero (2 times half-duplex mode) or set it to 1
% (full-duplex mode): ASIO driven hardware -- typically on MS-Windows --
% will usually need full-duplex mode. On Macintosh OS/X it depends on the
% sound hardware. IntelMacs are happy with half-duplex mode, some PowerMacs
% may need full-duplex mode.
%
%
% If you need low-latency, make sure to read "help InitializePsychSound"
% carefully or contact the forum.
%

% History:
% 07/20/2007 Written (MK)

% Running on PTB-3? Abort otherwise.
AssertOpenGL;

fprintf('\n\nTHIS IS EARLY ALPHA CODE! IT MAY OR MAY NOT WORK RELIABLY ON YOUR SETUP!\nTEST IT WITH MEASUREMENT EQUIPMENT IF YOU DEPEND ON ACCURATE FEEDBACK\nTIMING!!!\n\n');

% Latency provided?
if nargin < 1
    reqlatency = [];
end

if isempty(reqlatency)
    reqlatency = 7.5;
end

if nargin < 2
    duplex = [];
end

if isempty(duplex)
    duplex =0;
end

lat =  reqlatency / 1000;

% Try a sample rate of 48kHz. Should be supported by most hardware:
freq = 48000;

% Wait for release of all keys on keyboard:
KbReleaseWait;

% Perform low-level initialization of the sound driver:
InitializePsychSound(1);

% Provide some debug output:
PsychPortAudio('Verbosity', 10);

if (reqlatency == 0) && duplex
    % Special case: Full-duplex mode with minimum latency. We bypass Matlab
    % by activating PsychPortAudios full-duplex monitoring mode. The driver
    % itself will feed back all captured sound to the outputs with lowest
    % possible latency. However we don't have any control over latency or
    % sound and this only works on full-duplex hardware...
    fprintf('Full-duplex monitoring mode active.\n');
    pa = PsychPortAudio('Open', [], 4+2+1, 2, freq, 2, [], 0.010);
    PsychPortAudio('Start', pa, 0, 0, 1);
    while ~KbCheck
        WaitSecs(0.5);
        s=PsychPortAudio('GetStatus', pa);
        disp(s);
    end
    PsychPortAudio('Stop', pa);
    PsychPortAudio('Close');
    return;
end

if ~duplex
    % Open the default audio device [], with mode 2 (== Only audio capture),
    % and a required latencyclass of 2 == low-latency mode, as well as
    % a frequency of freq Hz and 2 sound channels for stereo capture.
    % This returns a handle to the audio device:
    painput = PsychPortAudio('Open', [], 2, 2, freq, 2);
else
    % Same procedure, but open for full-duplex operation:
    painput = PsychPortAudio('Open', [], 2+1, 2, freq, 2, [], 0.010);
    % Output- and input device are the same...
    paoutput = painput;
end

% Preallocate an internal audio recording  buffer with a capacity of 10 seconds:
PsychPortAudio('GetAudioData', painput, 10);

if ~duplex
    % Open default audio device [] for playback (mode 1), low latency (2), freq Hz,
    % stereo output:
    paoutput = PsychPortAudio('Open', [], 1, 2, freq, 2);
end

% Full duplex mode. Doesn't work yet...
if duplex
    % Prefill playback buffer with silence...
    PsychPortAudio('FillBuffer', paoutput, zeros(2, freq * 2 * lat));
end

% Start audio capture immediately and wait for the capture to start.
% We set the number of 'repetitions' to zero, i.e. record/play until
% manually stopped.
painputstart = PsychPortAudio('Start', painput, 0, 0, 1);

% Wait for at least lat secs of sound data to become available: This
% directly defines a lower bound on real feedback latency. Its also a weak
% point, because waiting longer than 'lat' will increase output latency...
s=PsychPortAudio('GetStatus', painput);
availsecs = s.RecordedSecs;
while availsecs < lat
    WaitSecs(0.0001);
    s=PsychPortAudio('GetStatus', painput);
    availsecs = s.RecordedSecs;
end

% Quickly readout available sound and initialize sound output buffer with it:
[audiodata offset overflow capturestart]= PsychPortAudio('GetAudioData', painput);

if ~duplex
    % Feed everything into the initial sound output buffer:
    PsychPortAudio('FillBuffer', paoutput, audiodata);

    % Start the playback engine immediately and wait for start, let it run
    % until manually stopped:
    playbackstart = PsychPortAudio('Start', paoutput, 0, 0, 1);
else
    % Duplex mode: We don't get separate timestamps for capture and
    % playback yet. Set them to be the same - The best we can do for now...
    playbackstart = painputstart;
end

% Now the playback engine should output the first lat msecs of our sound,
% while the capture engine captures the next msecs. Compute expected
% latency. This is what the driver thinks, accuracy depends on the quality
% of implementation of the underlying sound subsystem, so its dependent on
% operating system and sound driver/sound hardware:
expecteddelay = (playbackstart - capturestart) * 1000;
fprintf('Expected latency at least %f msecs.\n', expecteddelay);

% Feedback loop: Runs until keypress ...
while ~KbCheck
    % Sleep about lat/2 secs to give the engines time to at least capture and
    % output lat/2 secs worth of sound ...
    WaitSecs(lat/5);
    
    % Get new captured sound data ...
    [audiodata, offset, overrun] = PsychPortAudio('GetAudioData', painput);
    
    % ... and stream it into our output buffer:
    while size(audiodata, 2) > 0
        % Make sure to never push more data in the buffer than it can
        % actually hold, ie not more than half its maximum capacity:
        fetch = min(size(audiodata, 2), floor(freq * lat/2));
        % We feed data in chunks...
        pushdata = audiodata(:, 1:fetch);
        audiodata = audiodata(:, fetch+1:end);
        % Perform streaming buffer refill. As long as we don't push more
        % than a buffer size, the driver will take care of the rest...
        PsychPortAudio('FillBuffer', paoutput, pushdata, 1);
    end
    
    % Done. Next iteration...
end

% Done. Stop the capture engine:
PsychPortAudio('Stop', painput, 1);

% Drain its capture buffer...
[audiodata offset]= PsychPortAudio('GetAudioData', painput);

if ~duplex
    % Stop the playback engine:
    PsychPortAudio('Stop', paoutput, 1);
end

% Ok, done. Close engines and exit.
PsychPortAudio('Close');

% Done.
fprintf('Demo finished, bye!\n');

return;