Best way to build an auditory metronome into my experiment


I’m programming an experiment which requires participants to perform a simple choice reaction time task whilst performing a distractor task (foot tapping or articulatory suppression) to the beat of a metronome (100 beats per minute).

I create my experiments in Builder and was originally planning on inserting an audio file of a ticking metronome, but now I think it might be easier & neater to insert a “code component” (Python command) which basically simulates a metronome (100 ticks/beeps per minute) throughout the entire experiment.

Can I get Psychopy to present such a timed sound using python commands? I don’t actually care whether it’s a tick or a beep, etc., as long as it’s 100 beats per minute.

Then ideally I would also be able to suppress the ticking during certain conditions, though is not totally essential (if it just beeps throughout that’s fine too!).

I’d be really grateful for any advice!

You are able to simulate a metronome in the PsychoPy by utilising the psychopy.Sound module and the psychtoolbox. The sound module will allow you to play any sound, or a tone/beep whilst the GetSecs() function from the psychtoolbox will allow you to delay said sound by any amount.

The .play() function from the Sound module does have a parameter of when which can delay the playing of a sound, however this appeared to be inconsistent in my tests which is why I chose to use GetSecs()

For the example I will use this metronome sound, located in the the root project folder sounds\metronome.wav

Here is the basic breakdown of the code component

We assign our desired metronome BPM at the start of the experiment because in this instance, we are not manipulating it on a per-trial basis. Then we use sound.Sound() to create a reference to the locally stored metronome.wav.

Afterwards we use ptb.GetSecs() to return the current real time in seconds and use a conditional if statement to determine if the difference between the last time we obtained the seconds and now exceeds our defined BPM.

If it does, then play the required sound and update the now variable to the most current seconds.

Here is the final result played at 100 BPM

You could modify the if statement to include the and (&&) operator for a boolean shouldPlayMetronome variable to suppress the ticking during conditions

Hi @Juris_S, Thank you so much for this extremely helpful suggestion. This is EXACTLY the sort of thing I was after. However when I enter your code into my experiment it does not like the last bit under “Each frame” - Specifically the first line - Is there a typo in there? (Should the square bracket be there?). PsychoPy3 says “/* Syntax Error: Fix Python code */” for that line. Any further help appreciated but thanks again for much for this advice.

Hi @Arturo ,

Yes there’s a typo in the each frame section, the ] bracket should actually be greater than sign to create the >= operator. Here is what it should look like:

Which falls in line with the described logic of:

if the difference between the last time we obtained the seconds and now exceeds our defined BPM.

Amazing. It now doesn’t give the syntax error (thank you!) but it still won’t work (in an otherwise fully working experiment). I wonder what’s wrong. Could it be something to do with the sound settings? Or do I need to enable to psychtoolbox or download it somehow? Where does it get the metronome.wav file from…?
Thanks again so much for your super helpful suggestion, I feel like I’m so close…!

OK, so I think it’s an issue with the soundfile, as I’m (sort of) able to get it working if I use one of my own .wav files!

Hi @Arturo,

What I gather from your responses is that you are new to PsychoPy, in that case I would really recommend you look at the Getting Started page then coder tutorials so you can get a feel for the application.

I have provided the metronome.wav file which can be simply downloaded from this post by pressing the triple dots.


If you’re copy/pasting the code this .wav file would need to be placed in a folder called Sounds located in the root directory of your project (by default this folder doesn’t exist so you’ll have to create it)

Thanks very much for your help. I’ve programmed a couple of experiment in PsychoPy before but I’m useless with inserting bits of code…! (I mostly use Builder) Thanks for the link to the coder tutorials!

I did get it to work although it only played the sound file during the initial instruction screen; when I then enter my trial loop it stopped (I need it to play all the way through the whole experiment).

I also seem to be having some weird issue where sometimes the experiment will run, and sometimes it won’t (after I enter the subject number, it immediately exits the experiment but does not give an error message). This must be a different problem I guess.

Anyway, thanks very much for your help, it’s much appreciated!

@Juris_S I think it’s all fixed and working now!

I couldn’t find a way to play the metronome continuously throughout the experiment from beginning to end, but if I place your code within the trial loop it plays the metronome for the duration of the trial loop, which is really all I need.

I also moved the code from “begin routine” to “begin experiment”, because I didn’t want to metronome to restart with every trial (I want it to play continuously).

I’m really pleased it’s working now, thanks so much again for your help.

Update: To anyone else experiencing this issue, I fixed it by copying my metronome code into each routine separately. I’m sure there must be a smarter way, but this seems to work.

Hi @Juris_S,
I have noticed that when my experiment is more complex (with multiple routines in the trial loop), my metronome code doesn’t work as it seems to want to start and stop with every routine.
At the moment, I have inserted the code in the routine for my instruction screen (before the trial loop starts), but I would like the metronome to keep playing throughout the whole experiment, and not stop/start with each routine.
Is there a piece of code I can insert to achieve that?
Any tips gratefully received