Microphone does not work in multiple routines

If this template helps then use it. If not then just delete and start from scratch.

OS (e.g. Win10): Win10
PsychoPy version (e.g. 1.84.x): 2022.2.2
Standard Standalone? (y/n) If not then what?: Yes
What are you trying to achieve?: using microphone to record each production in multiple routines

What did you try to make it work?: I was able to record when there was only one routine, but the exp failed as soon as I added in another routine.

What specifically went wrong when you tried that?: When i tried to use the PTB driver, here is the error message that I encountered:

PTB-ERROR: Failed to open audio device 8. PortAudio reports this error: Invalid device
Traceback (most recent call last):
File “C:\Users\labuser\Desktop\hsc_dissertation\production\practice_session\run_psychopy_minimal_working_example_lastrun.py”, line 184, in
q1_mic = sound.microphone.Microphone(
File “C:\Program Files\PsychoPy\lib\site-packages\psychopy\sound\microphone.py”, line 478, in init
self._stream = audio.Stream(
File “C:\Program Files\PsychoPy\lib\site-packages\psychtoolbox\audio.py”, line 97, in init
self.handle = PsychPortAudio(‘Open’, device_id, mode,
Exception: Failed to open PortAudio audio device due to unsupported combination of audio parameters.
Exception ignored in: <function Stream.del at 0x000001F957A7AF70>
Traceback (most recent call last):
File “C:\Program Files\PsychoPy\lib\site-packages\psychtoolbox\audio.py”, line 236, in del
self.close()
File “C:\Program Files\PsychoPy\lib\site-packages\psychtoolbox\audio.py”, line 146, in close
raise err
File “C:\Program Files\PsychoPy\lib\site-packages\psychtoolbox\audio.py”, line 139, in close
PsychPortAudio(‘Close’, self.handle)
AttributeError: ‘Stream’ object has no attribute ‘handle’
################ Experiment ended with exit code 1 [pid:12824] #################

I have encountered similar error as well when I used sounddevice as the driver.

File “C:\Users\labuser\Desktop\hsc_dissertation\production\practice_session\run_psychopy_minimal_working_example_lastrun.py”, line 184, in
q1_mic = sound.microphone.Microphone(
File “C:\Program Files\PsychoPy\lib\site-packages\psychopy\sound\microphone.py”, line 478, in init
self._stream = audio.Stream(
File “C:\Program Files\PsychoPy\lib\site-packages\psychtoolbox\audio.py”, line 97, in init
self.handle = PsychPortAudio(‘Open’, device_id, mode,
Exception: Failed to open PortAudio audio device due to unsupported combination of audio parameters.
Exception ignored in: <function Stream.del at 0x000001697F73CF70>
Traceback (most recent call last):
File “C:\Program Files\PsychoPy\lib\site-packages\psychtoolbox\audio.py”, line 236, in del
self.close()
File “C:\Program Files\PsychoPy\lib\site-packages\psychtoolbox\audio.py”, line 146, in close
raise err
File “C:\Program Files\PsychoPy\lib\site-packages\psychtoolbox\audio.py”, line 139, in close
PsychPortAudio(‘Close’, self.handle)
AttributeError: ‘Stream’ object has no attribute ‘handle’
0.9432 WARNING Monitor specification not found. Creating a temporary one…
################ Experiment ended with exit code 1 [pid:12664] #################

It really does seem to me that somehow PsychoPy cannot open another microphone even though the recording parameters are entirely the same as the first microphone. I have attached my PsychoPy minimal working example below.

working_exp_2022_08_15.zip (101.3 KB)

Any help is appreciated given that I am in a time crunch and I would love to use this recording function for my experiment.

Hello HungShao,

Since the main issue appears to be that PTB cannot get a device with the audio parameters you are using. Try setting your microphone’s sample rate to 44.1KHz under the “Hardware” tab of the microphone component.

Hi @mdc, thank you for the reply. I have set the sampling rate to 44.1 KHZ in the microphone component before and it did not work (when there was only one routine). Turned out the audio interface I am using only allows me to record using sampling rate of 48K. But this worked when there was only one routine.

more update: i was able to switch the sampling rate from 48K to 44.1 in the audio interface. I still get the same error about not being able to use the second microphone.

Hi, @mdc . I am having the same issue. Having more than one routine with mic component worked fine using Mac OS, but giving me the error on Windows. I’ve seen people reporting the same issue here and there, but haven’t found any solutions other than having one mic. However, I need to have multiple routines with a mic. Any solutions?

Hi @deh10 unfortunately i don’t think there is a solution yet. I have been trying to debug this. Here is what I have been doing – rather than adding the microphone component in GUI for the second routine, I inserted a code chunk and putting relevant code for the microphone.

While the error in my original post is gone, when I checked the recording, not all sound files were saved. There should be 3 wav files but only 2 were saved. The first production in the first routine did not get saved. I wonder if its due to an error in the code chunk. I am attaching an updated zip folder that contains the working minimal example here.

For the second routine, here is what I added:

At the begin routine:

mic_q1 = sound.microphone.Microphone(
    device=8, channels=1, 
    sampleRateHz=44100, maxRecordingSize=24000.0)

At each frame:

if mic_q1.status == NOT_STARTED and t >= 0.4-frameTolerance:
    # keep track of start time/frame for later
    mic_q1.frameNStart = frameN  # exact frame index
    mic_q1.tStart = t  # local t and not account for scr refresh
    mic_q1.tStartRefresh = tThisFlipGlobal  # on global time
    win.timeOnFlip(mic_q1, 'tStartRefresh')  # time at next scr refresh
    # add timestamp to datafile
    thisExp.addData('mic_q1.started', t)
    # start recording with mic
    mic_q1.start()
    mic_q1.status = STARTED
if mic_q1.status == STARTED:
    # update recorded clip for mic
    mic_q1.poll()
if mic_q1.status == STARTED:
    # is it time to stop? (based on global clock, using actual start)
    if tThisFlipGlobal > mic_q1.tStartRefresh + 4.55-frameTolerance:
        # keep track of stop time/frame for later
        mic_q1.tStop = t  # not accounting for scr refresh
        mic_q1.frameNStop = frameN  # exact frame index
        # add timestamp to datafile
        thisExp.addData('mic_q1.stopped', t)
        # stop recording with mic
        mic_q1.stop()
        mic_q1.status = FINISHED

At end routine:

# tell mic to keep hold of current recording in mic.clips and transcript (if applicable) in mic.scripts
# this will also update mic.lastClip and mic.lastScript
mic_q1.stop()
tag_q1 = data.utils.getDateStr()
micClip = mic_q1.bank(tag=tag, 
    transcribe='None',
    config=None
)   
q1_trials.addData('mic_q1.clip', os.path.join(micRecFolder, 'recording_mic_%s.wav' % tag_q1))

At end experiment:

for tag_q1 in mic_q1.clips:
    for i, clip in enumerate(mic_q1.clips[tag_q1]):
        clipFilename = 'recording_mic_%s.wav' % tag_q1
        print(i)
        print(clip)
        # if there's more than 1 clip with this tag, append a counter for all beyond the first
        if i > 0:
            clipFilename += '_%s' % i
        clip.save(os.path.join(micRecFolder, clipFilename))```

working_exp_2022_08_17.zip (134.0 KB)

see my solution on this post: