Random crashes when using voicekey()

Hi everybody,
I have been trying to solve the following problem for the last couple of months, but as of yet have not succeeded. I have been successfully running several experiments using an external voicekey (Reacsys vkms-1) and the parallel port with varying PsychoPy versions. Since the voicekey only registers the latency of the response, and the content and the accuracy has to be coded from experimenters (which is far from an easy task), we want to double-check the accuracy of the coding. Thus, in addition to the parallel port voicekey, we wanted to record the trials. We were thus really happy with the development of the voicekey()-function. However, in a large number of sessions, the experiment randomly crashes. Most of the times, we only get the windows message “pythonw.exe has stopped working”. Rarely, at least when we end the experiment prematurely, we get the following error message:

portaudio error in Pa_AbortStream: Wait timed out
portaudio error in Pa_AbortStream: PortAudio not initialized
portaudio error in Pa_CloseStream: PortAudio not initialized
portaudio error in Pa_Terminate: PortAudio not initialized
Error closing audio backend.
Exception TypeError: “‘NoneType’ object is not callable” in <bound method Server.del of pyolib.server.Server object at 0x17FD5F30 ignored

Importantly, in the majority of sessions, the experiment works well and the PsychoPy recordings and the results from the external voicekey converge rather nicely. We are now using PsychoPy 1.84.2 on a Windows 7 SP1 pc, but the problem also occurs with older PsychoPy and Windows versions.
Oh, and I am under the impression that the experiment is especially likely to crash when there are noises before the initialization of vk.start(). I have played around with starting voicekey.pyo.init() later, but that didn’t do the trick either.
From other threads, I get the impression that this might be caused by pyo – but in this case, I can’t change that to pygame, correct?
I would very much appreciate any help! I have attached the relevant pieces of code below (hopefully- I have deliberately only deleted some parts of the runTrial() to enable a better understanding- if this is still too much, let me know and I will delete more).
Best,
Manuel

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from psychopy import visual
from psychopy import core, event, misc, logging, gui, data, parallel, monitors, voicekey
from psychopy import sound, microphone
from operator import itemgetter
import fragebogen, vragenlijst
import pyglet
import os, itertools
import codecs
import random
import copy

#...

if mode==1:
    port = parallel.PParallelInpOut32(address=0xD010)

#...

def voice_key():
    return port.readPin(10)


def get_code():
    quit=0
    response = event.waitKeys(maxWait='inf',keyList=["num_1","num_2","num_3","num_4","num_5","lctrl"], timeStamped=False)[0]
#    response = event.waitKeys(maxWait='inf', timeStamped=False)[0]
    if response=="lctrl":
        response=event.waitKeys(maxWait='inf',keyList=["num_1","num_2","num_3","num_4","num_5","b","q"], timeStamped=False)[0]
        if response=="b":
            quit=-1
        elif response=="q":
            core.quit()
    return response,quit

def runTrial(trial,count):
    ITI=random.randint(500,1500)
    ITI_in_SEC=float(ITI)/1000.0
    for frameN in range(all_time+1):
        if trial["onset"]==0:
            if frameN==all_time:
                if trial["type"]==0:
                    blue.draw()
                else:
                    green.draw()
        else:
            if frameN<=all_time:
                if trial["type"]==0:
                    blue.draw()
                else:
                    green.draw()
        if frameN<fix:
            fixation.draw()
        if frameN==all_time:
            target.draw()
        myWin.flip()
        if frameN==all_time:
            print count
            trialClock.reset()
            vk.start()
    
    while (trialClock.getTime()<3.0) and (trial["rt"]==-1):
        if mode == 1:
            if voice_key()==1:
                trial["rt"]=trialClock.getTime()
        elif mode== 0:
            event.waitKeys(maxWait= 3.0,keyList="space")
            trial["rt"]=trialClock.getTime()
    if trial["rt"]==-1:
        trial["rt"]=3.0
    blue.setAutoDraw(False)
    green.setAutoDraw(False)
    myWin.flip()
    event.clearEvents()
    response,quit=get_code()
    trial["resp"] = list(response)[-1]
    print vk.event_detected, vk.event_onset, trialClock.getTime()
    trial["virt"]=vk.event_onset
    minT=0
    if vk.event_onset < 0.1:
        minT=1.5
    else: 
        minT=1.0
    while trialClock.getTime() - vk.event_onset < minT:
        qx=0
    trialClock.reset()
    print trial

    vk.stop()
    return quit
