LOW LATENCY AUDIO IN MATLAB

Some computers experience long delays when you are trying to play sound in your experiment in MATLAB. This may apply BOTH to eyetracking and non-eyetracking experiments.

The problem (as I understand it) is that playing a sound actually involves two steps:

  1. queuing up the sound in your sound card
  2. starting the audio that's been queued up in your sound card

MATLAB comes with a wavplay function (not part of Psychophysics Toolbox) for Windows machines. wavplay can be used to play sounds. The problem is that wavplay is not very good. It operates slowly. It also forces you to combine steps (1) and (2) above into a single step instead of letting you do (1) in advance. This can lead to long latencies. So, wavplay is not good for playing sounds, especially not when you need accurate timing.

Also, wavplay cannot be used at all on Mac and Linux machines. Your experiment will crash if you try.

To reduce latency and get better timing information, Psychophysics Toolbox introduces a new set of functions for working with sounds. These functions are called PsychPortAudio.

There are two steps to using PsychPortAudio:

  1. Set up your computer with the proper files and drivers: For PCs | For Macs
  2. Edit your experiment in MATLAB to use PsychPortAudio. Instructions for this are below.

PsychPortAudio is only available in Psychophysics Toolbox 3. Psychophysics Toolbox 2 does have an alternative to wavplay called Snd, but it's not as good as PsychPortAudio, and I don't have much experience with it.

Note that all of this applies only to your participant PC—the one that the participant uses while performing the eye-tracking experiment. That's because this is the computer that plays the sound files. The computer that controls the eye-tracker and collects the eye-tracking data has nothing to do with any of this.

Structure of the rest of this page:

TESTING FOR DELAYS

You may want to test the accuracy of your audio stimulus timing in your experiment.

Angie Isaacs recommended using the GetSecs function to test the amount of time it takes wavplay to execute and saving those latencies in a file for later review. To do so, add this code at the start of the experiment:

	outfile = fopen('latencytest.txt', 'w');

In your loop for each trial, to play the sounds:

	[sounddata soundfreq] = wavread(soundfilename);
	t1=GetSecs;
	wavplay(sounddata, soundfreq, 'sync');
	t2=GetSecs;
	latency=t2-t1;
	fprintf(outfile, '%s,%2.4f\n', soundfilename, latency); 

