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

SDL 2.0.5 won't play sound at 96KHz on macOS #2459

Closed
SDLBugzilla opened this issue Feb 11, 2021 · 0 comments
Closed

SDL 2.0.5 won't play sound at 96KHz on macOS #2459

SDLBugzilla opened this issue Feb 11, 2021 · 0 comments

Comments

@SDLBugzilla
Copy link
Collaborator

@SDLBugzilla SDLBugzilla commented Feb 11, 2021

This bug report was migrated from our old Bugzilla tracker.

These attachments are available in the static archive:

Reported in version: 2.0.5
Reported for operating system, platform: macOS 10.12, x86_64

Comments on the original bug report:

On 2017-05-20 08:38:25 +0000, Lior Halphon wrote:

I upgraded my SDL1.2 project to SDL2, and sound stopped working on macOS. Sound is configured to 96KHz. SDL_OpenAudio returns 0 and returns the correct obtained struct, and my audio callback is being called, but no sound is produced.

Lowering the frequency to 44.1KHz makes the sound play. Downgrading to SDL 2.0.4 allows playback in 96KHz again.

On 2017-05-23 17:42:58 +0000, Ryan C. Gordon wrote:

Created attachment 2745
sample.wav at 96k

This is working here for me with the test/loopwave.c program in SDL's source distribution ( https://hg.libsdl.org/SDL/file/7860594a8ad7/test/loopwave.c ) and a 96KHz wave file (attached) on macOS 10.12.5.

--ryan.

On 2017-05-23 17:43:46 +0000, Ryan C. Gordon wrote:

Is there some code you can post that reproduces this bug?

On 2017-05-23 18:09:15 +0000, Lior Halphon wrote:

The following code reproduces the problem. It should play white noise for 10 seconds, but only plays for a split second. Changing freq to 96000 or samples to 2048 solves it.

#include <stdlib.h>
#include <SDL2/SDL.h>

static void audio_callback(void *gb, Uint8 *stream, int len)
{
while (len--) {
*(stream++) = rand();
}
}

int main(int argc, char **argv)
{
SDL_AudioSpec want_aspec, have_aspec;

SDL_Init( SDL_INIT_EVERYTHING );

/* Configure Audio */
memset(&want_aspec, 0, sizeof(want_aspec));
want_aspec.freq = 96000;
want_aspec.format = AUDIO_S16SYS;
want_aspec.channels = 2;
want_aspec.samples = 512;
want_aspec.callback = audio_callback;
want_aspec.userdata = NULL;
SDL_OpenAudio(&want_aspec, &have_aspec);

/* Start Audio */
SDL_PauseAudio(0);

SDL_Delay(10000);
return 0;

}

On 2017-05-23 18:10:07 +0000, Lior Halphon wrote:

(In reply to Lior Halphon from comment # 3)

Changing freq to 96000

to 44100*

On 2017-05-23 18:32:04 +0000, Sam Lantinga wrote:

This is a quirk in Mac OS X CoreAudio. If you don't fill audio buffers fast enough they'll stop being used in the audio pipeline. The only answer I've found is to make sure you have 15-20 ms in your audio buffers. Changing your buffer size or reducing your audio rate is the correct workaround.

On 2017-05-23 18:32:20 +0000, Sam Lantinga wrote:

This is true on iOS as well.

On 2017-05-23 18:40:57 +0000, Ryan C. Gordon wrote:

(In reply to Sam Lantinga from comment # 6)

This is true on iOS as well.

Hmm, we might be able to mitigate this now that we have SDL_AudioStream, which can buffer the difference if the app wants too small of a buffer per-callback...

(But it's still possible the issue is me misusing CoreAudio and it only manifests when the buffers are small.)

--ryan.

On 2017-05-23 18:46:33 +0000, Lior Halphon wrote:

How did it work in SDL 2.0.4 and 1.2 then? What was changed to make this an issue?

On 2017-05-23 18:59:28 +0000, Ryan C. Gordon wrote:

(In reply to Lior Halphon from comment # 8)

How did it work in SDL 2.0.4 and 1.2 then? What was changed to make this an
issue?

We moved from Apple's AudioUnits API to AudioQueues.

--ryan.

On 2017-05-24 04:24:10 +0000, Ryan C. Gordon wrote:

This should be fixed by https://hg.libsdl.org/SDL/rev/ad26a063ffff ... poking at Apple's API suggests that what CoreAudio wants is at least X milliseconds of audio available when it's time to feed the audio hardware, and it doesn't care if you queued one gigantic buffer to get there or a dozen tiny ones.

I imagine it's possible that a USB or bluetooth device wants way more buffered at a time than the on-board PCM chip, and there's probably an API to query for that minimum limit, but aiming for being able to buffer two blocks of 50 milliseconds seems to work okay (20ms was too small).

This approach also lets us have the app's callback fire with the originally-desired sample size but also not use a full SDL_AudioStream to buffer the difference.

--ryan.

On 2017-05-24 05:33:43 +0000, Ryan C. Gordon wrote:

(In reply to Ryan C. Gordon from comment # 10)

I imagine it's possible that a USB or bluetooth device wants way more
buffered at a time than the on-board PCM chip, and there's probably an API
to query for that minimum limit, but aiming for being able to buffer two
blocks of 50 milliseconds seems to work okay (20ms was too small).

Turns out 50 only needs to be 10 when you use the correct variable with the equation (samples, not size). https://hg.libsdl.org/SDL/rev/0b4a3c824d38

--ryan.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant