Audio I/O Demo 4– Setting up a microphone feedback loop¶
This demo records microphone input or audio in and plays it back on audio out.
DatapixxMicrophoneDemo can be called with argument 1 or 2, where 1 is for a microphone and 2 is for an audio in source. A microphone needs a bigger gain, otherwise the code is very similar for both sources.
This is a loopback demo, we record audio at 48 kHz and for a maximum of 20 MB/100 seconds of data Datapixx('SetMicrophoneSchedule', 0, 48000, 0, 3, 0, 5e6);
.
We then acquire the number of audio frames recorded
status = Datapixx('GetMicrophoneStatus');
andnFrames = status.newBufferFrames;
, then we play it back with an audio schedule:Datapixx('SetAudioSchedule', 0, 48000, nFrames, 3, 0);
.
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 | function DatapixxMicrophoneDemo(audioSource)
% DatapixxMicrophoneDemo([audioSource=1])
%
% Records audio from the microphone input,
% then plays back the recording on the audio outputs.
%
% Optional argument:
%
% audioSource = 1 to use a high-impedance microphone plugged into "MIC IN" jack
% 2 to use a line-level audio source plugged into "Audio IN" jack
%
% Also see: DatapixxAudioFeedbackDemo
%
% History:
%
% Nov 1, 2009 paa Written
% Oct 29, 2014 dml Revised
AssertOpenGL; % We use PTB-3
% OS-independant keyCodes
KbName('UnifyKeyNames');
Escape = KbName('ESCAPE');
% Open Datapixx, and stop any schedules which might already be running
Datapixx('Open');
Datapixx('StopAllSchedules');
Datapixx('InitAudio');
Datapixx('RegWrRd'); % Synchronize DATAPixx registers to local register cache
% Get audio source argument
if nargin < 1
audioSource = [];
end
if isempty(audioSource)
audioSource = 1;
end
% Configure audio acquisition
if (audioSource == 1)
fprintf('\nEnsure microphone is plugged into DATAPixx "MIC IN" jack\n');
gain = 100; % For inexpensive high-impedance microphones
elseif (audioSource == 2)
fprintf('\nEnsure audio source is plugged into DATAPixx "Audio IN" jack\n');
gain = 1; % For powered microphones, or other line-level audio
else
fprintf('audioSource argument must be either 1 or 2\n');
Datapixx('Close');
return;
end
Datapixx('SetMicrophoneSource', audioSource, gain);
Datapixx('DisableAudioLoopback');
Datapixx('RegWrRd');
% We'll keep executing record/playback loop until user escapes
while (1)
KbReleaseWait(); % Wait until no buttons are being pressed
fprintf('\nHit any key to start recording, (or <escape> to exit)...\n');
if (exist('OCTAVE_VERSION'))
fflush(stdout);
end
[~, keyCode] = KbWait; % Wait for the initiating keypress
if keyCode(Escape)
break;
end
% Start recording stereo audio input at 48 kHz.
% We'll record into address 0, with a 5 million frame buffer (20MB) for up to 100 seconds of solid recording.
Datapixx('SetMicrophoneSchedule', 0, 48000, 0, 3, 0, 5e6);
Datapixx('StartMicrophoneSchedule');
Datapixx('RegWrRd');
fprintf('Recording...\n');
if (exist('OCTAVE_VERSION'))
fflush(stdout);
end
% A second keypress will stop the recording
KbReleaseWait();
fprintf('Hit any key to stop recording, and initiate playback...\n');
if (exist('OCTAVE_VERSION'))
fflush(stdout);
end
[~, keyCode] = KbWait; % I guess we'll permit an escape here as well
if keyCode(Escape)
break;
end
Datapixx('StopMicrophoneSchedule');
Datapixx('RegWrRd');
% How many samples did we acquire?
status = Datapixx('GetMicrophoneStatus');
nFrames = status.newBufferFrames;
% At this point, we could upload the data to the host with the following command:
% data = Datapixx('ReadMicrophoneBuffer', nFrames);
% Instead, we are to tell the audio output system to playback directly from the acquisition buffer!
Datapixx('SetAudioVolume', 0.25); % Not too loud
Datapixx('SetAudioSchedule', 0, 48000, nFrames, 3, 0);
Datapixx('StartAudioSchedule');
Datapixx('RegWrRd');
fprintf('Now its PLAYBACK time...\n');
if (exist('OCTAVE_VERSION'))
fflush(stdout);
end
% We'll wait around until the playback has completed.
endDemo = 0;
while(1)
Datapixx('RegWrRd');
status = Datapixx('GetAudioStatus');
if (~status.scheduleRunning)
break;
end
% Let an escape during playback also terminate the demo
[keyIsDown, ~, keyCode] = KbCheck;
if (keyIsDown && keyCode(Escape))
Datapixx('StopAudioSchedule');
Datapixx('RegWrRd');
endDemo = 1;
break;
end
end
if (endDemo)
break;
end
end
% Job done
Datapixx('Close');
fprintf('\n\nDemo completed\n\n');
|