(Ideally, you'll put wavread before the start of your actual trial, so that the time to read your sound file off the hard drive occurs before the trial begins.)

At the end of the experiment:

	fclose(outfile);

When your experiment is done, you will have a file showing the time it took for wavplay to finish playing each of your sound files. Subtract the actual duration of the sound file to find the latency.

After you've testing the timing, you'll probably want to remove these lines of code. There's no sense in running these tests during an actual experimental session.

Once you have set up PsychPortAudio (below), PsychPortAudio also provides its own tests of latency. Those are described below.

PSYCHPORTAUDIO SETUP: PC

If Step Two showed that you have a sizable latency, there are two steps to improving it.

Step One: First, download the ASIO4All driver. (It's free!) Run the file on the PC that the participant uses during the experiment. (In an eye-tracking experiment, this is the computer that the participant is sitting at.)

Step Two: After you've set up the ASIO4All driver, you also need to tell Psychophysics Toolbox how to use the driver.

This is done by downloading a file helpfully provided by the Psychophysics Toolbox people. It comes as a compressed ZIP file. On most computers, you just need to double-click on the file to "unzip" it and get the original file.

When you unzip the ZIP file, you should see a file called portaudio_x86.dll. This is the file that tells Psychophysics Toolbox how to use the ASIO driver. You need to place this in your Psychophysics Toolbox folder. If you're not sure where that folder is, search your computer for Psychtoolbox.

Once portaudio_x86.dll is in place, simply exit MATLAB and restart it. Now Psychophysics Toolbox will be using the ASIO driver.

PSYCHPORTAUDIO SETUP: MAC

If you have a Mac, you already have a set of good sound drivers. But, you do have to set up PsychPortAudio the first time you use it.

This is as simple as copying a file from one folder to another. The file gets downloaded to your computer automatically when you download Psychophysics Toolbox, but you have to copy it into the right place. My understanding is that the reason you have to do it manually is because PTB doesn't have permission to mess with the folder on its own.

So, here is what you need to do:

  1. Go to the folder where you installed Psychophysics Toolbox. (You can search your computer for Psychtoolbox if you don't know where that is.)
  2. Go into the PsychSound folder.
  3. You should see a file here called libportaudio [some numbers & other stuff].
  4. Copy that file.

OK, you have the file. Now you need to put into the right folder:

  1. Double-click on your Macintosh HD on the desktop
  2. Double-click your account name (in my case it's scottfraundorf)
  3. Go into the folder named lib. (If you don't have a folder named lib, pull down the File menu and choose New Folder. Name the new folder lib)
  4. Paste the libportaudio file (from step #4) into the lib folder.

At this point, restart Matlab and you should be good to go.

PLAYING LOW-LATENCY SOUND IN MATLAB

Psychophysics Toolbox 3 introduces PsychPortAudio, a very nice set of functions for playing sound. They have lower latency and provide you with a lot more options than the wavplay function.

You'll first need to set up PsychPortAudio following the instructions above for PC or for Mac. You only need to do that once per machine. Then you can run as many experiments as you want.

At the very start of your experiments, add these lines:

	InitializePsychSound(1);
	pahandle = PsychPortAudio('Open', [], 1, [], FREQUENCY, CHANNELS, [], 0.015);

The first line sets up the sound driver, in general. The second line opens up a sound channel—a line of communication between your experiment and your sound card. (Opening up a sound channel is a lot like creating a screen using the Screen function.)

The rest of the PsychPortAudio('Open') statement controls the exact properties of your sound channel. Most of these you can just leave as I've specified above.

The properties you might want to change are:

To play audio stimuli during your experiment, there are four lines of code. The first line reads the sound file off your hard drive. The second line queues up that sound in your sound card by putting it in the sound card's "buffer." The third line actually starts playing the sound. The fourth line waits until the sound has stopped playing before it continues on. (If you want your experiment to continue while the sound is playing, you can omit this last line.)

	[sounddata soundfreq] = wavread(soundfilename)
	PsychPortAudio('FillBuffer', pahandle, sounddata');
	PsychPortAudio('Play', pahandle);
	PsychPortAudio('Stop', pahandle, 1);

The nice thing about this is it gives you precise timing. You can use the first 2 lines of codes to load the sound file and add it to the buffer BEFORE your trial actually starts up. Then, the call to start playing the sound during your actual trial is very quick, and ensures accurate timing.

(pahandle appears in all of these lines because it's the name of your sound channel; it was set up when you used the PsychPortAudio('Open') statement earlier.)

CAUTION: In the FillBuffer statement, make sure to include the ' after the name of your sound matrix. This transposes the matrix, so that it is in the format that PsychPortAudio expects. If you omit the ', your program will crash when you try to play the sound.

At the end of your experiment, add this line:

	PsychPortAudio('Close');

This closes the sound channel. Don't forget to do this! If you forget to close the sound channel, the next person who uses the computer may not be able to open their own sound channel.

Another thing that you can do is just to put the PsychPortAudio('Close') statement at the start of all your experiments. That will close any sound channels that someone else left open. :)

If you've installed the CogToolbox, that toolbox also comes with a demo of playing (and recording!) sound in Psychophysics Toolbox. To see some sample code, type the following command in MATLAB:

	edit sounddemo

And, you can actually run that demo code by typing:

	sounddemo

CONFIRMING THE FINAL LATENCY

Psychophysics Toolbox automatically runs its own tests of sound latency whenever you start up an experiment that uses sound (at least if you're using PsychPortAudio).

In all the text that scrolls by in the MATLAB command window after you start your experiment, you'll see text that looks like this (the particular numbers may be different):

PTB-INFO: Real samplerate 44100.000000 Hz. Input latency 0.000000 msecs, Output latency 0.000000 msecs.

The number after Output latency is the time it takes to get the sound playing after you request it. If you have a good sound set-up, it can be 0. On other systems, you may see a positive number here (e.g., 39.977324 msecs). That is the time it takes for the sound to actually start playing after your PsychPortAudio('Play') statement.

If you are using wavplay rather than PsychPortAudio, you will not see this number reported.

TROUBLESHOOTING

When you start your experiment, you should see several messages in your MATLAB command window. (This is the window where you type MATLAB commands—the messages do not appear in your actual experiment.)

First, somewhere in the Command Window, you should see a message like:

	Detected an ASIO enhanced PortAudio driver. Good!

If you don't see this, you probably didn't download portaudio_x86.dll, or didn't put it in the correct folder. See Step Two of the PC setup instructions.

You should also see this message somewhere in the Command Window:

	Found at least one ASIO enabled soundcard in your system.

If you don't see any message like this (at all), you probably didn't download and install the ASIO driver. See Step One of the PC setup instructions.

If, instead of the above message, you see a different message that looks like this:

	PTB-Warning: Although using the ASIO enabled Psychtoolbox sound driver,
	PTB-Warning: could not find any ASIO capable soundcard in your system

it means that you did set up the ASIO driver, but it unfortunately doesn't work with your sound card. This is a hardware issue and (unfortunately) I'm not sure how much can be done to improve the latency beyond what your sound card allows. Having the ASIO driver won't hurt you in this case—I think it just gets ignored—but it won't speed up the latency either.

If all of the above messages look normal, but the program crashes at the PsychPortAudio('FillBuffer') statement, you probably forgot the ' to transpose the matrix. See the instructions on using PsychPortAudio.

If the program doesn't crash, but the sound has static in it, try adjusting your latency settings in the PsychPortAudio('Open') statement. Increase the latency until you don't get the static anymore. See the instructions on using PsychPortAudio.