/usr/share/psychtoolbox-3/PsychDemos/BasicSoundInputDemo.m is in psychtoolbox-3-common 3.0.9+svn2579.dfsg1-1.
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 | function BasicSoundInputDemo(wavfilename, voicetrigger, maxsecs)
% BasicSoundInputDemo([wavfilename] [, voicetrigger=0] [, maxsecs=inf])
%
% Demonstrates very basic usage of the new Psychtoolbox sound driver
% PsychPortAudio() for audio capture / recording.
%
% Sound is captured from the default recording device, optionally waiting
% until the amplitude exceeds some threshold level before start of
% recording. At the end of the recording session the recorded sound is
% played back vie the default output device. Waveform data of captured
% sound is also plotted to a Matlab figure window during capture.
%
% This demo only demonstrates normal operation, not the low-latency mode,
% extra demos and tests for low-latency and high precision timing output will
% follow soon. If you need low-latency, make sure to read "help
% InitializePsychSound" carefully or contact the forum.
% Our preliminary testing for low-latency mode showed that sub-millisecond
% accurate sound onset and << 10 msecs latency are possible on OS/X and on
% some specially configured M$-Windows setups.
%
%
% Optional arguments:
%
% wavfilename = Name of a .wav sound file to store the recorded sound to.
% If left out, sound won't be stored to filesystem.
%
% voicetrigger = If set to a non-zero threshold value, the driver will wait
% for the sound signal to exceed the specified voicetrigger threshold
% level before it starts capturing audio data.
%
% maxsecs = Maximum number of seconds of sound to capture. Defaults to
% infinite - sound is recorded until a key is pressed.
% History:
% 06/30/2007 Written (MK)
% 08/10/2008 Add some sound onset time calculation for the fun of it. (MK)
% Running on PTB-3? Abort otherwise.
AssertOpenGL;
% Filename provided?
if nargin < 1
wavfilename = [];
end
if nargin < 2
voicetrigger = [];
end
if isempty(voicetrigger)
voicetrigger = 0;
end
if nargin < 3
maxsecs = [];
end
if isempty(maxsecs)
maxsecs = inf;
end
% Wait for release of all keys on keyboard:
while KbCheck; end;
% Perform basic initialization of the sound driver:
InitializePsychSound;
% Open the default audio device [], with mode 2 (== Only audio capture),
% and a required latencyclass of zero 0 == no low-latency mode, as well as
% a frequency of 44100 Hz and 2 sound channels for stereo capture.
% This returns a handle to the audio device:
freq = 44100;
pahandle = PsychPortAudio('Open', [], 2, 0, freq, 2);
% Preallocate an internal audio recording buffer with a capacity of 10 seconds:
PsychPortAudio('GetAudioData', pahandle, 10);
% Start audio capture immediately and wait for the capture to start.
% We set the number of 'repetitions' to zero,
% i.e. record until recording is manually stopped.
PsychPortAudio('Start', pahandle, 0, 0, 1);
fprintf('Audio capture started, press any key for about 1 second to quit.\n');
% Want to start via VoiceTrigger?
if voicetrigger > 0
% Yes. Fetch audio data and check against threshold:
level = 0;
% Repeat as long as below trigger-threshold:
while level < voicetrigger
% Fetch current audiodata:
[audiodata offset overflow tCaptureStart] = PsychPortAudio('GetAudioData', pahandle);
% Compute maximum signal amplitude in this chunk of data:
if ~isempty(audiodata)
level = max(abs(audiodata(1,:)));
else
level = 0;
end
% Below trigger-threshold?
if level < voicetrigger
% Wait for a millisecond before next scan:
WaitSecs(0.0001);
end
end
% Ok, last fetched chunk was above threshold!
% Find exact location of first above threshold sample.
idx = min(find(abs(audiodata(1,:)) >= voicetrigger)); %#ok<MXFND>
% Initialize our recordedaudio vector with captured data starting from
% triggersample:
recordedaudio = audiodata(:, idx:end);
% For the fun of it, calculate signal onset time in the GetSecs time:
% Caution: For accurate and reliable results, you should
% PsychPortAudio('Open',...); the device in low-latency mode, as
% opposed to the "normal" mode used in this demo! If you fail to do so,
% the tCaptureStart timestamp may be inaccurate on some systems, and
% therefore this tOnset timestamp may be off! See for example
% PsychPortAudioTimingTest and AudioFeedbackLatencyTest for how to
% setup low-latency high precision mode.
tOnset = tCaptureStart + ((offset + idx - 1) / freq);
fprintf('Estimated signal onset time is %f secs, this is %f msecs after start of capture.\n', tOnset, (tOnset - tCaptureStart)*1000);
else
% Start with empty sound vector:
recordedaudio = [];
end
% We retrieve status once to get access to SampleRate:
s = PsychPortAudio('GetStatus', pahandle);
% Stay in a little loop until keypress:
while ~KbCheck & ((length(recordedaudio) / s.SampleRate) < maxsecs)
% Wait a second...
WaitSecs(1);
% Query current capture status and print it to the Matlab window:
s = PsychPortAudio('GetStatus', pahandle);
% Print it:
fprintf('\n\nAudio capture started, press any key for about 1 second to quit.\n');
fprintf('This is some status output of PsychPortAudio:\n');
disp(s);
% Retrieve pending audio data from the drivers internal ringbuffer:
audiodata = PsychPortAudio('GetAudioData', pahandle);
nrsamples = size(audiodata, 2);
% Plot it, just for the fun of it:
plot(1:nrsamples, audiodata(1,:), 'r', 1:nrsamples, audiodata(2,:), 'b');
drawnow;
% And attach it to our full sound vector:
recordedaudio = [recordedaudio audiodata]; %#ok<AGROW>
end
% Stop capture:
PsychPortAudio('Stop', pahandle);
% Perform a last fetch operation to get all remaining data from the capture engine:
audiodata = PsychPortAudio('GetAudioData', pahandle);
% Attach it to our full sound vector:
recordedaudio = [recordedaudio audiodata];
% Close the audio device:
PsychPortAudio('Close', pahandle);
% Replay recorded data: Open default device for output, push recorded sound
% data into its output buffer:
pahandle = PsychPortAudio('Open', [], 1, 0, 44100, 2);
PsychPortAudio('FillBuffer', pahandle, recordedaudio);
% Start playback immediately, wait for start, play once:
PsychPortAudio('Start', pahandle, 1, 0, 1);
% Wait for end of playback, then stop engine:
PsychPortAudio('Stop', pahandle, 1);
% Close the audio device:
PsychPortAudio('Close', pahandle);
% Shall we store recorded sound to wavfile?
if ~isempty(wavfilename)
wavwrite(transpose(recordedaudio), 44100, 16, wavfilename)
end
% Done.
fprintf('Demo finished, bye!\n');
|