question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

MacOS: Empty result for all_speakers/all_microphones

See original GitHub issue

Symptom:

% ptpython
>>> sys.version
'3.10.8 (main, Oct 21 2022, 22:22:30) [Clang 14.0.0 (clang-1400.0.29.202)]'

>>> import soundcard as sc
>>> sc.all_speakers()
[]

>>> sc.all_microphones()
[]

>>> sc.default_speaker()
<Speaker HyperX Cloud Alpha Wireless (0 channels)>

>>> sc.default_microphone()
<Microphone HyperX Cloud Alpha Wireless (0 channels)>

Note all_speakers() and all_microphones() return empty lists instead of the expected data. The other strangeness is that it says the default speaker and microphone have “0” channels.

I have Python 3.10.8 installed on MacOS Ventura using Homebrew. To rule out environment problems, I’ve checked env for any weird variables, cleared out my site-packages directory and reinstalled soundcard and all its dependencies, but the problem persists.

Just the other day, all of this was working as expected, but after doing a complete reinstall of Python and soundcard, this no longer works.

As a proof that my CoreAudio native libraries are working, the program SwitchAudio (installed by brew install switchaudio-osx; source code at https://github.com/deweller/switchaudio-osx ) returns the following output showing all my devices:

% SwitchAudioSource -a -f json
{"name": "HyperX Cloud Alpha Wireless", "type": "input", "id": "51", "uid": ""}
{"name": "MacBook Pro Microphone", "type": "input", "id": "148", "uid": ""}
{"name": "Loopback Audio", "type": "input", "id": "153", "uid": ""}
{"name": "HyperX Cloud Alpha Wireless", "type": "output", "id": "51", "uid": ""}
{"name": "MacBook Pro Speakers", "type": "output", "id": "141", "uid": ""}
{"name": "Loopback Audio", "type": "output", "id": "153", "uid": ""}

Technically, I could drop the soundcard dependency, call switchaudio-osx via the CLI, parse the resulting JSON, and get what I need. But I wanted to report this issue in the soundcard lib.

Looking at the definition of all_speakers() for CoreAudio in soundcard/coreaudio.py:

def all_speakers():
    """A list of all connected speakers."""
    device_ids = _CoreAudio.get_property(
        _cac.kAudioObjectSystemObject,
        _cac.kAudioHardwarePropertyDevices,
        "AudioObjectID")
    return [_Speaker(id=d) for d in device_ids
            if _Speaker(id=d).channels > 0]

See how it only creates a Speaker object if channels > 0 ? Well, the default speaker and default microphone are showing up as channels = 0, for some reason, so maybe all of my devices are showing up as channels = 0 using the API…

Based on the native code here (which we know works, because switchaudio-osx works on my system), it looks like the soundcard CFFI code is probably correctly enumerating all the devices. Unfortunately, switchaudio doesn’t implement channel detection, so I can’t vouch for the correctness of this code in soundcard/coreaudio.py:

    @property
    def channels(self):
        bufferlist = _CoreAudio.get_property(
            self._id,
            _cac.kAudioDevicePropertyStreamConfiguration,
            'AudioBufferList', scope=_cac.kAudioObjectPropertyScopeOutput)
        if bufferlist and bufferlist[0].mNumberBuffers > 0:
            return bufferlist[0].mBuffers[0].mNumberChannels
        else:
            return 0

Looks like it gets to the return 0 there at the end, which is the source of all the problems… unfortunately I don’t know why this happens, or how to fix it.

Issue Analytics

  • State:open
  • Created 10 months ago
  • Comments:11 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
allquixoticcommented, Dec 5, 2022

This is the first time I’ve heard of a bug like this. Thus it might either be something very new, or something specific to your machine.

I have a few other Macs floating around that I’ll test on when I get a chance, but it may not be soon.

Could this be in some way related to a new macOS security measure? (It wouldn’t be the first time). For example, are you using a third-party terminal application, or are you calling the code from an untrusted application? Some applications need to be whitelisted in accessibility settings before they are allowed to work correctly.

Maybe, but I tried it both with iTerm2 and the native Mac Terminal app, and neither one pops up a security prompt asking me to permit microphone access or anything like that. They don’t appear as options in Privacy to even enable microphone access, because they don’t seem to need it.

It also wouldn’t be the first time for macOS to change some behavior of the C API “silently”. Do you know whether this might have happened in response to some update you installed?

The only possible update it could have been is between Ventura 13.0.0 and Ventura 13.0.1. I’m not 100% sure I had tested this both before and after the 13.0.1 upgrade, as I wasn’t paying attention to specifically when I installed the update vs. when I was messing with python-soundcard.

And, if you would indulge me, could you try testing the number of channels in your Rust wrapper? I wonder if this is somehow specific to soundcard, or in fact applies to every CoreAudio application.

I wasn’t able to get this working in Rust, but that’s mainly due to my own incompetence with figuring out how to do raw memory allocation in Rust. The furthest I got was some program crashes. I can’t put any more time into it unfortunately.

If you don’t have time to help me here, that’s perfectly understandable as well. But I’d be grateful for your help, as I personally don’t have a recent macOS machine to test these things on!

0reactions
debasish-mihupcommented, Dec 5, 2022

@bastibe @allquixotic There is another similar package https://github.com/kyleneideck/BackgroundMusic#recording-system-audio that enables system audio recording. Maybe worth checking it out if not done already.

Read more comments on GitHub >

github_iconTop Results From Across the Web

If your Mac starts up to a blank screen - Apple Support
Try to start up from macOS Recovery. If your Mac seems to be turned on but the screen remains blank, follow the appropriate...
Read more >
How can I clear previous output in Terminal in Mac OS X?
To clear entered text, first jump left with Command + A and then clear the text to the right of the pointer with...
Read more >
Outlook for Mac search returns "No Results," and task items ...
Outlook for Mac displays a "No Results" message if indexing is not finished. ... Additionally, when you search for mail items by using...
Read more >
Mac's Trash won't empty? Here's how to fix it - MacPaw
If your Mac's running the latest version of the macOS but Trash still misbehaves, try the following fixes. 1. Restart your Mac. The...
Read more >
How to clear disk space on a Mac | Macworld
You may also need to clear some space on your Mac is if you are installing an operating system update. When Apple released...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found