All too often, I see researchers carefully defining presentation times of stimuli in milliseconds, but programming a script that fails to deliver these exact timings. For example, if you try to present something for a duration of 35 ms it is likely to actually last for 50 ms.
Here’s a general introduction on how to get it right, no matter if you use PsychoPy, E-Prime, Presentation, PsychToolbox or something else. Examples of good code is provided using PsychoPy.
While this introduction is conceptual, you can see it fleshed out in code here.
General considerations
Don’t trust the software timings. Measure physical timing! If your experiment depends on precise timing, it is always a good idea to test it. Not just by the software’s internal timing function but actually measuring the output (visual, auditive etc.). The software often doesn’t have access to delays caused by low-level buffers and hardware.
Program for poor computers: Program your experiment like it should run on a 20-year-old computer. This means that all initializations and calculations (also stuff as simple as angle=[a*sin(b), a*cos(b)] ) should be done before the trial starts, so that the only processing required during the timing-critical period is the presentation of pre-generated stimuli.
Jitter is worse than latency: First and foremost, you want to eliminate jitter in timing. Secondly, you can pay attention to latency. If latency is constant, you can easily correct for it, either in your experiment or in the analysis of it. However, if there is an unintended jitter (i.e. a variable latency), you have a serious source of noise that could mask the effect you are looking for. So don’t panic if you see a constant latency of your stimuli relative to a trigger. Do panic if you see jitter 😉
Use dedicated hardware and updated drivers: Always use dedicated (as opposed to on-board) hardware for stimulus delivery. A sound card for audio delivery and a graphics card for visual presentation. This means that, in general, you should not use a laptop for stimulus delivery. Also, install the newest drivers from the hardware vendor’s website. Microsoft Windows often provide out-of-date drivers.
Visual timing
Visual timing is discrete, not continuous … and you can only present visual stimuli at these discrete timesteps. The primary concern about visual timing is synchronization with the monitor refresh rate. Usually, monitors have a refresh rate of 60 Hz, meaning that they show 60 “images” each second. So for 60 Hz, pick one of the following presentation times – and nothing in between:
- 16.667 ms
- 33.333 ms
- 50.000 ms
- 67.667 ms
… and so forth. On a 60 Hz monitor you simply cannot present anything in between, e.g. at 40 ms. You have to choose between 33.333 or 50ms. Likewise, if you run your experiment on a 85 Hz monitor, you have a different set of times for visual presentations. More generally, visual timing is discrete, not continuous.
Think in frames instead of milliseconds: it follows that milliseconds is a very bad way of timing visual stimuli, because milliseconds makes us think of timing as a continuum. You should rather think about timing in the measure of “frames” (“number of monitor refreshes”). So rather than “stimDuration = 50 ms”, you should do “stimDuration = 3 frames”.
It is very unfortunate that most stimulus delivery software (Presentation, E-Prime, Cogent etc.) use milliseconds as their primary unit of timing, because people many people are then unaware that the stimulus was actually presented for a longer/shorter duration than the experimenter specified when programming the script. There is no difference between the actual stimulus duration (50 ms) if you specify 35 ms and 48 ms in the script. Similarly one might be overly surprised that people were able to detect a difference between 48 ms and 52 ms (shown at 50 ms and 67 ms). Another problem is that if you specify that you want to present something e.g. every 40 ms it would show up on frame 3 (after 50 ms), 5 (33 ms later), 8 (50 ms later) and so on.
Thinking in frames solves these kinds of issues. To my knowledge, PsychoPy is the stimulus presentation software that most explicitly allows you to use frames rather than milliseconds for timing. It does, however, require that your graphics card and drivers support vertical synchronization, often called V-sync.
Location of the screen matters (for the pedantic): if you want to be REALLY in control of visual timing, you should consider where you present the stimuli on the screen. Both CRTs and LCDs update the display from the top towards the bottom. This process can take anywhere up to 17 ms, meaning that the vertical center point is updated up to 8.5 ms after the monitor updating begins. So keep stimuli at the same horizontal level if you want consistent timing! Also, many monitors take 2-5 ms to change from black to white, so the onset is actually not a discrete event but a gradual fading.
These things will automatically be clear to you when you do use a photodiode to test timing between actual display and some signal, e.g. a parallel port trigger.
Audio timing
In contrast to visual timing, audio timing can be thought of as continuous, since it is normally delivered at 44100 Hz or above. However, there are hardware obstacles to be overcome.
Use the sound card output: many modern computers have poor on-board audio cards that is a major cause of jitter and latency compared to dedicated audiocards. I’ve seen EEG experiments almost destroyed by the fact that headphones were plugged into the front of the cabinet (output of on-board audio) instead of the back of the cabinet (output of dedicated audio).
Tweak audio card settings: if possible, experiment with reducing buffer size and enable other precision options.
Use hardware acceleration: in some software (e.g. Presentation) you can enable hardware acceleration of audio. This is preferred to software acceleration.
Trigger timing
Trigger timing of the parallel port is difficult to assess since triggers are used as the reference for timing. However, you can assess consistency by measuring the duration between triggers. You can do this by sending triggers at e.g. 129 ms intervals and check the precision of this interval. I have found that it is very precise, with a jitter is below 0.5 ms across stimulus delivery software (E-Prime, Presentation, PsychoPy). So in general, you need not worry about trigger timing.
SynchRonizing events
Say you want to show an image, play a sound and send a trigger at the same time. How do you do that? I would suggest the following procedure:
- Draw visual stimulus to buffer. Wait for monitor update. It is self-evident that the monitor update should be the first step. The last two steps probably execute within a millisecond whereas if the monitor output was sent after any of the two, it could be delayed by up to 16 ms.
- On update, send trigger and log time to keep the trigger close to visual stimulus. The trigger/log is essential and we don’t want the assessment of the visual timing to be contaminated by a possible small delay incurred by the initiation of the sound.
- Play sound.
If you just present sounds, go with
- Play sound.
- Send trigger and log time.
Once again, if millisecond timing is critical to your experiment then assess the physical delivery of the stimuli and tweak your script/system to optimize that.
Pingback: Playing sound with low latency and jitter in OpenSesame - Ondřej HavlíčekOndřej Havlíček