Error: Maximum number of simultaneously open audio devices exceeded

I made an auditory version of the continuous temporal expectancy task (CTET; O’Connell et al., 2009), which works perfectly until the 4th trial of the 5th block when the task shuts down and I receive an error in function OpenSlave: Maximum number of simultaneously open audio devices exceeded. The task consists of 4 different audio tones that differ only in regards to frequency (500Hz, 625Hz, 750Hz, 875Hz). The participant looks at a fixation cross while the tones are played, standard tones are 800ms and target tones are 1120ms. When they detect a longer tone duration, they click space. Each block consists of 255 tones, in which 15-18 are target tones. I created the task using Code rather than Builder, so I employed the PTB Sound Class. Below will explain the code for the experiment:

Main Introduction: I create the duration list to determine the duration of each tone and the pitch list to set the tone frequency:

Begin experiment tab:
hits_numb = 0
hit_tracker = False
resp_wind_end = 100000

Begin routine:
#Import packages and ‘shuffle’ function
import random
import numpy as np

#randomize seed
random.seed()

#determining the duration of all 255 stimuli in the block
# Create pre-determined arrays with different number of targets #
row18 = np.array([8,9,10,11,11,12,12,13,13,14,14,14,15,15,15,16,16,16])
row19 = np.array([8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,15,16,16,16])
row20 = np.array([8,8,9,9,10,10,11,11,12,12,12,13,13,13,14,14,15,15,16,16])
row21 = np.array([8,8,8,9,9,9,10,10,10,11,11,12,12,13,13,14,14,15,15,16,16])
row22 = np.array([8,8,8,8,9,9,9,10,10,10,11,11,11,12,12,12,13,13,14,14,15,16])

rowlist = [row18, row19, row20, row21, row22]

# determine the number of targets in block by picking a pre-defined array #
row_roll = random.randint(0,4)
temprow = rowlist[row_roll]
shuffle(temprow)
cumu_temprow = np.cumsum(temprow) - 1 # -1 to shift targets

#create an empty list for final durations of all stimuli
*durlist = np.arange(0,255)0

# add targetpositions to durlist #
for i in range(0,len(cumu_temprow)):

  • durlist[cumu_temprow[i]] = 1*

#insert proper durations into final list (in ms). 800ms for non-targets, 1120ms for targets.
for x in range(0,len(durlist)):

  • if durlist > 0.5:*
  •    durlist[x] = 1105*
    
  • else:*
  •    durlist[x] = 785 *
    

#transform ms to seconds, since psychopy uses seconds as units
durlist = durlist/1000

#keep track of where we are in the durationlist
cur_dur = 0

#check durationlist (only for potential debugging)
print(durlist)

#Array of 255 numbers of just 500, 625, and 750
new_pitch_list = np.repeat([500, 625, 750],85)
random.shuffle(new_pitch_list)
print(new_pitch_list)

#When there is repeating values (e.g., 500 500), replace second value with 875
for x in range(1,len(new_pitch_list)):

  • if(new_pitch_list[x-1] == new_pitch_list):*
  •    new_pitch_list[x] = 875*
    

print(new_pitch_list)

#Counter for new_pitch_list
cur_new = 0

#save ISIs#
thisExp.addData(‘ISIrow’, temprow) # save variable to make calculating ISIs easier

Blocks: Then the task moves onto the blocks. I created an audio tone using the PTB audio device with the following:

Begin Routine:
#Code for playing sound stimuli - this works for one tone only
*snd = sound.backend_ptb.SoundPTB(value=new_pitch_list[cur_new], secs=durlist[cur_dur], stereo=-1, volume=1.0, *

  •                             loops=0, sampleRate=48000, blockSize=4800, *
    
  •                             preBuffer=-1, hamming=True, stopTime=(), *
    
  •                             name='Tone', autoLog=True, syncToWin=None)*
    

snd.play()
core.wait(0)

#Marking the targets and non-targets
if durlist[cur_dur] > 1: #mark targets with 72 and non-targets with 73

  • main_p_port.setData(72)*
  • targ_start_time = gen_timer.getTime()*
  • resp_wind_end = targ_start_time + 1.92*
  • hit_tracker = True*
    else:
  • main_p_port.setData(73)*

# setup timer across trials #
if currentLoop.thisN == 0:

  • gen_timer = core.Clock()*
  • hit_tracker = False*

Each Frame:
*if key_resp.keys == ‘space’:
main_p_port.setData(74) #Send trigger 74: response given
resp_temp_time = gen_timer.getTime()
if resp_wind_end >= resp_temp_time and hit_tracker == True:
hits_numb = hits_numb + 1
hit_tracker = False
elif resp_wind_end < resp_temp_time:
hit_tracker = False
*
End Routine:
thisExp.addData(‘imgdurtest’, durlist[cur_dur]) #save variable to identify targets and non-targets in data
cur_dur = cur_dur + 1 #update where we are in the durationlist
cur_new = cur_new + 1 #update where we are in the new pitch list

The experiment continues through 10 of these blocks. In between each block there is a break screen that is essentially the exact same as the Main Introduction code. The break screen creates the duration and pitch lists for the PTB to create the audio tones.

However, after the beginning of the fifth block (on the 4th trial) the experiment shuts down for an Error in function OpenSlave. It says I am exceeding the maximum amount of audio devices that can be open at one time. I’m guessing this means that during each block I should shut down the PTB function that created the tones during the blocks, but I don’t know how to carry this out.

If someone can help me with this I’d be very grateful!