audio: Remove AUDIO_U16* support.
It wasn't heavily used, and you can't use memset to silence a U16 buffer. Fixes #7380.main
parent
941a603665
commit
f48d0cc164
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 };
|
||||
|
|
Loading…
Reference in New Issue