Issues playing audio across conditions

OS: X Yosemite
PsychoPy version: 1.85.6
Standard Standalone?: Yes
What are you trying to achieve?: I am trying to design an experiment that presents a series of words while music plays continuously in the background. Within an experimental condition, 4x8 word lists are to be presented to the participant whilst listening to the appropriate audio file. To elaborate, I want a list of 8-words to be presented (each word allocated a window of 3seconds) followed by a break. This break is to allow participants to write down their responses. As such, I require the break to only have one termination option, being that of a button press so the participant is ready to proceed to the next list. Repeating that process 4 times would comprise an experimental condition. The tricky part,however, is enabling audio files to play continuously whilst the word lists and breaks are presented. Further, still, I wish to replicate this framework of 4x8 word lists 3 more times, the only difference being a change in audio-file after the 4th,8th,12th break.

**What did you try to make it work?: I’m fairly new to coding and Pyschopy so my efforts thus far may seem rather minimal. However, I have made limited progress. Within the builder view, I have managed to achieve sequential word list presentation via connection of an excel file in the loop component. Repeating this 16 times in separate routines sets up the text element of my experiment. I have also tried designing one routine to equate to one condition.

**What specifically went wrong when you tried that?: The issue with having 16 routines is a fairly obvious one, the music is fragmented upon each routine transition. Additionally, due to the break termination being indiscriminate it’s impossible to put start and stop values that would be universal for particpant progression rates. The singular approach of having 32 words in one word routine is problematic due to the words not progressing through the list concurrent with the audio-file. Rather, one word is presented for say 3 seconds with the music playing and then dissapears; leaving a blank screen with just the music playing. Additionally with that approach, I cannot insert the indefinite breaks after the 8th, 16th, 24th word etc.

I do believe that the result I want can only be achieved via some coding. However, since I am a novice in coding if anyone has an example solution please do take me through it step by step.

Thanks advance,

Andrew Giles

Hi Andrew,

From what you describe, you really only need one routine. It’s a bit clumsy, but I’d put eight text stimuli on that routine, one presented from 0-3 s, one from 3-6 s, etc. Your conditions file would have 8 columns (one for each word) and 4 rows (one for each trial in a condition).

What you also need is two nested loops surrounding that routine. Search this forum for “nested loops” to see how it is done.

You will have noticed that the conditions file is enough for only four trials. So what you need to do is use a new conditions file for each subsequent condition (i.e. you have four conditions files with the same layout). The outer loop is responsible for cycling through those conditions files.

i.e. the conditions file for the outer loop (there is just one) has two columns: one containing the name of the conditions file for the inner loop dialog to use, and the second containing the name of the sound file for this condition. i.e. this conditions file is two columns Ă— four rows.

The issue with the sound is that Builder tidies up at the end of each routine by terminating any sounds that are playing. You can get around this by playing the sound via a small snippet of code in a code component. Builder isn’t aware of the sound playing, so it won’t stop it at the end of a routine.

e.g. insert a code component on your trial routine. In the “begin experiment” tab, put something like this to create a sound object we can refer to later:

audio = sound.Sound()

In the “Begin routine” tab, put something like this, so a sound file will be played but only if it is the first (i.e. zeroth) iteration of the loop. I’m using “sound_name” here to refer to whatever variable name you use in your outer conditions file to refer to the sound:

if your_inner_loop_name.thisN == 0 # on the first trial of a condition
    audio.setSound(sound_name)
    audio.play()

Hey Michael,

Thank you for the swift response, I will try and implement what you have suggested. One thing I forgot to mention, for the 4x8 lists x4conditions has a source list of a 128 unique words. This is is so the participant only sees the 128 words a total of once come the end of the experiment. Would that cause much alteration to your suggestion or would it be as simple as having 128 columns for my conditions file?

Andrew

Very likely. These sorts of “details” are very important to describe. “4x8 word lists are to be presented to the participant.” is a very different situation to “4 sets of 8 words selected without replacement from a list of 128”. At this stage, I’m reluctant to attempt to say how to implement what you need without a very precise description of the design.

Think “what level of detail would I need to give in the method section of a paper or thesis so that the reader was left with no ambiguity as to the experimental procedure?”

