PsychPortAudio asynchronous playback

Hi,

I've been trying to set up an experiment that involves playing a brief
audio file in time with an animation. I have to play the audio file
repeatedly over the course of the experiment (between 200 and 800
times, depending on response times).

I've run into trouble usind wavplay and Snd because of their reliance
on the playsnd function - it fails to write to the sound card after
playing the sound so many times.

In trying to implement the PsychPortAudio functions, I'm running into
trouble because they don't seem to provide synchronous playback - my
animation freezes until the sound has played through.

Using wavplay, I ensured that I was not trying to play a new sound
before the other had time to finish, and was careful to flush the
queue using Snd('Quiet') or Stop.

Any suggestions would be much appreciated!

Thanks,
Liz
Post bits of your code. PsychPortAudio is asynchronous, it will
play in the background while your matlab script executes.

Or do you *want* it to be synchronous?

-mario

--- In psychtoolbox@yahoogroups.com, "liz.arsenault" <liz.arsenault@...> wrote:
>
> Hi,
>
> I've been trying to set up an experiment that involves playing a brief
> audio file in time with an animation. I have to play the audio file
> repeatedly over the course of the experiment (between 200 and 800
> times, depending on response times).
>
> I've run into trouble usind wavplay and Snd because of their reliance
> on the playsnd function - it fails to write to the sound card after
> playing the sound so many times.
>
> In trying to implement the PsychPortAudio functions, I'm running into
> trouble because they don't seem to provide synchronous playback - my
> animation freezes until the sound has played through.
>
> Using wavplay, I ensured that I was not trying to play a new sound
> before the other had time to finish, and was careful to flush the
> queue using Snd('Quiet') or Stop.
>
> Any suggestions would be much appreciated!
>
> Thanks,
> Liz
>
Hi,

Here is a skeleton of the structure I am using to play sounds. I would like them to play asynchronously behind my animation, but using the PsychPortAudio makes the animation jumpy.

leng = 20;      %maximum stimulus display length (seconds)

%Initialize Sound Driver
InitializePsychSound;

for i=1:10     %loop over the various trials
   
    %trials might use different audio files
    [soundFile, freq, nbits] = wavread('ShortClick.wav');
    wavedata    =soundFile';
    nrchannels  =size(wavedata,1);
   
    sound(1) = PsychPortAudio('Open', [], [], 0, freq, nrchannels);
    PsychPortAudio('FillBuffer', sound(1), wavedata);
   
    while answer ~= 13  %adjust using keys[...], end adjustment with "Enter"
   
        %--- DISPLAY STIMULUS ---%
        fr=1;                           %Initialize to frame 1
        t0=getsecs;                     %Start timer
        tw = 0                          %elapsed time
        hasPlayed = 0;                  %Flag for stopping sound  
        soundOnsets = [];               %A row matrix queue of all the times in which the sound file should be played
   
       
        while tw < leng                     %animate while stimulus should be displayed.
           
            %% Compute frame content
           
            if size(soundOnsets > 0)         %are there sounds in the queue?
               if tw >= soundOnsets(1)       %should one be played?
                  t1 = PsychPortAudio('Start', pahandle, 1, 0, 1);
                  hasPlayed = 1;
                  if size(soundOnsets > 1)    %remove played sound from queue
                    soundOnsets = soundOnsets(2:end);
                  else
                    soundOnsets = [];
                  end
               end
            end
           
            %draw frame content
           
            %Listen for a response
                      
            tw=getsecs-t0;                          %Update time
     
            if hasPlayed == 1
                %If this section is excluded, next time I try to play a sound,
                %there is an error saying that PsychPortAudio has already
                %started.
                PsychPortAudio('Stop', pahandle);
                hasPlayed = 0;
            end
        end
    end
   
    PsychPortAudio('Close', sound(1));

end


This looks difficult to read, so I am going to post this m-file in the "Files" section, along with a short example that has an animation.

