How to use code component to play audio at t==1?

OS (e.g. Win10): Win 10
PsychoPy version : 2020.2.5
Standard Standalone? y
What are you trying to achieve?:

I’m pretty new to psychopy and python so I only have a basic understanding of coding, and I’m using the Builder. I’m trying to use the code component to play a short sound at 8 different timepoints in a routine without having to add 8 different sound components.

So far, I can get a sound to play ‘properly’ (i.e. once when I want it to) at about 1 seconds, 2 seconds, and 3 seconds after the routine begins if I include this code in the Begin routine tab:

spring = sound.Sound('folder/spring1.wav')
springTime = [60, 120, 180]

and this in the Each Frame tab:

if frameN in springTime:
    spring.play()

However, the timing never quite lines up with the other components which are scheduled to start on a specific second, and I’d like to know how to code sounds and other stimuli to start by seconds instead of frames.

Unfortunately, I haven’t had a lot of luck. For example, I was trying to code the sound to play at 1 second. If I write this into the Each Frame tab:

if t == 1:
    spring.play()

Nothing plays, which I understand is because the frames doesn’t match up perfectly with the time. But, if I do this

if t >= 1:
    spring.play()

then after a second has past, the spring noise starts playing over and over again instead of just playing once.

I’m sure I’m missing something obvious. I’ve tried playing around with the code component and had no luck. I couldn’t reverse engineer an answer from the generated code for the sound component. I’ve tried looking it up, but nothing I’ve found explains how to use the t variable like this.

Can anyone help?

Hi There,

You are very close! But there are a few things to take into account here.

Firstly, t is a float value, and we cannot/shouldn’t test floats for equality in python (because they will never be equal) for this reason we may need to use the >= operator rather than ==.

Secondly, you might want to instead use a clock that restarts at the begining of every trial so replace t with something like nameofroutineClock.getTime().

Third, we only want to initiate the presentation of a sound on a single frame, rather than trying to call .play() on several frames.

So, in your code component you want something like this in your begin experiment/routine tab:

mySound = sound.Sound('folder/spring1.wav.wav')
mySound.started = False
presentationTime = 1

Then in your ‘every frame’ tab use something like:

if myTrialClock.getTime()>1 and mySound.started==False:
    mySound.play()
    mySound.started=True

Then in the end routine tab:
mySound.started=False

Hope this helps,
Becca