You need to get your head around the structure of a conditions file. Each row represents info available to one iteration of a loop. Each column represents a different variable needed on that iteration. So if you have 128 columns, then you would have only one trial but with somehow 128 variables specified within it, which is almost certainly not what you are after. What one is generally striving for is a relatively small number of columns (i.e. variables), and the number of rows equivalent to the number of loop iterations sought (often, this corresponds to the number of trials, but not always).

Your case might be tricky to implement with a single conditions file of 128 rows, but we’ll see what way to go when you have described the procedure precisely.

My apologies for the lack of clarity, I will outline the intended experimental procedure in full below.

Essentially I am conducting a serial-recall task with accompanying music(audio). The serial-recall task proceeds as follows. Participants will be presented on screen with a total of 128 unique words (I currently have an excel file containing these 128 words). These 128 words are to be presented individually on screen (3 seconds per word) in groupings of 8 to the participant; thus participants will be presented with a total of 16 lists come the end of the experiment. After each 8-word list (3s per word x 8 =24s per list), there should be a blank screen break that allows participants to write down (with pen/paper) the words they have just seen in serial order. The termination of these breaks should be associated with a button press, as the time to write down responses will most likely vary due to individual differences. Once a break is terminated, the next list is presented. These 16 lists will be divided by 4 to allocate an equal amount of lists to each condition. The experimental manipulations are that of the audio files that play concurrently with the conditions. For example, one condition would comprise of 4 lists (32 unique words total) and 4 breaks being presented (additionally 4 button presses by the participant to advance to the subsequent lists). The appropriate audio file would span the duration of the condition; essentially playing continuously until the 4th break in the condition is terminated by the participant. The termination of the fourth break would indicate the end of the condition. Upon this termination, the next condition would begin. The subsequent conditions follow the same framework as the previous, the only difference being the words within the 4 lists and the background audio file playing.

One last aspect I was curious about is the order in which these 128 words are presented in. Ideally, I would like the words to be presented in a random order for each participant; this is to avoid any priming affect word order might have on participant recall. By being random, all participants would still be exposed to the same lexical content yet in varying orders.

I do believe that is every aspect of the experimental design. Apologies if I repeated myself.

All the best,

Andrew

Hi Andrew,

That is excellent.

Yes, this can actually be done rather simply.

  • You just need a single conditions file with 128 rows. I’m going to assume that the column name for that file is word. Please replace it in the code below with whatever variable name you are actually using.

You need two routines:

  • The first shows the word. Insert a single text component, start time 0 s, duration 3 s. Specify its text value as $word, set to update every repeat

  • The second is for the pause. Insert a keyboard component which is set to force the end of the routine. Add another text component with some sort of instructions if you like.

  • You need to surround both routines with a loop, connected to your 128-row conditions file. Set it to random. I’m going to assume this loop is called trials. Please replace it in the code below with whatever name you are actually using.

On the pause routine, insert a code component. This code in the “Begin routine” tab will ensure that it runs only on the appropriate trials:

# only pause every 8th trial:
if trials.thisN not in range(7, 128, 8): # ie start = 7, stop = 128, step = 8
    continueRoutine = False # immediately shows the next word instead

The sound files have to be handled separately as they don’t change in time with the words, which are ordered randomly. So we should define them in code. Put something like this in the “begin experiment” tab:

# define a list of your sound files:
sound_names = ['sounds/file01.wav','sounds/file02.wav','sounds/file03.wav','sounds/file04.wav']
shuffle(sound_names) # optional, only if you want this order randomised.

audio = sound.Sound() # create a sound object for playing later

On the word-showing routine, insert a code component. This code in its “Begin routine” tab will ensure that a new sound is played, only on the appropriate trials:

# only 4 times during the experiment:
if trials.thisN in range(0, 128, 32): # ie start = 0, stop = 128, step = 32
    current_sound = sound_names.pop() # pop the next one in order off the list
    audio.setSound(current_sound) # update the sound object with it
    audio.play()

# on every trial, record the sound name in the data file:
thisExp.addData('sound', current_sound)

Hey Mike,

Thank you for the detailed instructions and I shall implement them. If there are any issues I will keep you updated but hopefully, there won’t be :slight_smile: Sincerest thanks for taking the time to help me with this.

Thanks again,

Andrew

Just thought I’d say, I have now implemented your instructions and everything works perfectly.

Sincerest thanks,

Andrew

1 Like