--- In psychtoolbox@yahoogroups.com, "Mario Kleiner" <mario.kleiner@...> wrote:
>
> Post bits of your code. PsychPortAudio is asynchronous, it will
> play in the background while your matlab script executes.
>
> Or do you *want* it to be synchronous?
>
> -mario
>
> --- In psychtoolbox@yahoogroups.com, "liz.arsenault" liz.arsenault@ wrote:
> >
> > Hi,
> >
> > I've been trying to set up an experiment that involves playing a brief
> > audio file in time with an animation. I have to play the audio file
> > repeatedly over the course of the experiment (between 200 and 800
> > times, depending on response times).
> >
> > I've run into trouble usind wavplay and Snd because of their reliance
> > on the playsnd function - it fails to write to the sound card after
> > playing the sound so many times.
> >
> > In trying to implement the PsychPortAudio functions, I'm running into
> > trouble because they don't seem to provide synchronous playback - my
> > animation freezes until the sound has played through.
> >
> > Using wavplay, I ensured that I was not trying to play a new sound
> > before the other had time to finish, and was careful to flush the
> > queue using Snd('Quiet') or Stop.
> >
> > Any suggestions would be much appreciated!
> >
> > Thanks,
> > Liz
> >
>
Hi,

I would like asynchronous playback, so that it might play in the
"background" while the animation continues. As I've used it,
PsychPortAudio causes the animation to jump, and I didn't have this
problem with wavplay in asynchronous mode.

I've posted two files:
sound_and_structure.m, which shows how I've been using the sound and
sound_and_animation.m, which shows how PsychPortAudio has an effect on
the animation. The first is just so you can see quickly how I've been
usind PsychPortAudio, the second may be run.

Thanks,
Liz

--- In psychtoolbox@yahoogroups.com, "Mario Kleiner"
<mario.kleiner@...> wrote:
>
> Post bits of your code. PsychPortAudio is asynchronous, it will
> play in the background while your matlab script executes.
>
> Or do you *want* it to be synchronous?
>
> -mario
>
> --- In psychtoolbox@yahoogroups.com, "liz.arsenault"
<liz.arsenault@> wrote:
> >
> > Hi,
> >
> > I've been trying to set up an experiment that involves playing a brief
> > audio file in time with an animation. I have to play the audio file
> > repeatedly over the course of the experiment (between 200 and 800
> > times, depending on response times).
> >
> > I've run into trouble usind wavplay and Snd because of their reliance
> > on the playsnd function - it fails to write to the sound card after
> > playing the sound so many times.
> >
> > In trying to implement the PsychPortAudio functions, I'm running into
> > trouble because they don't seem to provide synchronous playback - my
> > animation freezes until the sound has played through.
> >
> > Using wavplay, I ensured that I was not trying to play a new sound
> > before the other had time to finish, and was careful to flush the
> > queue using Snd('Quiet') or Stop.
> >
> > Any suggestions would be much appreciated!
> >
> > Thanks,
> > Liz
> >
>
Ok,

tried to run your demo script but it doesn't run and i'm not bored
enough to fix it. You shouldn't use functions like get_key or
create_window or such that don't exist in PTB if you want anybody
to test run your code. And calling a variable 'sound' is not a
good idea because thats also the name of Matlabs sound() function.

But guessing whats going wrong:

1. Call the PsychPortAudio('Open') function only once at the
beginning of your script, and PsychPortAudio('Close') only once
at the end of your script, not in the trial-loop. Opening/Closing
a sound device can have significant startup overhead and the
first invokation of the 'Play' subfunction may be inaccurate in
timing after 'Open'ing the device, because it could happen that
the operating system only allocates some ressources at first
real start of playback. Its a good idea to emit some useless beep
before the first trial, just to make sure the audio system is fully
initialized before your actual study starts.

2. The last 1 in your call PsychPortAudio('Start', pahandle, 1, 0, 1);
asks the driver to wait (==pause/stall your Matlab script) until
sound playback has really started, i.e. when the first sample of
your sound hits the speakers. Typical onset latency between 'Start'ing
the playback engine and actual start of the sound can easily exceed
30 milliseconds on M$-Windows, so that call may introduce a
stall of multiple video frames. If you set that flag to 0, PA will not
wait until sound onset, but continue immediately with your Matlab
code, like the wavplay command.

But looking at your code i assume you want your sounds to play
at exactly scheduled points in time soundOnsets(i). In that case
you need a different strategy, at least if you need millisecond
precision:

1. Open the sound device with the flag 'reqlatencyclass' == 2 to
tell PA that you want precise, low-latency timing.

2. Tell PA when you want the sound to hit the speaker (true sound
onset):

PsychPortAudio('Start', pahandle, 1, soundOnsets(1), 0);

