Latency of sound file is not consistent across trials

1,049 views
Skip to first unread message

qzhever

unread,
Mar 1, 2013, 12:28:52 AM3/1/13
to psychop...@googlegroups.com
Hello,

I am trying to present short sound files at precise timing for an EEG experiment. I used an oscilloscope to test the timing and saw the sound always started after the EEG trigger, which actually should have occurred simultaneously. It is the first auditory experiment I am creating in Psychopy!

For each trial in the loop, I used the following script to load and play a sound file (file varies across trials):
######################################################
filename=('Stimuli'+os.path.sep+'%s.wav'%(thisTrial.sound))
trialClock=core.Clock()
t = 0
trialClock.reset()  # clock
frameN = -1

stimuli.setSound(filename) # stimuli are pre-recorded .wav files
if t > 0 and stimuli.status == NOT_STARTED:
          stimuli.play()
          stimuli.tStart = t  # underestimates by a little under one frame
          stimuli.frameNStart = frameN  # exact frame index
          sendEEGTrig(int(thisTrial.eventCode)) # send EEG trigger
elif stimuli.status == STARTED and t >= 0.5:
          stimuli.stop()
######################################################
I am using psychopy 1.76.00 on windows7.

I heard the latency problem can be largely fixed by playing the sound from ASIO4all drive. I have installed ASIO4all drive on windows7. This may sound really naive... But how do I use ASIO in psychopy? I noticed a number of discussion threads on the google group about using pyo. How to use these functions to improve the precision of timing?

Any suggestions will be greatly appreciated!!

Thank you!

Zhenghan

Sol Simpson

unread,
Mar 1, 2013, 8:10:06 AM3/1/13
to psychop...@googlegroups.com
Regarding the ASIO4all question, be sure to check out the projects FAQ: http://tippach.business.t-online.de/asio4all/faq.html

Basically, ASIO4all will only really improve things if your underlying sound card supports ASIO and you have enabled it in the sound cards control panel / configuration settings. If your hardware is not ASIO compliant or ASIO has not been enabled / configured, ASIO4all will not improve 'anything'.

Also note that for ASIO in general, what it does is make playback timing more deterministic, but there is still going to be a delay in playing the sound based on the msec buffer size you set for the ASIO device in its settings. What ASIO will do is make the range of this delay be ~ +/- 1 msec of the msec buffer size the ASIO device is set at. So this way you can add a 'known' delay to the audio start time based on when the sound was requested to start. So to sync the sound with another event, start the sound x msec before the other event, where x is the msec buffer size set for the ASIO device. From my experience using ASIO with several Sound Blaster cards that are all probably 5-9 years old now, setting the buffer size to < 4 msec will result in unstable results and not achieve the whole point of things. Using 4 - 10 msec buffer size (or higher) always seemed to work well.  

I do not have any experience with pyo, sorry.

Sol

He Jibo

unread,
Mar 1, 2013, 9:03:40 AM3/1/13
to psychop...@googlegroups.com
原来你也在用psychopy和python,非常告诉。最近学习工作如何?

---------------------------
He Jibo
Assistant Professor
Department of Psychology,
Wichita State University
website: www.hejibo.info



--
You received this message because you are subscribed to the Google Groups "psychopy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to psychopy-user...@googlegroups.com.
To post to this group, send email to psychop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/psychopy-users/-/Esz7lFdyevUJ.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

qzhever

unread,
Mar 1, 2013, 9:44:10 AM3/1/13
to psychop...@googlegroups.com
Thank you so much, Sol! I will take a look at the ASIO setting in the lab computer and try different buffer size.
 

The pyo-related thread I saw is this one: https://groups.google.com/forum/#!msg/psychopy-dev/6pWD_aCEJks/NaWR7J8YS1oJ

Zhenghan QI

unread,
Mar 1, 2013, 9:16:19 PM3/1/13
to psychop...@googlegroups.com
Hello, Sol,

Did you do anything different in your psychopy script for playing audio sound when using ASIO4all? I installed ASIO4all and changed the buffer offset to 10 ms for my external sound card on ASIO4all control panel. However, the latency between my trigger and the onset of my sound is still way above 10 ms. It is also inconsistent, between 70-100 ms.

Thanks so much!

Zhenghan


--
You received this message because you are subscribed to the Google Groups "psychopy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to psychopy-user...@googlegroups.com.
To post to this group, send email to psychop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msg/psychopy-users/-/WFs3pXTMUiAJ.

