Skip to content

Commit b7c8b2f

Browse files
committed
hints: Added SDL_HINT_AUDIO_ENFORCE_MINIMUM_SPEC.
Fixes #14426.
1 parent ea1514a commit b7c8b2f

File tree

2 files changed

+45
-12
lines changed

2 files changed

+45
-12
lines changed

include/SDL3/SDL_hints.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,36 @@ extern "C" {
493493
*/
494494
#define SDL_HINT_AUDIO_DUMMY_TIMESCALE "SDL_AUDIO_DUMMY_TIMESCALE"
495495

496+
/**
497+
* A variable controlling whether SDL enforces a minimum audio device spec.
498+
*
499+
* By default, SDL will require devices to be opened at a minimum spec
500+
* (at time of writing: 44100Hz, stereo, Sint16 format), so if something
501+
* lower quality tries to open the device first, it doesn't ruin audio
502+
* for the next thing that opens a device. For example, if a VoIP library
503+
* wants Uint8, 8000Hz, mono output, it doesn't force the entire game to
504+
* this state simply because it got there first.
505+
*
506+
* However, an app that knows it will definitely be the only thing opening
507+
* a device, and wants to open it at a lower spec, might be able to avoid
508+
* some otherwise-unnecessary conversions by bypassing this minimum
509+
* requirement.
510+
*
511+
* Note that even without the minimum enforcement, the system might choose a
512+
* different format/channels/frequency than requested by the app; this hint
513+
* just removes SDL's minimum policy.
514+
*
515+
* The variable can be set to the following values:
516+
*
517+
* - "0": Audio device mimimum formats _are not_ enforced.
518+
* - "1": Audio device minimum formats _are_ enforced. (default)
519+
*
520+
* This hint should be set before an audio device is opened.
521+
*
522+
* \since This hint is available since SDL 3.4.0.
523+
*/
524+
#define SDL_HINT_AUDIO_ENFORCE_MINIMUM_SPEC "SDL_AUDIO_ENFORCE_MINIMUM_SPEC"
525+
496526
/**
497527
* A variable controlling the default audio format.
498528
*

src/audio/SDL_audio.c

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1800,18 +1800,21 @@ static bool OpenPhysicalAudioDevice(SDL_AudioDevice *device, const SDL_AudioSpec
18001800
SDL_copyp(&spec, inspec ? inspec : &device->default_spec);
18011801
PrepareAudioFormat(device->recording, &spec);
18021802

1803-
/* We impose a simple minimum on device formats. This prevents something low quality, like an old game using S8/8000Hz audio,
1804-
from ruining a music thing playing at CD quality that tries to open later, or some VoIP library that opens for mono output
1805-
ruining your surround-sound game because it got there first.
1806-
These are just requests! The backend may change any of these values during OpenDevice method! */
1807-
1808-
const SDL_AudioFormat minimum_format = device->recording ? DEFAULT_AUDIO_RECORDING_FORMAT : DEFAULT_AUDIO_PLAYBACK_FORMAT;
1809-
const int minimum_channels = device->recording ? DEFAULT_AUDIO_RECORDING_CHANNELS : DEFAULT_AUDIO_PLAYBACK_CHANNELS;
1810-
const int minimum_freq = device->recording ? DEFAULT_AUDIO_RECORDING_FREQUENCY : DEFAULT_AUDIO_PLAYBACK_FREQUENCY;
1811-
1812-
device->spec.format = (SDL_AUDIO_BITSIZE(minimum_format) >= SDL_AUDIO_BITSIZE(spec.format)) ? minimum_format : spec.format;
1813-
device->spec.channels = SDL_max(minimum_channels, spec.channels);
1814-
device->spec.freq = SDL_max(minimum_freq, spec.freq);
1803+
if (!SDL_GetHintBoolean(SDL_HINT_AUDIO_ENFORCE_MINIMUM_SPEC, true)) {
1804+
SDL_copyp(&device->spec, &spec);
1805+
} else {
1806+
/* We impose a simple minimum on device formats. This prevents something low quality, like an old game using S8/8000Hz audio,
1807+
from ruining a music thing playing at CD quality that tries to open later, or some VoIP library that opens for mono output
1808+
ruining your surround-sound game because it got there first.
1809+
These are just requests! The backend may change any of these values during OpenDevice method! */
1810+
const SDL_AudioFormat minimum_format = device->recording ? DEFAULT_AUDIO_RECORDING_FORMAT : DEFAULT_AUDIO_PLAYBACK_FORMAT;
1811+
const int minimum_channels = device->recording ? DEFAULT_AUDIO_RECORDING_CHANNELS : DEFAULT_AUDIO_PLAYBACK_CHANNELS;
1812+
const int minimum_freq = device->recording ? DEFAULT_AUDIO_RECORDING_FREQUENCY : DEFAULT_AUDIO_PLAYBACK_FREQUENCY;
1813+
device->spec.format = (SDL_AUDIO_BITSIZE(minimum_format) >= SDL_AUDIO_BITSIZE(spec.format)) ? minimum_format : spec.format;
1814+
device->spec.channels = SDL_max(minimum_channels, spec.channels);
1815+
device->spec.freq = SDL_max(minimum_freq, spec.freq);
1816+
}
1817+
18151818
device->sample_frames = SDL_GetDefaultSampleFramesFromFreq(device->spec.freq);
18161819
SDL_UpdatedAudioDeviceFormat(device); // start this off sane.
18171820

0 commit comments

Comments
 (0)