-> Will ask our driver to schedule sound onset at time
soundOnsets(1). Your script will continue execution
immediately and our driver will try its best to satisfy
the onset deadline.

3. The PsychPortAudio('Stop'); call will actually return the time
of true sound onset, so you can use that to check if timing in
your trial was correct.

4. All this won't work reliably without installation of some
special low-latency driver on your system. Contact me via
e-mail and i'll e-mail you further instructions.

5. Measure! There's no way to make sure that sound onset
is accurate on a specific system configuration than measurement
with photo diode, microphone and oszillograph.
Once you've verified your system setup, you can trust our
driver.

But maybe you want to explain your requirements in more
detail. Audio-Visual studies with exact timing requirements
are a technical minefield, many ways to get it wrong,
only few to get it right.

-mario

--- In psychtoolbox@yahoogroups.com, "liz.arsenault" <liz.arsenault@...> wrote:
>
> Hi,
>
> Here is a skeleton of the structure I am using to play sounds. I would
> like them to play asynchronously behind my animation, but using the
> PsychPortAudio makes the animation jumpy.
>
> leng = 20; %maximum stimulus display length (seconds)
>
> %Initialize Sound Driver
> InitializePsychSound;
>
> for i=1:10 %loop over the various trials
>
> %trials might use different audio files
> [soundFile, freq, nbits] = wavread('ShortClick.wav');
> wavedata =soundFile';
> nrchannels =size(wavedata,1);
>
> sound(1) = PsychPortAudio('Open', [], [], 0, freq, nrchannels);
> PsychPortAudio('FillBuffer', sound(1), wavedata);
>
> while answer ~= 13 %adjust using keys[...], end adjustment with
> "Enter"
>
> %--- DISPLAY STIMULUS ---%
> fr=1; %Initialize to frame 1
> t0=getsecs; %Start timer
> tw = 0 %elapsed time
> hasPlayed = 0; %Flag for stopping sound
> soundOnsets = []; %A row matrix queue of all the
> times in which the sound file should be played
>
>
> while tw < leng %animate while stimulus
> should be displayed.
>
> %% Compute frame content
>
> if size(soundOnsets > 0) %are there sounds in the
> queue?
> if tw >= soundOnsets(1) %should one be played?
> t1 = PsychPortAudio('Start', pahandle, 1, 0, 1);
> hasPlayed = 1;
> if size(soundOnsets > 1) %remove played sound from
> queue
> soundOnsets = soundOnsets(2:end);
> else
> soundOnsets = [];
> end
> end
> end
>
> %draw frame content
>
> %Listen for a response
>
> tw=getsecs-t0; %Update time
>
> if hasPlayed == 1
> %If this section is excluded, next time I try to play a
> sound,
> %there is an error saying that PsychPortAudio has
> already
> %started.
> PsychPortAudio('Stop', pahandle);
> hasPlayed = 0;
> end
> end
> end
>
> PsychPortAudio('Close', sound(1));
>
> end
>
> This looks difficult to read, so I am going to post this m-file in the
> "Files" section, along with a short example that has an animation.
>
> --- In psychtoolbox@yahoogroups.com, "Mario Kleiner" <mario.kleiner@>
> wrote:
> >
> > Post bits of your code. PsychPortAudio is asynchronous, it will
> > play in the background while your matlab script executes.
> >
> > Or do you *want* it to be synchronous?
> >
> > -mario
> >
> > --- In psychtoolbox@yahoogroups.com, "liz.arsenault" liz.arsenault@
> wrote:
> > >
> > > Hi,
> > >
> > > I've been trying to set up an experiment that involves playing a
> brief
> > > audio file in time with an animation. I have to play the audio file
> > > repeatedly over the course of the experiment (between 200 and 800
> > > times, depending on response times).
> > >
> > > I've run into trouble usind wavplay and Snd because of their
> reliance
> > > on the playsnd function - it fails to write to the sound card after
> > > playing the sound so many times.
> > >
> > > In trying to implement the PsychPortAudio functions, I'm running
> into
> > > trouble because they don't seem to provide synchronous playback - my
> > > animation freezes until the sound has played through.
> > >
> > > Using wavplay, I ensured that I was not trying to play a new sound
> > > before the other had time to finish, and was careful to flush the
> > > queue using Snd('Quiet') or Stop.
> > >
> > > Any suggestions would be much appreciated!
> > >
> > > Thanks,
> > > Liz
> > >
> >
>