1 Like

Hi Manuel,

Your question has been asked a few years back but I am running into the same issue.
I am using the builder mainly but inserted a code component with vk.OnsetVoiceKey() and Psychopy crashes randomly.
There was no issue at all for a few months, but now it happens quite frequently. I had a 4 hour-session a couple of days ago with no issue and today for a 30 minute-session it crashed twice.
I only get the “python.exe has stopped working” window.
I have tried to replicate a crash again for 2 hours now but can’t.

When all runs “well” I still get those error messages though:

Portaudio error in Pa_AbortStream (pa_stop): Unanticipated host error
Portaudio error in Pa_CloseStream (pa_deinit): PortAudio not initialized
Portaudio error in Pa_Terminate (pa_deinit): PortAudio not initialized
Pyo error: Error closing audio backend.

and

Traceback (most recent call last):
  File "C:\Program Files\PsychoPy3\lib\site-packages\pyo\lib\_core.py", line 790, in __call__
    return self.method(self.target, *args, **kwargs)
  File "C:\Program Files\PsychoPy3\lib\site-packages\psychopy\voicekey\__init__.py", line 443, in stop
    for ch in range(len(self.t_exit)):
ReferenceError: weakly-referenced object no longer exists

I don’t know if you found a solution to the issue on your side?

Best,
Aurore

Just ran into the same ReferenceError as Aurore. I know I’m three years late, but I’m hoping this reply will help future scientists who run into this same, highly frustrating problem.

Background
PsychoPy’s audio processing tools rely on pyo to process audio. I do not understand audio servers, but the pyo server that we need has its own rhythm that it uses to run code periodically. See here. They have tools to make sure your functions run in-sync with the pyo rhythm.

What does ReferenceError mean?
You get ReferenceError when your code tries to refer to an object that was once associated to a var, but that object is now gone. In this case, pyo tries to refer to the OnsetVoiceKey() object you had instantiated in your last trial, but because your code has instantiated a new one in the same var, it does not find it. I don’t know why it sometimes crashes, but when my code crashes the only errors present are ReferenceError.

My janky solution
Get your code to wait a few ms after each trial so that pyo can catch up. I learned this trick from the PsychoPy developers who seem to be aware of this problem. See source code for self.wait_for_event().

In my case, I’m using psychopy.core.wait(0.25) at the end of my method that records audio. I haven’t gotten ReferenceError or a crash since.

Would it be possible to use the new Microphone class (which uses psychtoolbox instead of pyo for the recordings)? I don’t expect we’ll be committing much of our own time to working on the old voicekey code (although contributions are always welcome of course)

The new microphone class was behaving weirdly for me. It had trouble outputting a recording of a fixed amount of time and the audio output sounded slowed and choppy.

I can dig through my history for code to reproduce the error, but it’s pretty far back. Let me know if that’s something y’all are interested in.

Well, yes, in general I believe the PTB mic is the way to go, and we want to focus on just a single option. If there’s something going wrong with the new Microphone then I’d prefer we get that fixed. I don’t see us investing further time trying to fix up the old Voicekey class.

After adding “core.wait(0.25)” right after “vpvk.stop()” in end Routine, I’ve run into a new error message related to the Pyo server not being properly booted. This error occurs sporadically(mostly occurs at about 50 trials, and the experiment ended with errors ), and the relevant code snippet leading to the error is as follows:

Pyo error: The Server must be booted!
Traceback (most recent call last):
Portaudio error in Pa_CloseStream (pa_deinit): PortAudio not initialized
File “C:\Users\admin\Desktop\erpmarker\erp_exp_voicekey_23818_marker_lastrun.py”, line 485, in
if tThisFlipGlobal > I_jitter.tStartRefresh + jitter_time - frameTolerance:
TypeError: unsupported operand type(s) for +: ‘float’ and ‘NoneType’

I guess [TypeError] may be caused by the wrong usage of voicekey.

I kindly request assistance from you to help me address these issues. If anyone has encountered similar problems or has insights into why these errors might occur, your guidance would be greatly appreciated.

Thank you for your time and consideration, and I look forward to any advice or solutions that you can provide.
erp_exp_voicekey_23818_marker.psyexp (42.1 KB)