Skip to main content
Skip table of contents

Streaming continuous audio

In this demo, we take a sound file and stream it continuously to the device.

In this demo, to write the Audio Buffer, we call Datapixx('WriteAudioBuffer', waveData(:,1:nBufferFrames), 0);, which fits as much data as the buffer can take, at address zero.

We create the Audio Schedule for playback, and we write the new frames that were not written yet: Datapixx('WriteAudioBuffer', waveData(:, nextWriteFrame: nextWriteFrame+nStreamFrames-1), -1); the -1 here signifies that we are continuously streaming audio and to continue without changing the address.

function DatapixxAudioStreamDemo(wavFilename)
% DatapixxAudioStreamDemo([wavFilename=funk.wav])
% Demonstrates how to continuously stream an audio waveform to the DATAPixx CODEC.
% Optional argument:
% wavFilename = Name of a .wav sound file to load and play.
%               Otherwise the funk.wav provided with PsychToolbox is used.
% Also see: DatapixxAudioDemo
% History:
% Oct 1, 2009  paa     Written
% Oct 29, 2014 dml     Revised 

AssertOpenGL;   % We use PTB-3

% Get the .wav filename
if nargin < 1
    wavFilename = [];
if isempty(wavFilename)
    wavFilename = [PsychtoolboxRoot 'PsychDemos' filesep 'SoundFiles' filesep 'funk.wav'];

% Load the .wav file
[waveData, freq] = audioread(wavFilename);
waveData = waveData';               % Transpose so that each row has 1 channel
nChannels = size(waveData, 1);
nTotalFrames = size(waveData, 2);

% We'll demonstrate streaming with a 1 second buffer,
% and update the streaming buffer no faster than 100 times per second.
nBufferFrames = freq;
if (nBufferFrames > nTotalFrames)
    nBufferFrames = nTotalFrames;
minStreamFrames = floor(freq / 100);

% Open DATAPixx, and stop any schedules which might already be running
Datapixx('SetAudioVolume', 1.00);    % Not too loud
Datapixx('RegWrRd');    % Synchronize DATAPixx registers to local register cache

% Fill the buffer with as much of the data that fits.
Datapixx('WriteAudioBuffer', waveData(:,1:nBufferFrames), 0);

% Configure the DATAPixx to play the buffer at the correct frequency.
% If the .wav file has a single channel, it will play to both ears in mono mode,
% otherwise it will play in stereo mode.
if (nChannels == 1)
    lrMode = 0;
    lrMode = 3;
Datapixx('SetAudioSchedule', 0, freq, nTotalFrames, lrMode, 0, nBufferFrames);

% Start the playback
Datapixx('RegWrRd');    % Synchronize DATAPixx registers to local register cache

% Continuously feed the streaming buffer until the entire waveform has been played,
% or until a key is pressed.
fprintf('\nWaveform playback starting, press any key to abort.\n');
if (exist('OCTAVE_VERSION'))
nextWriteFrame = nBufferFrames + 1;
nFramesLeft = nTotalFrames - nBufferFrames;
while nFramesLeft > 0
    Datapixx('RegWrRd');   % Update registers for GetAudioStatus
    status = Datapixx('GetAudioStatus');
    if status.freeBufferFrames >= minStreamFrames           % Do not waste CPU time doing millions of tiny buffer updates
        if status.freeBufferFrames >= nFramesLeft           % Stream buffer has room for remainder of the waveform?
            nStreamFrames = nFramesLeft;                    % This iteration will download the remainder of the waveform
            nStreamFrames = status.freeBufferFrames;        % Top off stream buffer with a section of waveform
        Datapixx('WriteAudioBuffer', waveData(:, nextWriteFrame: nextWriteFrame+nStreamFrames-1), -1);    % Download waveData
        nextWriteFrame = nextWriteFrame + nStreamFrames;    % Update for next iteration
        nFramesLeft = nFramesLeft - nStreamFrames;

    % A keypress will immediately abort the schedule
    if (KbCheck)
        Datapixx('RegWrRd');    % Synchronize DATAPixx registers to local register cache

% Show final status of DAC scheduler
fprintf('\nStatus information for audio scheduler:\n');
Datapixx('RegWrRd');   % Update registers for GetAudioStatus

% Job done
fprintf('\nDemo completed\n\n');
JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.