Comments (28)
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!
from soundcard.
Thank you for the bug report.
Could you try to run something like
"""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]
This should confirm whether the channel detection is somehow broken, or the problem is elsewhere.
Also, could you grab the .channels
property of your default_speaker()
?
from soundcard.
>>> import soundcard
>>> device_ids = soundcard.coreaudio._CoreAudio.get_property(soundcard.coreaudio._cac.kAudioObjectSystemObject, soundc
... ard.coreaudio._cac.kAudioHardwarePropertyDevices, "AudioObjectID")
>>> [soundcard.coreaudio._Speaker(id=d) for d in device_ids]
[<Speaker P27h-20 (0 channels)>, <Speaker C49RG9x (0 channels)>, <Speaker C49RG9x (0 channels)>, <Speaker HyperX Cloud Alpha Wireless (0 channels)>, <Speaker Shure MV88+ (0 channels)>, <Speaker MacBook Pro Microphone (0 channels)>, <Speaker MacBook Pro Speakers (0 channels)>, <Speaker Microsoft Teams Audio (0 channels)>, <Speaker Loopback Audio (0 channels)>]
soundcard.default_speaker().channels
is also 0.
In short: yes, everything is showing as 0 channels.
from soundcard.
I ended up bypassing the need for the Python soundcard lib by rewriting my code in Rust and using a CoreAudio binding to do what I needed (after I learned how the heck to use CoreAudio in the first place);
https://github.com/allquixotic/macpitch/blob/main/src/main.rs
I don't actually read or use the channels in any of this, but I'm more than willing to try out code in either Python or Rust that calls CoreAudio on my system and attempts to identify the number of channels for my devices.
Just as a reminder, this is on MacOS Ventura (latest stable version) on a M1 Max MacBook Pro (latest MBP model) that this seems to go awry. I also have several external displays and USB soundcards attached.
I'm not sure what exactly caused all the channels to start displaying as 0. I also have the Rogue Amoeba Audio Capture Engine (ACE) installed, which is a kernel-mode driver that provides "loopback" functionality for CoreAudio devices. I'm not sure how this could/would affect the number of channels in the CoreAudio API, though.
from soundcard.
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.
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.
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?
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.
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!
from soundcard.
@bastibe Slightly off topic as I don't wish to create a fresh ticket. I have an older intel based macbook air and the system is able to take audio feed from microphone and lists all microphone connected but it does not detect any system audio i.e. loopback=True. Any idea why this could be?
from soundcard.
You should have seen a warning saying that the loopback functionality is not available on macOS. If you know how to implement it on macOS, I'd be grateful for a hint, or pull request.
from soundcard.
Blackhole project is another project which achieves this, although it is a different product suite in itself.
from soundcard.
I'd never heard of Blackhole, but seemingly it's very similar to Rogue Amoeba's Audio Capture Engine, except that it's open source (GPL3). Embedding Blackhole within Python SoundCard is impractical, because there are installation steps to installing the Blackhole package at the system level, which we can't coordinate when just installing a Python package.
Also, licensing: because this project is licensed under the BSD license, which prevents combining this code with GPL3, it would probably violate the GPL to automatically install Blackhole with SoundCard.
I'm not sure there's a better way to do it than to instruct Mac users who need loopback to install Blackhole or Audio Capture Engine (or equivalent; there might be other competitors).
We can't support the SoundCard loopback
property on any particular sound device, though, because the name of any given audio capture device created by Blackhole, ACE, etc. could be user-defined, so we have no way of identifying which device might be a loopback.
from soundcard.
Presumably, there's some way of implementing loopback devices on macOS within soundcard. I just haven't found the relevant API in Core Audio, yet.
Loopback devices were a later addition to soundcard, partly contributed by pull requests. They were not included in the original release, and therefore were not part of my original research. Which is to say, there might be a trivial way to do this.
from soundcard.
@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.
from soundcard.
@bastibe I can repro this issue on my M1 MacBook Pro running Ventura 13.1 on System python (3.9.6) but not on Homebrew installed python (3.10.4). Let me know if I can help troubleshoot
from soundcard.
I bet that's a sandboxing issue. In the past, some people needed to activate something in the accessibility settings to get around issues like this. As far as I know, there is nothing I can do about that in the software itself.
If you do find a reason or workaround, please let me know.
from soundcard.
I have two Macs where I have tested the code
- Intel Mac with macOS Monterrey soundcard is working
- Soundcard 0.4.2
- Intel Mac with macOS Ventura 13.4 soundcard is working
- Soundcard 0.4.2
- M2 Pro with Ventura 13.3.1 same issue channels not appearing
- Soundcard 0..4.2
- M2 Pro with Ventura 13.4 same issue channels not appearing
- Soundcard 0.4.2
I’m updating the Intel Mac to see if it’s related to Apple Silicon or Ventura.
I use an app to request permission for the terminal so that’s not the reason
Edited: I'm using a Focusrite 3th gen
Edited2:
I have finished updating the Intel Mac with Ventura 13.4 and SoundCard still works.
@allquixotic One question the setup work at some point on the Apple silicon Mac?
from soundcard.
I think I found the problem @bastibe
The channel number is not automatically assigned on Apple Silicon
I'm using this Function from Coreaudio
Apple Silicon
AudioChannelDescription[] 1
0.0
Intel
AudioChannelDescription[] 1
1.401298464324817e-45
I found that it's possible to use this
AudioChannelDescription *channelDescription = [[AudioChannelDescription alloc] init];
[channelDescription setChannelLabel:@"Left" forChannelNumber:0];
I'm not too experienced with CoreAudio so I'll prefer suggestions on this
Please let me know if this makes sense
from soundcard.
More interesting findings with this issue. I wanted to verify that the Permission theory was correct.
So I wrote this CPP code
#include <CoreAudio/CoreAudio.h>
#include <AudioUnit/AudioUnit.h>
void requestMicrophonePermission(AudioDeviceID deviceID) {
OSStatus status;
AudioObjectPropertyAddress selectorAddress;
selectorAddress.mSelector = kAudioDevicePropertyDataSource;
selectorAddress.mScope = kAudioDevicePropertyScopeInput;
selectorAddress.mElement = kAudioObjectPropertyElementMain;
// Request microphone permission
status = AudioObjectSetPropertyData(deviceID, &selectorAddress, 0, nullptr, sizeof(CFStringRef), "Microphone");
if(status != noErr) {
printf("Error: %d\n", status);
}
printf("Request microphone permission: %d\n", status);
}
int main()
{
AudioDeviceID deviceID;
UInt32 size = sizeof(deviceID);
AudioObjectPropertyAddress propertyAddress = {
kAudioHardwarePropertyDefaultInputDevice,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMain
};
AudioObjectGetPropertyData(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &size, &deviceID);
requestMicrophonePermission(deviceID);
printf("Device ID: %u\n", deviceID);
AudioObjectPropertyAddress propertyAddress2 = {
kAudioDevicePropertyStreamConfiguration,
kAudioObjectPropertyScopeInput,
kAudioObjectPropertyElementMain
};
OSStatus status;
UInt32* size2;
AudioBufferList bufferList[] = {3};
status = AudioObjectGetPropertyData(
deviceID, &propertyAddress2, 0, NULL, size2, bufferList);
printf("Audio buffer: %u\n", bufferList[0].mNumberBuffers);
printf("Audio data: %u\n", bufferList[0].mBuffers[0].mNumberChannels);
printf("Audio data: %u\n", bufferList->mBuffers[0].mNumberChannels);
// getAudioBufferListFromDeviceID(deviceID);
return 0;
}
The Apple Silicon Mac returns different errors depending on the input source.
- Scarlett 8i6 USB
Error: 2003332927
- Macbook pro microphone
Error: 1852797029
- HD Pro Webcam C920
Error: 2003332927
Running the same code on the Intel mac returns 0 so no error on the status
I'm talking about this part of the code
// Request microphone permission
status = AudioObjectSetPropertyData(deviceID, &selectorAddress, 0, nullptr, sizeof(CFStringRef), "Microphone");
if(status != noErr) {
printf("Error: %d\n", status);
}
printf("Request microphone permission: %d\n", status);
from soundcard.
So we need to request permission for using the sound card from a CLI program? How very interesting, and annoying. Thank you for the analysis.
Is this why we can't get the channel number?
from soundcard.
@bastibe Any plans to support MacOS? I believe @alfonsocv12 has given some possible way out for the problems.
from soundcard.
I don't currently have the time to do it myself. But I'll happily review a pull request.
from soundcard.
Related Issues (20)
- Support acoustic echo cancellation (AEC) for windows HOT 1
- Problems with the "fuzzy matcher" in get_microphone() HOT 1
- Watch for moved streams? HOT 1
- Decode error in _CoreAudio.CFString_to_str HOT 2
- feature request - ability to add virtual audio channels. HOT 1
- Why won't it save my audio when I use this with SoundFile? HOT 4
- OSError: ctypes.util.find_library() did not manage to locate a library called 'harfbuzz' please help in windows HOT 2
- Does anyone know how to make this work? HOT 1
- Wav file is empty after recording is saved to file HOT 5
- how to end playback in advance? HOT 2
- Need help with settings HOT 6
- Record audio unlimited HOT 6
- get mac audio output level HOT 1
- Queation: Is that possible to record based on a button click? HOT 1
- Data loss while recording HOT 4
- Cannot record sound with loopback if silence at start HOT 10
- loopback record audio from speaker return zero array HOT 5
- Problem with the player HOT 1
- how to get non numpy "raw" mono data from the record() method HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from soundcard.