audio: Handle non-power-of-two spec.samples when unsupported Fixes #3685
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
index e2306bc..b9c38dc 100644
--- a/src/audio/SDL_audio.c
+++ b/src/audio/SDL_audio.c
@@ -1413,6 +1413,19 @@ open_audio_device(const char *devname, int iscapture,
}
}
+ /* For backends that require a power-of-two value for spec.samples, take the
+ * value we got from 'desired' and round up to the nearest value
+ */
+ if (!current_audio.impl.SupportsNonPow2Samples && device->spec.samples > 0) {
+ device->spec.samples -= 1;
+ device->spec.samples |= device->spec.samples >> 1;
+ device->spec.samples |= device->spec.samples >> 2;
+ device->spec.samples |= device->spec.samples >> 4;
+ device->spec.samples |= device->spec.samples >> 8;
+ device->spec.samples |= device->spec.samples >> 16;
+ device->spec.samples += 1;
+ }
+
if (current_audio.impl.OpenDevice(device, devname) < 0) {
close_audio_device(device);
return 0;
diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h
index 0f98f90..6afaae1 100644
--- a/src/audio/SDL_sysaudio.h
+++ b/src/audio/SDL_sysaudio.h
@@ -88,6 +88,7 @@ typedef struct SDL_AudioDriverImpl
SDL_bool OnlyHasDefaultOutputDevice;
SDL_bool OnlyHasDefaultCaptureDevice;
SDL_bool AllowsArbitraryDeviceNames;
+ SDL_bool SupportsNonPow2Samples;
} SDL_AudioDriverImpl;
diff --git a/src/audio/alsa/SDL_alsa_audio.c b/src/audio/alsa/SDL_alsa_audio.c
index 3f990a2..59de607 100644
--- a/src/audio/alsa/SDL_alsa_audio.c
+++ b/src/audio/alsa/SDL_alsa_audio.c
@@ -1009,6 +1009,7 @@ ALSA_Init(SDL_AudioDriverImpl * impl)
impl->FlushCapture = ALSA_FlushCapture;
impl->HasCaptureSupport = SDL_TRUE;
+ impl->SupportsNonPow2Samples = SDL_TRUE;
return SDL_TRUE; /* this audio target is available. */
}
diff --git a/src/audio/coreaudio/SDL_coreaudio.m b/src/audio/coreaudio/SDL_coreaudio.m
index 6717fea..4d35756 100644
--- a/src/audio/coreaudio/SDL_coreaudio.m
+++ b/src/audio/coreaudio/SDL_coreaudio.m
@@ -1173,6 +1173,7 @@ COREAUDIO_Init(SDL_AudioDriverImpl * impl)
impl->ProvidesOwnCallbackThread = SDL_TRUE;
impl->HasCaptureSupport = SDL_TRUE;
+ impl->SupportsNonPow2Samples = SDL_TRUE;
return SDL_TRUE; /* this audio target is available. */
}
diff --git a/src/audio/directsound/SDL_directsound.c b/src/audio/directsound/SDL_directsound.c
index 530d566..885b5f0 100644
--- a/src/audio/directsound/SDL_directsound.c
+++ b/src/audio/directsound/SDL_directsound.c
@@ -668,6 +668,7 @@ DSOUND_Init(SDL_AudioDriverImpl * impl)
impl->GetDefaultAudioInfo = DSOUND_GetDefaultAudioInfo;
impl->HasCaptureSupport = SDL_TRUE;
+ impl->SupportsNonPow2Samples = SDL_TRUE;
return SDL_TRUE; /* this audio target is available. */
}
diff --git a/src/audio/disk/SDL_diskaudio.c b/src/audio/disk/SDL_diskaudio.c
index f1edf50..0a7a395 100644
--- a/src/audio/disk/SDL_diskaudio.c
+++ b/src/audio/disk/SDL_diskaudio.c
@@ -195,6 +195,7 @@ DISKAUDIO_Init(SDL_AudioDriverImpl * impl)
impl->AllowsArbitraryDeviceNames = SDL_TRUE;
impl->HasCaptureSupport = SDL_TRUE;
+ impl->SupportsNonPow2Samples = SDL_TRUE;
return SDL_TRUE; /* this audio target is available. */
}
diff --git a/src/audio/pipewire/SDL_pipewire.c b/src/audio/pipewire/SDL_pipewire.c
index e56344d..0921d26 100644
--- a/src/audio/pipewire/SDL_pipewire.c
+++ b/src/audio/pipewire/SDL_pipewire.c
@@ -1417,6 +1417,7 @@ PIPEWIRE_Init(SDL_AudioDriverImpl *impl)
impl->HasCaptureSupport = SDL_TRUE;
impl->ProvidesOwnCallbackThread = SDL_TRUE;
+ impl->SupportsNonPow2Samples = SDL_TRUE;
return SDL_TRUE;
}
diff --git a/src/audio/pulseaudio/SDL_pulseaudio.c b/src/audio/pulseaudio/SDL_pulseaudio.c
index b61d998..288c3d9 100644
--- a/src/audio/pulseaudio/SDL_pulseaudio.c
+++ b/src/audio/pulseaudio/SDL_pulseaudio.c
@@ -945,6 +945,7 @@ PULSEAUDIO_Init(SDL_AudioDriverImpl * impl)
impl->GetDefaultAudioInfo = PULSEAUDIO_GetDefaultAudioInfo;
impl->HasCaptureSupport = SDL_TRUE;
+ impl->SupportsNonPow2Samples = SDL_TRUE;
return SDL_TRUE; /* this audio target is available. */
}
diff --git a/src/audio/wasapi/SDL_wasapi.c b/src/audio/wasapi/SDL_wasapi.c
index 1223611..80a36bd 100644
--- a/src/audio/wasapi/SDL_wasapi.c
+++ b/src/audio/wasapi/SDL_wasapi.c
@@ -617,6 +617,7 @@ WASAPI_Init(SDL_AudioDriverImpl * impl)
impl->Deinitialize = WASAPI_Deinitialize;
impl->GetDefaultAudioInfo = WASAPI_GetDefaultAudioInfo;
impl->HasCaptureSupport = SDL_TRUE;
+ impl->SupportsNonPow2Samples = SDL_TRUE;
return SDL_TRUE; /* this audio target is available. */
}