diff --git a/Psychtoolbox/PsychDemos/BasicSoundInputDemo.m b/Psychtoolbox/PsychDemos/BasicSoundInputDemo.m index f49aa8304..b2264b2bf 100644 --- a/Psychtoolbox/PsychDemos/BasicSoundInputDemo.m +++ b/Psychtoolbox/PsychDemos/BasicSoundInputDemo.m @@ -1,5 +1,5 @@ -function BasicSoundInputDemo(wavfilename, voicetrigger, maxsecs, device, reqlatencyclass) -% BasicSoundInputDemo([wavfilename][, voicetrigger=0][, maxsecs=inf][, device][, reqlatencyclass]) +function BasicSoundInputDemo(wavfilename, voicetrigger, maxsecs, device, reqlatencyclass, channels) +% BasicSoundInputDemo([wavfilename][, voicetrigger=0][, maxsecs=inf][, device][, reqlatencyclass][, channels=2]) % % Demonstrates very basic usage of the new Psychtoolbox sound driver % PsychPortAudio() for audio capture / recording. @@ -32,6 +32,8 @@ function BasicSoundInputDemo(wavfilename, voicetrigger, maxsecs, device, reqlate % reqlatencyclass = Override reqlatencyclass parameter for audio capture. Defaults % to standard [] for low-latency, high timing precision if omitted. % +% channels = Number of input and output channels to use. Defaults to 2. +% % History: % 06/30/2007 Written (MK) @@ -77,8 +79,12 @@ function BasicSoundInputDemo(wavfilename, voicetrigger, maxsecs, device, reqlate reqlatencyclass = 2; end +if nargin < 6 || isempty(channels) + channels = 2; +end + % Workaround broken qt plotting on some Octave setups: -if IsOctave && exist('graphics_toolkit') +if IsOctave && exist('graphics_toolkit') %#ok try graphics_toolkit ('fltk'); catch @@ -94,9 +100,9 @@ function BasicSoundInputDemo(wavfilename, voicetrigger, maxsecs, device, reqlate % Open audio device 'device', with mode 2 (== Only audio capture), % and a required latencyclass of 'reqlatencyclass', with the preferred -% default sampling frequency of the audio device, and 2 sound channels +% default sampling frequency of the audio device, and 'channels' sound channels % for stereo capture. This returns a handle to the audio device: -pahandle = PsychPortAudio('Open', device, 2, reqlatencyclass, [], 2); +pahandle = PsychPortAudio('Open', device, 2, reqlatencyclass, [], channels); % Get what freq'uency we are actually using: s = PsychPortAudio('GetStatus', pahandle); @@ -120,7 +126,7 @@ function BasicSoundInputDemo(wavfilename, voicetrigger, maxsecs, device, reqlate % Repeat as long as below trigger-threshold: while level < voicetrigger % Fetch current audiodata: - [audiodata offset overflow tCaptureStart] = PsychPortAudio('GetAudioData', pahandle); + [audiodata, offset, ~, tCaptureStart] = PsychPortAudio('GetAudioData', pahandle); % Compute maximum signal amplitude in this chunk of data: if ~isempty(audiodata) @@ -174,7 +180,11 @@ function BasicSoundInputDemo(wavfilename, voicetrigger, maxsecs, device, reqlate nrsamples = size(audiodata, 2); % Plot it, just for the fun of it: - plot(1:nrsamples, audiodata(1,:), 'r', 1:nrsamples, audiodata(2,:), 'b'); + if channels > 1 + plot(1:nrsamples, audiodata(1,:), 'r', 1:nrsamples, audiodata(2,:), 'b'); + else + plot(1:nrsamples, audiodata(1,:), 'r'); + end drawnow; % And attach it to our full sound vector: @@ -202,7 +212,7 @@ function BasicSoundInputDemo(wavfilename, voicetrigger, maxsecs, device, reqlate % Replay recorded data: Open 'device' for output, push recorded sound % data into its output buffer: -pahandle = PsychPortAudio('Open', device, 1, 0, freq, 2); +pahandle = PsychPortAudio('Open', device, 1, 0, freq, channels); PsychPortAudio('FillBuffer', pahandle, recordedaudio); % Start playback immediately, wait for start, play once: diff --git a/Psychtoolbox/PsychDemos/DelayedSoundFeedbackDemo.m b/Psychtoolbox/PsychDemos/DelayedSoundFeedbackDemo.m index 38768eb63..a2817b20f 100644 --- a/Psychtoolbox/PsychDemos/DelayedSoundFeedbackDemo.m +++ b/Psychtoolbox/PsychDemos/DelayedSoundFeedbackDemo.m @@ -1,5 +1,5 @@ -function DelayedSoundFeedbackDemo(reqlatency, duplex, freq, minLatency, device) -% DelayedSoundFeedbackDemo([reqlatency=150 ms][, duplex=0][, freq]=48000[, minLatency=10 ms][, device]) +function DelayedSoundFeedbackDemo(reqlatency, duplex, freq, minLatency, device, channels) +% DelayedSoundFeedbackDemo([reqlatency=150 ms][, duplex=0][, freq]=48000[, minLatency=10 ms][, device][, channels=2]) % % CAUTION: TEST TIMING OF THIS SCRIPT WITH MEASUREMENT EQUIPMENT IF YOU % DEPEND ON ACCURATE FEEDBACK TIMING!!! @@ -52,6 +52,8 @@ function DelayedSoundFeedbackDemo(reqlatency, duplex, freq, minLatency, device) % % 'device' Optional device index of soundcard to use. % +% 'channels' Number of input and output channels to use. Defaults to 2. +% % Specific tips for different setups: % % On OSX with builtin sound chip on Intel Macs, choose duplex = 0 for @@ -159,13 +161,17 @@ function DelayedSoundFeedbackDemo(reqlatency, duplex, freq, minLatency, device) % fail with an error if it can't achieve the most high-perf settings: latmode = 4; +if nargin < 6 || isempty(channels) + channels = 2; +end + 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... - pa = PsychPortAudio('Open', device, 4+2+1, latmode, freq, 2, [], minLatency); + pa = PsychPortAudio('Open', device, 4+2+1, latmode, freq, channels, [], minLatency); % Now that the device is open, try to enable the "Zero latency direct input % monitoring" feature of some subset of some sound cards. @@ -239,12 +245,12 @@ function DelayedSoundFeedbackDemo(reqlatency, duplex, freq, minLatency, device) if ~duplex % Open the default audio device [], with mode 2 (== Only audio capture), % and a required latencyclass of latmode == low-latency mode, as well as - % a frequency of freq Hz and 2 sound channels for stereo capture. + % a frequency of freq Hz and 'channels' sound channels for stereo capture. % This returns a handle to the audio device: - painput = PsychPortAudio('Open', device, 2, latmode, freq, 2, [], minLatency); + painput = PsychPortAudio('Open', device, 2, latmode, freq, channels, [], minLatency); else % Same procedure, but open for full-duplex operation: - painput = PsychPortAudio('Open', device, 2+1, latmode, freq, 2, [], minLatency); + painput = PsychPortAudio('Open', device, 2+1, latmode, freq, channels, [], minLatency); % Output- and input device are the same... paoutput = painput; end @@ -254,9 +260,8 @@ function DelayedSoundFeedbackDemo(reqlatency, duplex, freq, minLatency, device) PsychPortAudio('GetAudioData', painput, max(2 * lat, 10)); if ~duplex - % Open default audio device [] for playback (mode 1), low latency (2), freq Hz, - % stereo output: - paoutput = PsychPortAudio('Open', device, 1, latmode, freq, 2, [], minLatency); + % Open default audio device [] for playback (mode 1), low latency (2), freq Hz output: + paoutput = PsychPortAudio('Open', device, 1, latmode, freq, channels, [], minLatency); end % Get actually chosen sampling frequency: @@ -268,7 +273,7 @@ function DelayedSoundFeedbackDemo(reqlatency, duplex, freq, minLatency, device) % One could do this more clever, but this is a safe no-brainer and memory % is cheap: outbuffersize = floor(freq * 3 * max(lat, 10)); -PsychPortAudio('FillBuffer', paoutput, zeros(2, outbuffersize)); +PsychPortAudio('FillBuffer', paoutput, zeros(channels, outbuffersize)); % Start audio playback immediately, wait for the start to happen. Retrieve the % start timestamp, ie., the system time when the first sample in the output @@ -306,7 +311,7 @@ function DelayedSoundFeedbackDemo(reqlatency, duplex, freq, minLatency, device) fprintf('CaptureQuantum (Duty cycle length) is %f msecs, for a buffersize of %i samples.\n', captureQuantum * 1000, s.BufferSize); end -[audiodata offset overflow capturestart] = PsychPortAudio('GetAudioData', painput, [], captureQuantum); +[audiodata, offset, overflow, capturestart] = PsychPortAudio('GetAudioData', painput, [], captureQuantum); % Sanity check returned values: audiodata should be at least headroom * s.BufferSize % samples, offset should be zero as this is the first 'GetAudioData' call