Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: System default audio device not used in versions >= 2024 #6372

Open
Cortexan opened this issue Apr 13, 2024 · 0 comments
Open

[Bug]: System default audio device not used in versions >= 2024 #6372

Cortexan opened this issue Apr 13, 2024 · 0 comments
Labels
🐞 bug Issue describes a bug (crash or error) or undefined behavior.

Comments

@Cortexan
Copy link

Cortexan commented Apr 13, 2024

PsychoPy Version

2024.1.0

What OS are your PsychoPy running on?

Windows 11

Bug Description

In Psychopy versions < 2024, with:

prefs.hardware["audioDevice"] == "default"

the current default system audio output device is utilised. The default device can be verified via psychtoolbox:

import psychtoolbox as ptb
from psychopy.sound import getDevices

def getAvailableDevices():
    devices = []

    for profile in getDevices(kind="output").values():
        device = {
            'deviceName': profile.get('DeviceName', "Unknown Microphone"),
            'index': profile.get('DeviceIndex', None),
        }
        devices.append(device)

    return devices

default_device = ptb.PsychPortAudio('Open')
device_status = ptb.PsychPortAudio('GetStatus', default_device)
default_device_key = device_status['OutDeviceIndex']

for device_dict in getAvailableDevices():
    if device_dict['index'] == default_device_key:
        default_device_name = device_dict['deviceName']

print(f'The default device is: "{default_device_name}"')

However, in Psychopy version >= 2024, the "default" audio device is selected as the 0-indexed device identified by getAvailableDevices(), potentially resulting in an audio device other than the system default being selected.

This is resolved by modifying the SpeakerDevice() class in ~\psychopy\hardware\speaker.py as follows:

# added for new method of identifying default device
import psychtoolbox as ptb 

class SpeakerDevice(BaseDevice):
    def __init__(self, index):
        # use first device if index is default
        if not isinstance(index, (int, float)) or index < 0:

            # # these lines:
            # profiles = self.getAvailableDevices() # no longer needed in this case
            # index = profiles[0]['index'] # error induced here, pulling device index from 0-indexed entry in profiles

            # are replaced with:
            default_port_audio = ptb.PsychPortAudio('Open') # using psychtoolbox to identify default device
            index = ptb.PsychPortAudio('GetStatus', default_port_audio)['OutDeviceIndex'] # pulling index directly from psychtoolbox output

        # store index
        self.index = index
        # set global device (best we can do for now)
        setDevice(index)

 #... the rest stays the same

Although I'm sure there is a more elegant and comprehensive solution, this update at least addresses the issue.

Expected Behaviour

Audio should play through system default device when:

psychopy.prefs.hardware['AudioDevice'] == ['default']

Steps to Reproduce

  1. Connect more than one audio device (e.g., Bluetooth headphones)
  2. Attempt to play audio
  3. Audio from psychopy will potentially be sent to incorrect device (e.g., built-in speakers)
    ...

Additional context

This has been reproduced and verified on two different systems with python versions 3.9 and 3.11.

Expected behaviour is observed in psychopy 2023.2.3

@Cortexan Cortexan added the 🐞 bug Issue describes a bug (crash or error) or undefined behavior. label Apr 13, 2024
@Cortexan Cortexan mentioned this issue Apr 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐞 bug Issue describes a bug (crash or error) or undefined behavior.
Projects
None yet
Development

No branches or pull requests

1 participant