From f48d0cc164c02c20a00ff2b0b4a57f54c905b6d6 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Tue, 28 Feb 2023 15:17:47 -0500 Subject: [PATCH] audio: Remove AUDIO_U16* support. It wasn't heavily used, and you can't use memset to silence a U16 buffer. Fixes #7380. --- docs/README-migration.md | 20 ++ include/SDL3/SDL_audio.h | 5 - src/audio/SDL_audio.c | 52 ++--- src/audio/SDL_audio_c.h | 2 - src/audio/SDL_audiocvt.c | 8 - src/audio/SDL_audiotypecvt.c | 281 ---------------------------- src/audio/SDL_mixer.c | 51 ----- src/audio/alsa/SDL_alsa_audio.c | 6 - src/audio/coreaudio/SDL_coreaudio.m | 2 +- src/audio/dsp/SDL_dspaudio.c | 10 - src/audio/netbsd/SDL_netbsdaudio.c | 6 - src/audio/pipewire/SDL_pipewire.c | 6 - src/audio/sndio/SDL_sndioaudio.c | 4 - src/test/SDL_test_common.c | 18 +- test/testautomation_audio.c | 8 +- 15 files changed, 41 insertions(+), 438 deletions(-) diff --git a/docs/README-migration.md b/docs/README-migration.md index ca05e3884..8a6c0416b 100644 --- a/docs/README-migration.md +++ b/docs/README-migration.md @@ -78,6 +78,26 @@ should be changed to: SDL_free(dst_data); ``` +AUDIO_U16, AUDIO_U16LSB, AUDIO_U16MSB, and AUDIO_U16SYS have been removed. They were not heavily used, and one could not memset a buffer in this format to silence with a single byte value. Use a different audio format. + +If you need to convert U16 audio data to a still-supported format at runtime, the fastest, lossless conversion is to AUDIO_S16: + +```c + /* this converts the buffer in-place. The buffer size does not change. */ + Sint16 *audio_ui16_to_si16(Uint16 *buffer, const size_t num_samples) + { + size_t i; + const Uint16 *src = buffer; + Sint16 *dst = (Sint16 *) buffer; + + for (i = 0; i < num_samples; i++) { + dst[i] = (Sint16) (src[i] ^ 0x8000); + } + + return dst; + } +``` + The following functions have been renamed: * SDL_AudioStreamAvailable() => SDL_GetAudioStreamAvailable() diff --git a/include/SDL3/SDL_audio.h b/include/SDL3/SDL_audio.h index ce8529a95..bcac63d1e 100644 --- a/include/SDL3/SDL_audio.h +++ b/include/SDL3/SDL_audio.h @@ -90,11 +90,8 @@ typedef Uint16 SDL_AudioFormat; /* @{ */ #define AUDIO_U8 0x0008 /**< Unsigned 8-bit samples */ #define AUDIO_S8 0x8008 /**< Signed 8-bit samples */ -#define AUDIO_U16LSB 0x0010 /**< Unsigned 16-bit samples */ #define AUDIO_S16LSB 0x8010 /**< Signed 16-bit samples */ -#define AUDIO_U16MSB 0x1010 /**< As above, but big-endian byte order */ #define AUDIO_S16MSB 0x9010 /**< As above, but big-endian byte order */ -#define AUDIO_U16 AUDIO_U16LSB #define AUDIO_S16 AUDIO_S16LSB /* @} */ @@ -121,12 +118,10 @@ typedef Uint16 SDL_AudioFormat; */ /* @{ */ #if SDL_BYTEORDER == SDL_LIL_ENDIAN -#define AUDIO_U16SYS AUDIO_U16LSB #define AUDIO_S16SYS AUDIO_S16LSB #define AUDIO_S32SYS AUDIO_S32LSB #define AUDIO_F32SYS AUDIO_F32LSB #else -#define AUDIO_U16SYS AUDIO_U16MSB #define AUDIO_S16SYS AUDIO_S16MSB #define AUDIO_S32SYS AUDIO_S32MSB #define AUDIO_F32SYS AUDIO_F32MSB diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 23ee40053..8caa26b76 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -847,13 +847,8 @@ static SDL_AudioFormat SDL_ParseAudioFormat(const char *string) return AUDIO_##x CHECK_FMT_STRING(U8); CHECK_FMT_STRING(S8); - CHECK_FMT_STRING(U16LSB); CHECK_FMT_STRING(S16LSB); - CHECK_FMT_STRING(U16MSB); CHECK_FMT_STRING(S16MSB); - CHECK_FMT_STRING(U16SYS); - CHECK_FMT_STRING(S16SYS); - CHECK_FMT_STRING(U16); CHECK_FMT_STRING(S16); CHECK_FMT_STRING(S32LSB); CHECK_FMT_STRING(S32MSB); @@ -1600,30 +1595,18 @@ void SDL_QuitAudio(void) #endif } -#define NUM_FORMATS 10 -static int format_idx; +#define NUM_FORMATS 8 +static int format_idx; /* !!! FIXME: whoa, why are there globals in use here?! */ static int format_idx_sub; static SDL_AudioFormat format_list[NUM_FORMATS][NUM_FORMATS] = { - { AUDIO_U8, AUDIO_S8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, - AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB }, - { AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, - AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB }, - { AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S32LSB, - AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8 }, - { AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S32MSB, - AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8 }, - { AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S32LSB, - AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8 }, - { AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_S32MSB, - AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8 }, - { AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S16LSB, - AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8 }, - { AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S16MSB, - AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8 }, - { AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_S16LSB, - AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8 }, - { AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_S16MSB, - AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8 }, + { AUDIO_U8, AUDIO_S8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB }, + { AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB }, + { AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8 }, + { AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8 }, + { AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U8, AUDIO_S8 }, + { AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U8, AUDIO_S8 }, + { AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U8, AUDIO_S8 }, + { AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U8, AUDIO_S8 }, }; SDL_AudioFormat @@ -1649,20 +1632,7 @@ SDL_GetNextAudioFormat(void) Uint8 SDL_GetSilenceValueForFormat(const SDL_AudioFormat format) { - switch (format) { - /* !!! FIXME: 0x80 isn't perfect for U16, but we can't fit 0x8000 in a - !!! FIXME: byte for SDL_memset() use. This is actually 0.1953 percent - !!! FIXME: off from silence. Maybe just don't use U16. */ - case AUDIO_U16LSB: - case AUDIO_U16MSB: - case AUDIO_U8: - return 0x80; - - default: - break; - } - - return 0x00; + return (format == AUDIO_U8) ? 0x80 : 0x00; } void SDL_CalculateAudioSpec(SDL_AudioSpec *spec) diff --git a/src/audio/SDL_audio_c.h b/src/audio/SDL_audio_c.h index b1d585011..97bef2ade 100644 --- a/src/audio/SDL_audio_c.h +++ b/src/audio/SDL_audio_c.h @@ -66,12 +66,10 @@ typedef void (SDLCALL * SDL_AudioFilter) (struct SDL_AudioCVT * cvt, SDL_AudioFo extern SDL_AudioFilter SDL_Convert_S8_to_F32; extern SDL_AudioFilter SDL_Convert_U8_to_F32; extern SDL_AudioFilter SDL_Convert_S16_to_F32; -extern SDL_AudioFilter SDL_Convert_U16_to_F32; extern SDL_AudioFilter SDL_Convert_S32_to_F32; extern SDL_AudioFilter SDL_Convert_F32_to_S8; extern SDL_AudioFilter SDL_Convert_F32_to_U8; extern SDL_AudioFilter SDL_Convert_F32_to_S16; -extern SDL_AudioFilter SDL_Convert_F32_to_U16; extern SDL_AudioFilter SDL_Convert_F32_to_S32; /** diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index e6c1a8684..ab19b3120 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -441,9 +441,6 @@ static int SDL_BuildAudioTypeCVTToFloat(SDL_AudioCVT *cvt, const SDL_AudioFormat case AUDIO_S16: filter = SDL_Convert_S16_to_F32; break; - case AUDIO_U16: - filter = SDL_Convert_U16_to_F32; - break; case AUDIO_S32: filter = SDL_Convert_S32_to_F32; break; @@ -492,9 +489,6 @@ static int SDL_BuildAudioTypeCVTFromFloat(SDL_AudioCVT *cvt, const SDL_AudioForm case AUDIO_S16: filter = SDL_Convert_F32_to_S16; break; - case AUDIO_U16: - filter = SDL_Convert_F32_to_U16; - break; case AUDIO_S32: filter = SDL_Convert_F32_to_S32; break; @@ -735,9 +729,7 @@ static SDL_bool SDL_IsSupportedAudioFormat(const SDL_AudioFormat fmt) switch (fmt) { case AUDIO_U8: case AUDIO_S8: - case AUDIO_U16LSB: case AUDIO_S16LSB: - case AUDIO_U16MSB: case AUDIO_S16MSB: case AUDIO_S32LSB: case AUDIO_S32MSB: diff --git a/src/audio/SDL_audiotypecvt.c b/src/audio/SDL_audiotypecvt.c index a82243ab1..6a99038fc 100644 --- a/src/audio/SDL_audiotypecvt.c +++ b/src/audio/SDL_audiotypecvt.c @@ -50,12 +50,10 @@ SDL_AudioFilter SDL_Convert_S8_to_F32 = NULL; SDL_AudioFilter SDL_Convert_U8_to_F32 = NULL; SDL_AudioFilter SDL_Convert_S16_to_F32 = NULL; -SDL_AudioFilter SDL_Convert_U16_to_F32 = NULL; SDL_AudioFilter SDL_Convert_S32_to_F32 = NULL; SDL_AudioFilter SDL_Convert_F32_to_S8 = NULL; SDL_AudioFilter SDL_Convert_F32_to_U8 = NULL; SDL_AudioFilter SDL_Convert_F32_to_S16 = NULL; -SDL_AudioFilter SDL_Convert_F32_to_U16 = NULL; SDL_AudioFilter SDL_Convert_F32_to_S32 = NULL; #define DIVBY128 0.0078125f @@ -117,24 +115,6 @@ static void SDLCALL SDL_Convert_S16_to_F32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFo } } -static void SDLCALL SDL_Convert_U16_to_F32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const Uint16 *src = ((const Uint16 *)(cvt->buf + cvt->len_cvt)) - 1; - float *dst = ((float *)(cvt->buf + cvt->len_cvt * 2)) - 1; - int i; - - LOG_DEBUG_CONVERT("AUDIO_U16", "AUDIO_F32"); - - for (i = cvt->len_cvt / sizeof(Uint16); i; --i, --src, --dst) { - *dst = (((float)*src) * DIVBY32768) - 1.0f; - } - - cvt->len_cvt *= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); - } -} - static void SDLCALL SDL_Convert_S32_to_F32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) { const Sint32 *src = (const Sint32 *)cvt->buf; @@ -227,31 +207,6 @@ static void SDLCALL SDL_Convert_F32_to_S16_Scalar(SDL_AudioCVT *cvt, SDL_AudioFo } } -static void SDLCALL SDL_Convert_F32_to_U16_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const float *src = (const float *)cvt->buf; - Uint16 *dst = (Uint16 *)cvt->buf; - int i; - - LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U16"); - - for (i = cvt->len_cvt / sizeof(float); i; --i, ++src, ++dst) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 65535; - } else if (sample <= -1.0f) { - *dst = 0; - } else { - *dst = (Uint16)((sample + 1.0f) * 32767.0f); - } - } - - cvt->len_cvt /= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_U16SYS); - } -} - static void SDLCALL SDL_Convert_F32_to_S32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) { const float *src = (const float *)cvt->buf; @@ -461,60 +416,6 @@ static void SDLCALL SDL_Convert_S16_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioForm } } -static void SDLCALL SDL_Convert_U16_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const Uint16 *src = ((const Uint16 *)(cvt->buf + cvt->len_cvt)) - 1; - float *dst = ((float *)(cvt->buf + cvt->len_cvt * 2)) - 1; - int i; - - LOG_DEBUG_CONVERT("AUDIO_U16", "AUDIO_F32 (using SSE2)"); - - /* Get dst aligned to 16 bytes (since buffer is growing, we don't have to worry about overreading from src) */ - for (i = cvt->len_cvt / sizeof(Sint16); i && (((size_t)(dst - 7)) & 15); --i, --src, --dst) { - *dst = (((float)*src) * DIVBY32768) - 1.0f; - } - - src -= 7; - dst -= 7; /* adjust to read SSE blocks from the start. */ - SDL_assert(!i || !(((size_t)dst) & 15)); - - /* Make sure src is aligned too. */ - if (!(((size_t)src) & 15)) { - /* Aligned! Do SSE blocks as long as we have 16 bytes available. */ - const __m128 divby32768 = _mm_set1_ps(DIVBY32768); - const __m128 minus1 = _mm_set1_ps(-1.0f); - while (i >= 8) { /* 8 * 16-bit */ - const __m128i ints = _mm_load_si128((__m128i const *)src); /* get 8 sint16 into an XMM register. */ - /* treat as int32, shift left to clear every other sint16, then back right with zero-extend. Now sint32. */ - const __m128i a = _mm_srli_epi32(_mm_slli_epi32(ints, 16), 16); - /* right-shift-sign-extend gets us sint32 with the other set of values. */ - const __m128i b = _mm_srli_epi32(ints, 16); - /* Interleave these back into the right order, convert to float, multiply, store. */ - _mm_store_ps(dst, _mm_add_ps(_mm_mul_ps(_mm_cvtepi32_ps(_mm_unpacklo_epi32(a, b)), divby32768), minus1)); - _mm_store_ps(dst + 4, _mm_add_ps(_mm_mul_ps(_mm_cvtepi32_ps(_mm_unpackhi_epi32(a, b)), divby32768), minus1)); - i -= 8; - src -= 8; - dst -= 8; - } - } - - src += 7; - dst += 7; /* adjust for any scalar finishing. */ - - /* Finish off any leftovers with scalar operations. */ - while (i) { - *dst = (((float)*src) * DIVBY32768) - 1.0f; - i--; - src--; - dst--; - } - - cvt->len_cvt *= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); - } -} - static void SDLCALL SDL_Convert_S32_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) { const Sint32 *src = (const Sint32 *)cvt->buf; @@ -745,75 +646,6 @@ static void SDLCALL SDL_Convert_F32_to_S16_SSE2(SDL_AudioCVT *cvt, SDL_AudioForm } } -static void SDLCALL SDL_Convert_F32_to_U16_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const float *src = (const float *)cvt->buf; - Uint16 *dst = (Uint16 *)cvt->buf; - int i; - - LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U16 (using SSE2)"); - - /* Get dst aligned to 16 bytes */ - for (i = cvt->len_cvt / sizeof(float); i && (((size_t)dst) & 15); --i, ++src, ++dst) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 65535; - } else if (sample <= -1.0f) { - *dst = 0; - } else { - *dst = (Uint16)((sample + 1.0f) * 32767.0f); - } - } - - SDL_assert(!i || !(((size_t)dst) & 15)); - - /* Make sure src is aligned too. */ - if (!(((size_t)src) & 15)) { - /* Aligned! Do SSE blocks as long as we have 16 bytes available. */ - /* This calculates differently than the scalar path because SSE2 can't - pack int32 data down to unsigned int16. _mm_packs_epi32 does signed - saturation, so that would corrupt our data. _mm_packus_epi32 exists, - but not before SSE 4.1. So we convert from float to sint16, packing - that down with legit signed saturation, and then xor the top bit - against 1. This results in the correct unsigned 16-bit value, even - though it looks like dark magic. */ - const __m128 mulby32767 = _mm_set1_ps(32767.0f); - const __m128i topbit = _mm_set1_epi16(-32768); - const __m128 one = _mm_set1_ps(1.0f); - const __m128 negone = _mm_set1_ps(-1.0f); - __m128i *mmdst = (__m128i *)dst; - while (i >= 8) { /* 8 * float32 */ - const __m128i ints1 = _mm_cvtps_epi32(_mm_mul_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src)), one), mulby32767)); /* load 4 floats, clamp, convert to sint32 */ - const __m128i ints2 = _mm_cvtps_epi32(_mm_mul_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src + 4)), one), mulby32767)); /* load 4 floats, clamp, convert to sint32 */ - _mm_store_si128(mmdst, _mm_xor_si128(_mm_packs_epi32(ints1, ints2), topbit)); /* pack to sint16, xor top bit, store out. */ - i -= 8; - src += 8; - mmdst++; - } - dst = (Uint16 *)mmdst; - } - - /* Finish off any leftovers with scalar operations. */ - while (i) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 65535; - } else if (sample <= -1.0f) { - *dst = 0; - } else { - *dst = (Uint16)((sample + 1.0f) * 32767.0f); - } - i--; - src++; - dst++; - } - - cvt->len_cvt /= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_U16SYS); - } -} - static void SDLCALL SDL_Convert_F32_to_S32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) { const float *src = (const float *)cvt->buf; @@ -1036,56 +868,6 @@ static void SDLCALL SDL_Convert_S16_to_F32_NEON(SDL_AudioCVT *cvt, SDL_AudioForm } } -static void SDLCALL SDL_Convert_U16_to_F32_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const Uint16 *src = ((const Uint16 *)(cvt->buf + cvt->len_cvt)) - 1; - float *dst = ((float *)(cvt->buf + cvt->len_cvt * 2)) - 1; - int i; - - LOG_DEBUG_CONVERT("AUDIO_U16", "AUDIO_F32 (using NEON)"); - - /* Get dst aligned to 16 bytes (since buffer is growing, we don't have to worry about overreading from src) */ - for (i = cvt->len_cvt / sizeof(Sint16); i && (((size_t)(dst - 7)) & 15); --i, --src, --dst) { - *dst = (((float)*src) * DIVBY32768) - 1.0f; - } - - src -= 7; - dst -= 7; /* adjust to read NEON blocks from the start. */ - SDL_assert(!i || !(((size_t)dst) & 15)); - - /* Make sure src is aligned too. */ - if (!(((size_t)src) & 15)) { - /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ - const float32x4_t divby32768 = vdupq_n_f32(DIVBY32768); - const float32x4_t negone = vdupq_n_f32(-1.0f); - while (i >= 8) { /* 8 * 16-bit */ - const uint16x8_t uints = vld1q_u16((uint16_t const *)src); /* get 8 uint16 into a NEON register. */ - /* split uint16 to two int32, then convert to float, then multiply to normalize, subtract for sign, store. */ - vst1q_f32(dst, vmlaq_f32(negone, vcvtq_f32_u32(vmovl_u16(vget_low_u16(uints))), divby32768)); - vst1q_f32(dst + 4, vmlaq_f32(negone, vcvtq_f32_u32(vmovl_u16(vget_high_u16(uints))), divby32768)); - i -= 8; - src -= 8; - dst -= 8; - } - } - - src += 7; - dst += 7; /* adjust for any scalar finishing. */ - - /* Finish off any leftovers with scalar operations. */ - while (i) { - *dst = (((float)*src) * DIVBY32768) - 1.0f; - i--; - src--; - dst--; - } - - cvt->len_cvt *= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); - } -} - static void SDLCALL SDL_Convert_S32_to_F32_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) { const Sint32 *src = (const Sint32 *)cvt->buf; @@ -1321,67 +1103,6 @@ static void SDLCALL SDL_Convert_F32_to_S16_NEON(SDL_AudioCVT *cvt, SDL_AudioForm } } -static void SDLCALL SDL_Convert_F32_to_U16_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) -{ - const float *src = (const float *)cvt->buf; - Uint16 *dst = (Uint16 *)cvt->buf; - int i; - - LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U16 (using NEON)"); - - /* Get dst aligned to 16 bytes */ - for (i = cvt->len_cvt / sizeof(float); i && (((size_t)dst) & 15); --i, ++src, ++dst) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 65535; - } else if (sample <= -1.0f) { - *dst = 0; - } else { - *dst = (Uint16)((sample + 1.0f) * 32767.0f); - } - } - - SDL_assert(!i || !(((size_t)dst) & 15)); - - /* Make sure src is aligned too. */ - if (!(((size_t)src) & 15)) { - /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ - const float32x4_t one = vdupq_n_f32(1.0f); - const float32x4_t negone = vdupq_n_f32(-1.0f); - const float32x4_t mulby32767 = vdupq_n_f32(32767.0f); - uint16_t *mmdst = (uint16_t *)dst; - while (i >= 8) { /* 8 * float32 */ - const uint32x4_t uints1 = vcvtq_u32_f32(vmulq_f32(vaddq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src)), one), one), mulby32767)); /* load 4 floats, clamp, convert to uint32 */ - const uint32x4_t uints2 = vcvtq_u32_f32(vmulq_f32(vaddq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src + 4)), one), one), mulby32767)); /* load 4 floats, clamp, convert to uint32 */ - vst1q_u16(mmdst, vcombine_u16(vmovn_u32(uints1), vmovn_u32(uints2))); /* narrow to uint16, combine, store out. */ - i -= 8; - src += 8; - mmdst += 8; - } - dst = (Uint16 *)mmdst; - } - - /* Finish off any leftovers with scalar operations. */ - while (i) { - const float sample = *src; - if (sample >= 1.0f) { - *dst = 65535; - } else if (sample <= -1.0f) { - *dst = 0; - } else { - *dst = (Uint16)((sample + 1.0f) * 32767.0f); - } - i--; - src++; - dst++; - } - - cvt->len_cvt /= 2; - if (cvt->filters[++cvt->filter_index]) { - cvt->filters[cvt->filter_index](cvt, AUDIO_U16SYS); - } -} - static void SDLCALL SDL_Convert_F32_to_S32_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) { const float *src = (const float *)cvt->buf; @@ -1453,12 +1174,10 @@ void SDL_ChooseAudioConverters(void) SDL_Convert_S8_to_F32 = SDL_Convert_S8_to_F32_##fntype; \ SDL_Convert_U8_to_F32 = SDL_Convert_U8_to_F32_##fntype; \ SDL_Convert_S16_to_F32 = SDL_Convert_S16_to_F32_##fntype; \ - SDL_Convert_U16_to_F32 = SDL_Convert_U16_to_F32_##fntype; \ SDL_Convert_S32_to_F32 = SDL_Convert_S32_to_F32_##fntype; \ SDL_Convert_F32_to_S8 = SDL_Convert_F32_to_S8_##fntype; \ SDL_Convert_F32_to_U8 = SDL_Convert_F32_to_U8_##fntype; \ SDL_Convert_F32_to_S16 = SDL_Convert_F32_to_S16_##fntype; \ - SDL_Convert_F32_to_U16 = SDL_Convert_F32_to_U16_##fntype; \ SDL_Convert_F32_to_S32 = SDL_Convert_F32_to_S32_##fntype; \ converters_chosen = SDL_TRUE diff --git a/src/audio/SDL_mixer.c b/src/audio/SDL_mixer.c index 0804e000c..337083cac 100644 --- a/src/audio/SDL_mixer.c +++ b/src/audio/SDL_mixer.c @@ -80,7 +80,6 @@ static const Uint8 mix8[] = { /* The volume ranges from 0 - 128 */ #define ADJUST_VOLUME(s, v) ((s) = ((s) * (v)) / SDL_MIX_MAXVOLUME) #define ADJUST_VOLUME_U8(s, v) ((s) = ((((s) - 128) * (v)) / SDL_MIX_MAXVOLUME) + 128) -#define ADJUST_VOLUME_U16(s, v) ((s) = ((((s) - 32768) * (v)) / SDL_MIX_MAXVOLUME) + 32768) int SDL_MixAudioFormat(Uint8 *dst, const Uint8 *src, SDL_AudioFormat format, Uint32 len, int volume) @@ -177,56 +176,6 @@ int SDL_MixAudioFormat(Uint8 *dst, const Uint8 *src, SDL_AudioFormat format, } } break; - case AUDIO_U16LSB: - { - Uint16 src1, src2; - int dst_sample; - const int max_audioval = SDL_MAX_SINT16; - const int min_audioval = SDL_MIN_SINT16; - - len /= 2; - while (len--) { - src1 = SDL_SwapLE16(*(Uint16 *)src); - ADJUST_VOLUME_U16(src1, volume); - src2 = SDL_SwapLE16(*(Uint16 *)dst); - src += 2; - dst_sample = src1 + src2 - 32768 * 2; - if (dst_sample > max_audioval) { - dst_sample = max_audioval; - } else if (dst_sample < min_audioval) { - dst_sample = min_audioval; - } - dst_sample += 32768; - *(Uint16 *)dst = SDL_SwapLE16(dst_sample); - dst += 2; - } - } break; - - case AUDIO_U16MSB: - { - Uint16 src1, src2; - int dst_sample; - const int max_audioval = SDL_MAX_SINT16; - const int min_audioval = SDL_MIN_SINT16; - - len /= 2; - while (len--) { - src1 = SDL_SwapBE16(*(Uint16 *)src); - ADJUST_VOLUME_U16(src1, volume); - src2 = SDL_SwapBE16(*(Uint16 *)dst); - src += 2; - dst_sample = src1 + src2 - 32768 * 2; - if (dst_sample > max_audioval) { - dst_sample = max_audioval; - } else if (dst_sample < min_audioval) { - dst_sample = min_audioval; - } - dst_sample += 32768; - *(Uint16 *)dst = SDL_SwapBE16(dst_sample); - dst += 2; - } - } break; - case AUDIO_S32LSB: { const Uint32 *src32 = (Uint32 *)src; diff --git a/src/audio/alsa/SDL_alsa_audio.c b/src/audio/alsa/SDL_alsa_audio.c index 02f05651f..e25538cd4 100644 --- a/src/audio/alsa/SDL_alsa_audio.c +++ b/src/audio/alsa/SDL_alsa_audio.c @@ -584,12 +584,6 @@ static int ALSA_OpenDevice(_THIS, const char *devname) case AUDIO_S16MSB: format = SND_PCM_FORMAT_S16_BE; break; - case AUDIO_U16LSB: - format = SND_PCM_FORMAT_U16_LE; - break; - case AUDIO_U16MSB: - format = SND_PCM_FORMAT_U16_BE; - break; case AUDIO_S32LSB: format = SND_PCM_FORMAT_S32_LE; break; diff --git a/src/audio/coreaudio/SDL_coreaudio.m b/src/audio/coreaudio/SDL_coreaudio.m index c70a595f0..c089a267a 100644 --- a/src/audio/coreaudio/SDL_coreaudio.m +++ b/src/audio/coreaudio/SDL_coreaudio.m @@ -1067,7 +1067,7 @@ static int COREAUDIO_OpenDevice(_THIS, const char *devname) strdesc->mFramesPerPacket = 1; for (test_format = SDL_GetFirstAudioFormat(this->spec.format); test_format; test_format = SDL_GetNextAudioFormat()) { - /* CoreAudio handles most of SDL's formats natively, but not U16, apparently. */ + /* CoreAudio handles most of SDL's formats natively. */ switch (test_format) { case AUDIO_U8: case AUDIO_S8: diff --git a/src/audio/dsp/SDL_dspaudio.c b/src/audio/dsp/SDL_dspaudio.c index 8a7b9d9d1..b2aac5b39 100644 --- a/src/audio/dsp/SDL_dspaudio.c +++ b/src/audio/dsp/SDL_dspaudio.c @@ -145,16 +145,6 @@ static int DSP_OpenDevice(_THIS, const char *devname) format = AFMT_S8; } break; - case AUDIO_U16LSB: - if (value & AFMT_U16_LE) { - format = AFMT_U16_LE; - } - break; - case AUDIO_U16MSB: - if (value & AFMT_U16_BE) { - format = AFMT_U16_BE; - } - break; #endif default: format = 0; diff --git a/src/audio/netbsd/SDL_netbsdaudio.c b/src/audio/netbsd/SDL_netbsdaudio.c index 464bbf47e..0190d4757 100644 --- a/src/audio/netbsd/SDL_netbsdaudio.c +++ b/src/audio/netbsd/SDL_netbsdaudio.c @@ -250,12 +250,6 @@ static int NETBSDAUDIO_OpenDevice(_THIS, const char *devname) case AUDIO_S16MSB: encoding = AUDIO_ENCODING_SLINEAR_BE; break; - case AUDIO_U16LSB: - encoding = AUDIO_ENCODING_ULINEAR_LE; - break; - case AUDIO_U16MSB: - encoding = AUDIO_ENCODING_ULINEAR_BE; - break; case AUDIO_S32LSB: encoding = AUDIO_ENCODING_SLINEAR_LE; break; diff --git a/src/audio/pipewire/SDL_pipewire.c b/src/audio/pipewire/SDL_pipewire.c index 0a05d598a..adc8804ff 100644 --- a/src/audio/pipewire/SDL_pipewire.c +++ b/src/audio/pipewire/SDL_pipewire.c @@ -915,15 +915,9 @@ static void initialize_spa_info(const SDL_AudioSpec *spec, struct spa_audio_info case AUDIO_S8: info->format = SPA_AUDIO_FORMAT_S8; break; - case AUDIO_U16LSB: - info->format = SPA_AUDIO_FORMAT_U16_LE; - break; case AUDIO_S16LSB: info->format = SPA_AUDIO_FORMAT_S16_LE; break; - case AUDIO_U16MSB: - info->format = SPA_AUDIO_FORMAT_U16_BE; - break; case AUDIO_S16MSB: info->format = SPA_AUDIO_FORMAT_S16_BE; break; diff --git a/src/audio/sndio/SDL_sndioaudio.c b/src/audio/sndio/SDL_sndioaudio.c index 544129f2e..5afc54fee 100644 --- a/src/audio/sndio/SDL_sndioaudio.c +++ b/src/audio/sndio/SDL_sndioaudio.c @@ -291,10 +291,6 @@ static int SNDIO_OpenDevice(_THIS, const char *devname) this->spec.format = AUDIO_S16LSB; } else if ((par.bps == 2) && (par.sig) && (!par.le)) { this->spec.format = AUDIO_S16MSB; - } else if ((par.bps == 2) && (!par.sig) && (par.le)) { - this->spec.format = AUDIO_U16LSB; - } else if ((par.bps == 2) && (!par.sig) && (!par.le)) { - this->spec.format = AUDIO_U16MSB; } else if ((par.bps == 1) && (par.sig)) { this->spec.format = AUDIO_S8; } else if ((par.bps == 1) && (!par.sig)) { diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c index 818efcfbf..2a45a1506 100644 --- a/src/test/SDL_test_common.c +++ b/src/test/SDL_test_common.c @@ -39,8 +39,9 @@ static const char *video_usage[] = { "[--usable-bounds]" }; +/* !!! FIXME: Float32? Sint32? */ static const char *audio_usage[] = { - "[--rate N]", "[--format U8|S8|U16|U16LE|U16BE|S16|S16LE|S16BE]", + "[--rate N]", "[--format U8|S8|S16|S16LE|S16BE]", "[--channels N]", "[--samples N]" }; @@ -542,18 +543,6 @@ int SDLTest_CommonArg(SDLTest_CommonState *state, int index) state->audiospec.format = AUDIO_S8; return 2; } - if (SDL_strcasecmp(argv[index], "U16") == 0) { - state->audiospec.format = AUDIO_U16; - return 2; - } - if (SDL_strcasecmp(argv[index], "U16LE") == 0) { - state->audiospec.format = AUDIO_U16LSB; - return 2; - } - if (SDL_strcasecmp(argv[index], "U16BE") == 0) { - state->audiospec.format = AUDIO_U16MSB; - return 2; - } if (SDL_strcasecmp(argv[index], "S16") == 0) { state->audiospec.format = AUDIO_S16; return 2; @@ -566,6 +555,9 @@ int SDLTest_CommonArg(SDLTest_CommonState *state, int index) state->audiospec.format = AUDIO_S16MSB; return 2; } + + /* !!! FIXME: Float32? Sint32? */ + return -1; } if (SDL_strcasecmp(argv[index], "--channels") == 0) { diff --git a/test/testautomation_audio.c b/test/testautomation_audio.c index 130dc7f89..2fefb7e7b 100644 --- a/test/testautomation_audio.c +++ b/test/testautomation_audio.c @@ -502,11 +502,11 @@ static int audio_printCurrentAudioDriver(void *arg) /* Definition of all formats, channels, and frequencies used to test audio conversions */ static const int g_numAudioFormats = 18; -static SDL_AudioFormat g_audioFormats[] = { AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S16SYS, AUDIO_S16, AUDIO_U16LSB, - AUDIO_U16MSB, AUDIO_U16SYS, AUDIO_U16, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_S32SYS, AUDIO_S32, +static SDL_AudioFormat g_audioFormats[] = { AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S16SYS, AUDIO_S16, + AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_S32SYS, AUDIO_S32, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_F32SYS, AUDIO_F32 }; -static const char *g_audioFormatsVerbose[] = { "AUDIO_S8", "AUDIO_U8", "AUDIO_S16LSB", "AUDIO_S16MSB", "AUDIO_S16SYS", "AUDIO_S16", "AUDIO_U16LSB", - "AUDIO_U16MSB", "AUDIO_U16SYS", "AUDIO_U16", "AUDIO_S32LSB", "AUDIO_S32MSB", "AUDIO_S32SYS", "AUDIO_S32", +static const char *g_audioFormatsVerbose[] = { "AUDIO_S8", "AUDIO_U8", "AUDIO_S16LSB", "AUDIO_S16MSB", "AUDIO_S16SYS", "AUDIO_S16", + "AUDIO_S32LSB", "AUDIO_S32MSB", "AUDIO_S32SYS", "AUDIO_S32", "AUDIO_F32LSB", "AUDIO_F32MSB", "AUDIO_F32SYS", "AUDIO_F32" }; static const int g_numAudioChannels = 4; static Uint8 g_audioChannels[] = { 1, 2, 4, 6 };