psychopy.org | Reference | Downloads | Github

Partial success getting PYO to work: help needed!

Hello all,

I need to get PYO to work on a Windows 7 Enterprise Dell Optiplex 7040. It’s a requirement as colleagues are also using PYO on existing equipment, and sound playback (in our detection experiment) is much quieter using PyGame/sounddevice.

I tried first of all with the standalone PsychoPy install. Error:

Portaudio uses interleaved callback.
portaudio error in Pa_OpenStream: Illegal combination of I/O devices
portaudio error in Pa_CloseStream (pa_deinit): PortAudio not initialized
portaudio error in Pa_Terminate (pa_deinit): PortAudio not initialized
Portmidi initialized.
Portmidi number of devices: 2.
Midi input device : -1.
Can't get midi input device info : -1.
Midi output device : 0.
Midi output (Microsoft MIDI Mapper) opened.
Portaudio uses interleaved callback.

I then installed the latest PYO (pyo_0.8.7_py2.7_setup.exe) and 32-bit Anaconda for Python 2.7. The rest of this post uses this Python interpreter.

Same errors with this interpreter and latest PYO.

I then got a minimal example working without PsychoPy:


import sys
sys.path.append('C:\pyo\Python27\Lib\site-packages')
from pyo import *
s=Server(sr=44100, nchnls=2, buffersize=256, duplex=1, audio='portaudio', jackname='pyo', ichnls=None, winhost='asio')
s.boot()
print 'B'
s.start()
a = Sine(mul=0.01).out()
import time
time.sleep(5)
print 'C'

This crashed until I set winhost=‘asio’, at which point the sound played fine.

I then went into sound/backend_pyo.py in the PsychoPy code and updated the calls which instantiate Server to add this parameter.

PYO then worked fine for about half an hour - I was able to run the following sample code:

import sys
sys.path.append('C:\pyo\Python27\Lib\site-packages')
from psychopy import prefs
prefs.general['audioLib'] = ['pyo']
from psychopy import locale_setup, core, data, event, logging, sound, gui
print sound.__file__
f = sound.Sound('1025Hz pure sine_100ms.wav', secs=0.15) 
f.play()
import time
time.sleep(5)

…without a problem.

Frustratingly, things have now stopped working again - without me making any changes!

The above sample code runs without error, but hangs without playback, and doesn’t exit.

I will be coming back to this tomorrow. Does anyone have any advice on debugging PYO or finding the problem? I have already set PYO’s verbosity level to DEBUG.

Cheers,
Fintan

Olivier has replied here:

Hi,

First of all, on Windows, you must choose the good host (asio, wasapi (default as of 0.8.7), mme, etc.) and, if needed the good device ( Server.setOutputDevice(device_index) ). There is a script in the pyo documentation to test the audio setup on your system:

http://ajaxsoundstudio.com/pyodoc/winaudioinspect.html

Then, if you’re using wasapi, be sure there is both an output AND an input configured on your system (it’s not always the case on Windows). Otherwise, you boot the Server in output only by setting the duplex argument to 0. Sampling rate of pyo must also match the sampling rate of the system (System’s sr is often 48000 while pyo’s default is 44100).

Now, in your code, you should always call Server.stop() when you’re done so that pyo can properly release the audio driver. Maybe that’s the problem described in that post. If a process didn’t release the driver, subsequent attempts will probably fail.

PYO now works on my system.

I updated some code in sound/backend_pyo.py to this:


        # create the instance of the server:
        if platform in ['darwin', 'linux2']:
            # for mac/linux we set the backend using the server audio param
            pyoSndServer = Server(sr=rate, nchnls=maxChnls,
                                  buffersize=buffer, audio=audioDriver)
        else:
            # with others we just use portaudio and then set the OutputDevice
            # below
            pyoSndServer = Server(sr=rate, nchnls=maxChnls, buffersize=buffer, winhost='asio', duplex=0)

        pyoSndServer.setVerbosity(1)
        if platform == 'win32':
            pyoSndServer.setOutputDevice(outputID)
            if inputID is not None:
                pyoSndServer.setInputDevice(inputID)
        # do other config here as needed (setDuplex? setOutputDevice?)
        pyoSndServer.setDuplex(0)
        pyoSndServer.boot()

I’ve made two changes, adding winhost=‘asio’, duplex=0 to the server instantiation and hard-coding 0 in the pyoSndServer.setDuplex(0) call.

Jon - since it seems a few other people have experienced problems like this, would you like me to issue a pull request to configure duplex/ASIO in PYO?

I imagine it would look something like adding a global preference setting for a) duplex and b) Windows audio host (winhost parameter to PYO server), then updating backend_pyo.py to pay attention to this.

If you think this is a good idea, let me know where in the code you deal with preferences, and I’ll issue a PR.

Cheers,
Fintan

Some information that may be helpful if you want to use wasapi (perhaps for consistency, like me):

s=Server(sr=48000, nchnls=2, buffersize=256, duplex=0, audio='portaudio', jackname='pyo', ichnls=None, winhost='wasapi')

also works in my non-PsychoPy example above. Duplex needs to be 0 and the sampling rate needs to be 48000.

And finally,

pyoSndServer = Server(sr=48000, nchnls=maxChnls, buffersize=buffer, winhost='wasapi', duplex=0)

also works in backend_pyo.py.