For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Zhenghan Qi, Ph.D.
Postdoctoral Researcher
McGovern Institute for Brain Research at MIT
Office: 46 - 5081
Tel: 617-324-4959
web.mit.edu/zqi/www

qzhever

unread,
Mar 1, 2013, 9:53:27 PM3/1/13
to psychop...@googlegroups.com, z...@mit.edu
Hello,

Sorry that I am starting a new thread by asking a more general question following the previous discussion about latency.

I just remembered I asked how to log the onset of sound files a few months ago.

Here is what Jon told me:

"For sounds, however, you should be warned that PsychoPy is not using a
low-latency sound driver at the moment. It's just using pygame which
gives lags of 30ms and there's no way for psychopy to be able to tell
how much lag occurred on the presentation. So any logged values used in
this way will be quite rough.

We are working on better sound latencies, but even then they're likely
to be heavily system-dependent. "

Is it still true? Can I force Psychopy to use ASIO4all?

If there are any psychopy users who have succeeded in presenting sound stimuli with precise timing, do you mind sharing your sample script?

Thanks so much!

Zhenghan

Sol Simpson

unread,
Mar 2, 2013, 6:47:18 AM3/2/13
to psychop...@googlegroups.com
My comments were related to ASIO4all and ASIO in general since you asked about ASIO4all. I do not think psychopy uses ASIO4all internally, so if you want to use it you would need to do so using non psychopy API code. When I used / developed with ASIO functionality it was for a different python project. Sorry for any confusion.

Sol Simpson

unread,
Mar 2, 2013, 7:06:46 AM3/2/13
to psychop...@googlegroups.com
After looking at the 2011 post you provided the link to and reading it from be start of the thread, it seems that you can use pyo to access the ASIO4all backend. Since the latest psychopy can use pyo for sound, then it makes sense to check that you have also told psychopy to use pyo in your script. Then do what is needed to get pyo to use ASIO4all. Perhaps someone familiar with the pyo psychopy integration could chime in and give pointers on how to do this. I recall posts recently about how to enable pyo as the sound server, so maybe try searching the group posts too.

Thanks again,

Sol

Jonathan Peirce

unread,
Mar 3, 2013, 12:47:04 PM3/3/13
to psychop...@googlegroups.com
ASIO4ALL can be used from the pyo library, which PsychoPy supports as of
version 1.76.00.

1. Download and install the full 1.76.00 standalone installer
2. pygame is still set as the default sound library because I've only
just added the code so support pyo and I'm not sure if it will break
things yet. To set pyo as the preferred library go to
prefs>general>audioLib and change ['pygame','pyo'] to be the other way
around (this is setting the order in which the libs are searched for).
3. the pyo lib can support multiple different devices and drivers on
your machine (like ASIO and DirectSound). The order in which you try
these is controlled by prefs>general>audioLib. To find out which ones
pyo has identified you can do this

import pyo
print pyo.pa_get_output_devices()

I'd recommend trying out different options (by putting them first in the
prefs list). Note that you'll probably see one that says something like
"Primary Sound". That means the DirectSound driver that's built in to
windows. Note that ASIO4ALL is not the same as ASIO itself, and
according to the psychtoolbox forum it can be pretty flaky. You may want
to get yourself a genuine ASIO sound card. I haven't done this yet
myself, and bear in mind that you're exploring new territories at the
moment!

Jon
--
Jonathan Peirce
Nottingham Visual Neuroscience

http://www.peirce.org.uk/

Sol Simpson

unread,
Mar 3, 2013, 8:37:26 PM3/3/13
to psychop...@googlegroups.com
If anyone is looking for an in production ASIO supported sound card, check out EM-U, which is a sub division of sound blaster. Sound blaster branded sound cards do not support ASIO anymore as far as I know, it has been like that for several years now. The, likely more expensive, EM-U line of cards still seem to support it though.

Zhenghan QI

unread,
Mar 4, 2013, 7:05:41 PM3/4/13
to psychop...@googlegroups.com
Hi,

Thanks very much to Jon and Sol for the suggestions! We have a Roland Edirol UA-25EX, which supports ASIO driver. I did what Jon suggested and added the following lines to my script:
import pyo # for audio files
print pyo.pa_get_output_devices()
# Display (['Built-in Output', 'EDIROL UA-25EX'], [2, 3])
s = pyo.Server(sr=44100,nchnls=2, duplex=0)
s.setOutputDevice(3)


