Audio capture stopped working (macOS)

I have an audio application built on SDL2 that was working stably on macOS for months until quite recently (~1-2w), when audio capture suddenly stopped working. I haven’t made any changes to the stable version of the application (which is admittedly a prototype), so it’s hard to say what happened. It probably coincided with my most recent macOS update (to Sonoma 14.4.1). I have no problems on Ubuntu. It’s probably also worth mentioning that I’m building with clang on macos, gcc on linux.

Everything seems to work except that the stream provided by my callback function contains all zeroes. (This is a capture device opened with iscapture = 1 so the stream should contain audio data.) I’ve tested with two audio devices that both used to work fine with this application, and continue to work fine for others.

The issue also seems to be inconsistent. I’ve opened the application and had capture work just fine a couple times since the issue first appeared, but have no idea what conditions allowed it to work. Right now it’s not working at all.

First encountered in SDL 2.28.5, and tried updating to 2.30.2, but it’s the same. I threw together a quick test program to make sure there isn’t a bug somewhere else in my application that’s causing the problem:

#include "SDL.h"

void audio_callback(void *userdata, Uint8 *stream, int len)
{
    /* I get all zeroes, every time; even when I know my device is picking up a signal */
    for (int i=0; i<len; i++) {
	fprintf(stdout, "%d ", stream[i]);
    }
}

int main()
{
    SDL_Init(SDL_INIT_AUDIO);
    SDL_AudioDeviceID capture_device;
    
    SDL_AudioSpec desired, obtained;
    desired.channels = 2;
    desired.freq = 48000;
    desired.format = AUDIO_S16SYS;
    desired.samples = 512;
    desired.callback = audio_callback;

    capture_device = SDL_OpenAudioDevice(NULL, 1, &desired, &obtained, 0);
    if (capture_device <= 0) {
	fprintf(stderr, "Fatal: could not open device\n");
	exit(1);
    }
    
    SDL_PauseAudioDevice(capture_device, 0);
    SDL_Delay(100);
    SDL_PauseAudioDevice(capture_device, 1);

    /* Confirm all values are as expected */
    fprintf(stdout, "Obtained channels: %d, freq: %d, samples: %d\n", obtained.channels, obtained.freq, obtained.samples);
    fprintf(stdout, "correct format? %d\n", obtained.format == AUDIO_S16SYS);
}

I have no idea where to go from here. This problem is a total roadblock for my application (which is fundamentally an audio capture application) so I would be massively appreciative for any help any of you folks can offer. Thanks very much in advance

1 Like

Update: it’s definitely some issue with the OS-granted permission to use system microphones. The state right now is that when I launch the application from the emacs terminal emulator, audio capture doesn’t work, and I’m not prompted to grant permissions upon opening the audio device. Launching from the terminal directly works, but only after toggling the permission in system settings (it was already enabled, so this was basically like banging on a broken machine to get it working again).