Low latency sound with winsound

Hey all,

I’ve been struggling to find a low latency sound solution under Windows 7 for some time now. I would like to share the current approach with winsound, though I have to test it with an oscilloscope in the coming days. Also we need to look, if the sound quality and sound length is ok.

I’m loading the wave file to memory before playing it, instead of playing it from a file. It’s not possible to play it asynchronously, when loading from memory, so I use threading instead… (thanks for the hint Jon)

the code may be useful for some of you:


import threading

with open(startle_sound_file, 'rb') as f:
    startle_sound_str = f.read()

def sendTrigger(code):
   p_port.setData(code)
   core.wait(0.1)
   p_port.setData(0)

thread_play = threading.Thread(target=winsound.PlaySound, args=(startle_sound_str, winsound.SND_MEMORY,)) 

thread_play.start()
sendTrigger(255)

Best wishes
Piotr

1 Like

Thanks! I also used winsound on Windows, packing it into a class that mimics psychopy.sound.Sound. See https://github.com/lindeloev/psychopy-course/blob/master/ppc.py. It plays with around 2ms latency on the systems I’ve checked but on one other system, it did terribly (30 ms latency and then 20 ms jitter on top of that).

It’s clever that you load the file beforehand. I should do that as well.

I’m told that the timing is bad on Windows 10, but I haven’t tested it myself. Apparently, Windows 10 choose not to have a super-low-latency no-equalizer audio backend for system sound :slight_smile:

I tested winsound with an oscilloscope and would be very careful about using winsound with the SND_ASYNC flag. My sound of 50ms is cut to 33ms, when I’m using this mode. winsound just plays 33ms of the 50 ms. The sound seemed to be strange, but just saw it with the oscilloscope.

I don’t know about other sound cards, but it’s probably better to start a new thread to play the sound, instead of using the SND_ASYNC flag.

1 Like