I ran my script in Psychopy1.76.0 on a MacOSX 10.7.5. One problem I noticed is that the volume from left and right ears are not the same, which does not happen in Psychopy1.75. I tested the same code with and without the additional lines in version 1.75 and the sound volume was the same from both ears. Is it something that happened to other users? I will test the latency tomorrow using the oscilloscope.

By the way, what is the recommended buffersize for the pyo.Server function?

Thanks a lot!

Zhenghan




--
You received this message because you are subscribed to a topic in the Google Groups "psychopy-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/psychopy-users/ZPdusXWPB_A/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to psychopy-users+unsubscribe@googlegroups.com.
To post to this group, send email to psychopy-users@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Jonathan Peirce

unread,
Mar 5, 2013, 4:06:08 AM3/5/13
to psychop...@googlegroups.com
So in your prefs for psychopy you've set
    audioLib=['pyo','pygame']
    audioDriver=['EDIROL UA-25EX']
for psychopy's sound to use that device.

No idea why there would be a difference in volume between the speakers I'm afraid.

You should play around with the buffer size. Smaller should give lower latencies but at some point you might find the sound gets 'choppy' it fails to come back and re-fill the buffer before it has run out. As I say, this is largely untested and is likely to be heavily system dependent.

Jon
To unsubscribe from this group and all its topics, send an email to psychopy-user...@googlegroups.com.
To post to this group, send email to psychop...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.





--
Zhenghan Qi, Ph.D.
Postdoctoral Researcher
McGovern Institute for Brain Research at MIT
Office: 46 - 5081
Tel: 617-324-4959
web.mit.edu/zqi/www
--
You received this message because you are subscribed to the Google Groups "psychopy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to psychopy-user...@googlegroups.com.
To post to this group, send email to psychop...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.
 
 

-- 
Jonathan Peirce
Nottingham Visual Neuroscience

http://www.peirce.org.uk/

Zhenghan QI

unread,
Mar 5, 2013, 2:41:42 PM3/5/13
to psychop...@googlegroups.com
Thank you, Jon!

Yes, I did change the order of audiodrive and audiolib in the preference setting. I realized yesterday I did not use s.start() to even start the sound server. My original script still use sound.play() for delivering sound stimuli. I made the corresponding changes in the script and tried to run through the whole experiment again. But I saw the following problems in the Output and there was no sound at all.

Input AudioDeviceStart failed 560227702.
Error starting server
Input AudioDeviceRemoveIOProc failed 560227702
Error closing audio backend.

I tested the same codes in Shell and it did give me sound output (still has the issue of unbalanced volume though). There weren't any errors regarding starting and stopping sound server.

I am pasting the relevant psychopy codes here. Is there anything I am doing wrong?

Thank you so much for your time and patience! I realize the sound presentation functions in psychopy may be still in development. I am just wondering whether I am experiencing some problems developers have seen before.

Thanks!

Zhenghan
===============
import pyo# for audio files
print pyo.pa_get_output_devices()
#(['Built-in Output', 'EDIROL UA-25EX'], [2, 3])
print pyo.pa_get_input_devices()
#(['Built-in Microphone', 'Built-in Input', 'EDIROL UA-25EX'], [0, 1, 3])
s = pyo.Server().boot()
s.setOutputDevice(3)
s.setInputDevice(0)
print s.getSamplingRate()
#44100.0
print s.getBufferSize()
#256


    #-------Start Routine "trial"-------
    continueRoutine = True
    while continueRoutine:
        # get current time
        t = trialClock.getTime()
        frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
        # update/draw components on each frame
           
        # start/stop sound_1
        if t >= 0.0 and sound_1.status == NOT_STARTED:
            # keep track of start time/frame for later
            sound_1.tStart = t  # underestimates by a little under one frame
            sound_1.frameNStart = frameN  # exact frame index
            runClock.reset()
            s.start()
            snd = ('path-to-wav-file')
            sf = pyo.SfPlayer(snd,speed=1,loop=False).out()
            sound_1starttime = runClock.getTime()
            print sound_1starttime
        elif sound_1.status == STARTED and t >= thisTrial.sentence_dur:
            s.stop()
            sound_1.status == FINISHED

Jon Peirce

unread,
Mar 6, 2013, 4:01:01 AM3/6/13
to psychop...@googlegroups.com
All you need to do is set PsychoPy to use pyo and it will handle starting servers etc for you. 

--
Jonathan Peirce
Reply all
Reply to author
Forward
0 new messages