| Reference | Downloads | Github

Presentation of a sound in a random trial


Hello, guys!

I am new to PsychoPy and I will appreciate any help with my issue. My PsychoPy version is 1.85.2 on Macbook Air with OS 10.13.1

I am trying to make a sound presented at a random moment during a set of trials (and only once during this set). The set of trials is a sequence of 6 different positions of the stimuli and correct responses, which should be repeated every time but the sound should be playing in a random position of a stimuli.

It looks like this: I have a Routine with stimuli, which has a loop around it to define (with xlsx file) this set of trials.

I do not understand how to make a sound be random and in the same time control that it will be just once in the set of trials.

Thank you


This will likely require you to insert a code component and use a little Python code to add the control that you need. This could be as simple as choosing a random number between 0 and 5 at the beginning of the loop. On each subsequent trial, you check to see if the current trial number equals that value, and if so, play the sound. e.g. put something like this in the “Begin routine” tab of that code component:

if your_loop_name.thisN == 0: # only on the first trial:
    sound_trial_number = randint(low = 0, high = 6) # actually gives a value between 0 and 5

# record this in the data file on the appropriate trial number:
if your_loop_name.thisN == sound_trial_number:
    thisExp.addData('sound_trial_number', sound_trial_number)
    thisExp.addData('sound_trial_number', None)

Then in your sound component, you could put something like this in the volume field to check for a match with the current trial number:

your_loop_name.thisN == sound_trial_number

This boolean comparison results in a volume of 0 when the two numbers are different and 1 when they are the same.


Thank you Michael for the response and solution! It did work, but the issue is that the sound can be repeated few times within the loop or being not presented at all within the loop and I need it be only once per loop.


Sorry, I left a line out of the code that would restrict the selection of the number to only once per loop (I’d put an explanatory comment in there to that effect but left the actual code line out). I’ve edited the code above accordingly. This should ensure that only one number is chosen, which remains in effect for all of the trials within that loop. Hence you should always get exactly one trial with a sound.

Have also amended the data recording code so that the selected sound number is only recorded on the matching trial, which might or might not be what you want from an analysis point of view.


Extend above: Present text (rather than sound) in a random trial. For an “attentional test”.

Thank you Michael for answering this post which has helped me do what I want to do. However, the solution I have made to my problem is VERY clunky. Is there a better way to do what I want?

I want to: Present text (superimposed on image) in a random trial. So rather than sound, as used above, I want a letter to appear. I have done the same as above, and then just included the code below. This works. But is this a “bad way” to get this result?

if your_loop_name.thisN == sound_trial_number:
    text = visual.TextStim(win=win, name='text',
        text=u'hello I am text\n\n',
        pos=(0, 0), height=0.1, wrapWidth=None, ori=0, 
        color=u'red', colorSpace='rgb', opacity=1.0,
    text = visual.TextStim(win=win, name='text',
        pos=(0, 0), height=0.1, wrapWidth=None, ori=0, 
        color=u'red', colorSpace='rgb', opacity=0.0,

My question is: why doesn’t it work when I put:

your_loop_name.thisN == sound_trial_number

into the Opacity field of my text object? How come my text still appears? I have set text and Opacity to ‘each repeat’.

Many thanks, again for the original post. I’m mostly posting in case anyone else is also trying to use Text randomly presented at some point.

Cheers, Kirsten.


Creating text stimuli is time-expensive. You shouldn’t do that repeatedly. Just do it once (at the start of the experiment, for example), and in the code above you would just do this (i.e. just update the opacity value, don’t recreate the entire stimulus from scratch):

if your_loop_name.thisN == sound_trial_number:
    text.opacity = 1.0
    text.opacity = 0.0

Why doesn’t your expression your_loop_name.thisN == sound_trial_number in the opacity field of text component work? I don’t know, it should (and would indeed be easier than the code-based approach). We probably need to see some relevant screenshots to figure out why it isn’t working.