21 #include "../SDL_internal.h" 31 #include "../SDL_dataqueue.h" 35 #define HAVE_SSE3_INTRINSICS 1 38 #if HAVE_SSE3_INTRINSICS 43 float *
dst = (
float *) cvt->
buf;
44 const float *
src = dst;
52 if ((((
size_t) dst) & 15) == 0) {
54 const __m128 divby2 = _mm_set1_ps(0.5
f);
56 _mm_store_ps(dst, _mm_mul_ps(_mm_hadd_ps(_mm_load_ps(
src), _mm_load_ps(
src+4)), divby2));
57 i -= 4;
src += 8; dst += 4;
63 *dst = (
src[0] +
src[1]) * 0.5
f;
78 float *dst = (
float *) cvt->
buf;
79 const float *
src = dst;
86 *(dst++) = (
src[0] +
src[1]) * 0.5f;
100 float *dst = (
float *) cvt->
buf;
101 const float *
src = dst;
108 for (
i = cvt->
len_cvt / (sizeof (
float) * 6);
i; --
i,
src += 6, dst += 2) {
109 const float front_center_distributed = src[2] * 0.5f;
110 dst[0] = (src[0] + front_center_distributed + src[4]) / 2.5
f;
111 dst[1] = (src[1] + front_center_distributed + src[5]) / 2.5
f;
125 float *dst = (
float *) cvt->
buf;
126 const float *
src = dst;
132 for (
i = cvt->
len_cvt / (sizeof (
float) * 4);
i; --
i,
src += 4, dst += 2) {
133 dst[0] = (src[0] + src[2]) * 0.5
f;
134 dst[1] = (src[1] + src[3]) * 0.5
f;
148 float *dst = (
float *) cvt->
buf;
149 const float *
src = dst;
155 for (
i = cvt->
len_cvt / (sizeof (
float) * 8);
i; --
i,
src += 8, dst += 6) {
156 const float surround_left_distributed = src[6] * 0.5f;
157 const float surround_right_distributed = src[7] * 0.5f;
158 dst[0] = (src[0] + surround_left_distributed) / 1.5
f;
159 dst[1] = (src[1] + surround_right_distributed) / 1.5
f;
160 dst[2] = src[2] / 1.5f;
161 dst[3] = src[3] / 1.5f;
162 dst[4] = (src[4] + surround_left_distributed) / 1.5
f;
163 dst[5] = (src[5] + surround_right_distributed) / 1.5
f;
178 float *dst = (
float *) cvt->
buf;
179 const float *
src = dst;
187 for (
i = cvt->
len_cvt / (sizeof (
float) * 6);
i; --
i,
src += 6, dst += 4) {
188 const float front_center_distributed = src[2] * 0.5f;
189 dst[0] = (src[0] + front_center_distributed) / 1.5
f;
190 dst[1] = (src[1] + front_center_distributed) / 1.5
f;
191 dst[2] = src[4] / 1.5f;
192 dst[3] = src[5] / 1.5f;
207 const float *
src = (
const float *) (cvt->
buf + cvt->
len_cvt);
208 float *dst = (
float *) (cvt->
buf + cvt->
len_cvt * 2);
214 for (i = cvt->
len_cvt / sizeof (
float);
i; --
i) {
217 dst[0] = dst[1] = *
src;
233 const float *
src = (
const float *) (cvt->
buf + cvt->
len_cvt);
234 float *dst = (
float *) (cvt->
buf + cvt->
len_cvt * 3);
239 for (i = cvt->
len_cvt / (
sizeof(
float) * 2); i; --i) {
244 ce = (lf + rf) * 0.5
f;
246 dst[0] = lf + (lf - ce);
247 dst[1] = rf + (rf - ce);
266 float lf, rf, lb, rb, ce;
267 const float *
src = (
const float *) (cvt->
buf + cvt->
len_cvt);
268 float *dst = (
float *) (cvt->
buf + cvt->
len_cvt * 3 / 2);
274 for (i = cvt->
len_cvt / (
sizeof(
float) * 4); i; --i) {
281 ce = (lf + rf) * 0.5
f;
283 dst[0] = lf + (lf - ce);
284 dst[1] = rf + (rf - ce);
302 const float *
src = (
const float *) (cvt->
buf + cvt->
len_cvt);
303 float *dst = (
float *) (cvt->
buf + cvt->
len_cvt * 2);
310 for (i = cvt->
len_cvt / (
sizeof(
float) * 2); i; --i) {
332 float lf, rf, lb, rb, ls, rs;
334 const float *
src = (
const float *) (cvt->
buf + cvt->
len_cvt);
335 float *dst = (
float *) (cvt->
buf + cvt->
len_cvt * 4 / 3);
341 for (i = cvt->
len_cvt / (
sizeof(
float) * 6); i; --i) {
348 ls = (lf + lb) * 0.5
f;
349 rs = (rf + rb) * 0.5
f;
375 #define RESAMPLER_ZERO_CROSSINGS 5 376 #define RESAMPLER_BITS_PER_SAMPLE 16 377 #define RESAMPLER_SAMPLES_PER_ZERO_CROSSING (1 << ((RESAMPLER_BITS_PER_SAMPLE / 2) + 1)) 378 #define RESAMPLER_FILTER_SIZE ((RESAMPLER_SAMPLES_PER_ZERO_CROSSING * RESAMPLER_ZERO_CROSSINGS) + 1) 384 const double xdiv2 = x / 2.0;
391 if (diff < 1.0
e-21f) {
406 const int lenm1 = tablelen - 1;
407 const int lenm1div2 = lenm1 / 2;
411 for (i = 1; i < tablelen; i++) {
413 table[tablelen -
i] = (float) kaiser;
416 for (i = 1; i < tablelen; i++) {
419 diffs[i - 1] = table[
i] - table[i - 1];
433 if (!ResamplerFilter) {
435 const double dB = 80.0;
436 const double beta = 0.1102 * (dB - 8.7);
439 ResamplerFilter = (
float *)
SDL_malloc(alloclen);
440 if (!ResamplerFilter) {
445 ResamplerFilterDifference = (
float *)
SDL_malloc(alloclen);
446 if (!ResamplerFilterDifference) {
448 ResamplerFilter =
NULL;
462 SDL_free(ResamplerFilterDifference);
463 ResamplerFilter =
NULL;
464 ResamplerFilterDifference =
NULL;
476 float *lpadding,
float *rpadding,
const float *inbuf,
477 const int inbuflen,
float *outbuf,
const int outbuflen)
479 const float outtimeincr = 1.0f / ((float) outrate);
480 const float ratio = ((float) outrate) / ((float) inrate);
482 const int framelen = chans * (int)
sizeof (
float);
483 const int inframes = inbuflen / framelen;
484 const int wantedoutframes = (int) ((inbuflen / framelen) * ratio);
485 const int maxoutframes = outbuflen / framelen;
486 const int outframes = (wantedoutframes < maxoutframes) ? wantedoutframes : maxoutframes;
488 float outtime = 0.0f;
491 for (i = 0; i < outframes; i++) {
492 const int srcindex = (int) (outtime * inrate);
493 const float finrate = (float) inrate;
494 const float intime = ((float) srcindex) / finrate;
495 const float innexttime = ((float) (srcindex + 1)) / finrate;
497 const float interpolation1 = 1.0f - (innexttime - outtime) / (innexttime - intime);
499 const float interpolation2 = 1.0f - interpolation1;
502 for (chan = 0; chan < chans; chan++) {
503 float outsample = 0.0f;
508 const int srcframe = srcindex -
j;
510 const float insample = (srcframe < 0) ? lpadding[((paddinglen + srcframe) * chans) + chan] : inbuf[(srcframe * chans) + chan];
511 outsample += (insample * (ResamplerFilter[filterindex1 + (j *
RESAMPLER_SAMPLES_PER_ZERO_CROSSING)] + (interpolation1 * ResamplerFilterDifference[filterindex1 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)])));
515 const int srcframe = srcindex + 1 +
j;
517 const float insample = (srcframe >= inframes) ? rpadding[((srcframe - inframes) * chans) + chan] : inbuf[(srcframe * chans) + chan];
518 outsample += (insample * (ResamplerFilter[filterindex2 + (j *
RESAMPLER_SAMPLES_PER_ZERO_CROSSING)] + (interpolation2 * ResamplerFilterDifference[filterindex2 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)])));
520 *(dst++) = outsample;
523 outtime += outtimeincr;
526 return outframes * chans *
sizeof (float);
537 return SDL_SetError(
"No buffer allocated for conversion");
556 printf(
"Converting byte order\n");
560 #define CASESWAP(b) \ 562 Uint##b *ptr = (Uint##b *) cvt->buf; \ 564 for (i = cvt->len_cvt / sizeof (*ptr); i; --i, ++ptr) { \ 565 *ptr = SDL_Swap##b(*ptr); \ 576 default:
SDL_assert(!
"unhandled byteswap datatype!");
break;
582 format &= ~SDL_AUDIO_MASK_ENDIAN;
596 if (filter ==
NULL) {
618 const Uint16 dst_bitsize = 32;
627 default:
SDL_assert(!
"Unexpected audio format!");
break;
631 return SDL_SetError(
"No conversion from source format to float available");
637 if (src_bitsize < dst_bitsize) {
638 const int mult = (dst_bitsize / src_bitsize);
641 }
else if (src_bitsize > dst_bitsize) {
642 cvt->
len_ratio /= (src_bitsize / dst_bitsize);
658 const Uint16 src_bitsize = 32;
666 default:
SDL_assert(!
"Unexpected audio format!");
break;
670 return SDL_SetError(
"No conversion from float to destination format available");
676 if (src_bitsize < dst_bitsize) {
677 const int mult = (dst_bitsize / src_bitsize);
680 }
else if (src_bitsize > dst_bitsize) {
681 cvt->
len_ratio /= (src_bitsize / dst_bitsize);
704 const float *
src = (
const float *) cvt->
buf;
705 const int srclen = cvt->
len_cvt;
709 float *dst = (
float *) (cvt->
buf + srclen);
710 const int dstlen = (cvt->
len * cvt->
len_mult) - srclen;
722 SDL_memset(padding,
'\0', paddingsamples *
sizeof (
float));
739 #define RESAMPLER_FUNCS(chans) \ 740 static void SDLCALL \ 741 SDL_ResampleCVT_c##chans(SDL_AudioCVT *cvt, SDL_AudioFormat format) { \ 742 SDL_ResampleCVT(cvt, chans, format); \ 749 #undef RESAMPLER_FUNCS 754 switch (dst_channels) {
755 case 1:
return SDL_ResampleCVT_c1;
756 case 2:
return SDL_ResampleCVT_c2;
757 case 4:
return SDL_ResampleCVT_c4;
758 case 6:
return SDL_ResampleCVT_c6;
759 case 8:
return SDL_ResampleCVT_c8;
772 if (src_rate == dst_rate) {
777 if (filter ==
NULL) {
778 return SDL_SetError(
"No conversion available for these rates");
799 if (src_rate < dst_rate) {
800 const double mult = ((double) dst_rate) / ((double) src_rate);
804 cvt->
len_ratio /= ((double) src_rate) / ((double) dst_rate);
883 }
else if (src_rate == 0) {
885 }
else if (dst_rate == 0) {
890 printf(
"Build format %04x->%04x, channels %u->%u, rate %d->%d\n",
891 src_fmt, dst_fmt, src_channels, dst_channels, src_rate, dst_rate);
902 cvt->
rate_incr = ((double) dst_rate) / ((double) src_rate);
922 if (src_rate == dst_rate && src_channels == dst_channels) {
923 if (src_fmt == dst_fmt) {
943 if (src_channels < dst_channels) {
946 if ((src_channels == 1) && (dst_channels > 1)) {
955 if ((src_channels == 2) && (dst_channels >= 6)) {
964 if ((src_channels == 4) && (dst_channels >= 6)) {
973 if ((src_channels == 6) && (dst_channels == 8)) {
984 if ((src_channels == 2) && (dst_channels == 4)) {
992 }
else if (src_channels > dst_channels) {
996 if ((src_channels == 8) && (dst_channels <= 6)) {
1004 if ((src_channels == 6) && (dst_channels <= 2)) {
1012 if ((src_channels == 6) && (dst_channels == 4)) {
1020 if ((src_channels == 4) && (dst_channels <= 2)) {
1028 if ((src_channels == 2) && (dst_channels == 1)) {
1031 #if HAVE_SSE3_INTRINSICS 1033 filter = SDL_ConvertStereoToMono_SSE3;
1050 if (src_channels != dst_channels) {
1117 offset = ((
size_t) ptr) & 15;
1118 return offset ? ptr + (16 -
offset) : ptr;
1121 #ifdef HAVE_LIBSAMPLERATE_H 1123 SDL_ResampleAudioStream_SRC(
SDL_AudioStream *stream,
const void *_inbuf,
const int inbuflen,
void *_outbuf,
const int outbuflen)
1125 const float *inbuf = (
const float *) _inbuf;
1126 float *outbuf = (
float *) _outbuf;
1132 if (inbuf == ((
const float *) outbuf)) {
1139 inbuf = (
const float *) (ptr + outbuflen);
1140 outbuf = (
float *) ptr;
1143 data.data_in = (
float *)inbuf;
1144 data.input_frames = inbuflen / framelen;
1145 data.input_frames_used = 0;
1147 data.data_out = outbuf;
1148 data.output_frames = outbuflen / framelen;
1150 data.end_of_input = 0;
1153 result = SRC_src_process(
state, &data);
1155 SDL_SetError(
"src_process() failed: %s", SRC_src_strerror(result));
1160 SDL_assert(data.input_frames_used == data.input_frames);
1176 SRC_src_delete(state);
1191 if (SRC_available) {
1194 SDL_SetError(
"src_new() failed: %s", SRC_src_strerror(result));
1199 SDL_CleanupAudioStreamResampler_SRC(stream);
1216 const float *inbuf = (
const float *) _inbuf;
1217 float *outbuf = (
float *) _outbuf;
1219 const int inrate = stream->
src_rate;
1220 const int outrate = stream->
dst_rate;
1222 const int paddingbytes = paddingsamples *
sizeof (float);
1227 if (inbuf == ((
const float *) outbuf)) {
1234 inbuf = (
const float *) (ptr + outbuflen);
1235 outbuf = (
float *) ptr;
1251 SDL_memcpy(lpadding, ((
const Uint8 *) inbuf) + (inbuflen - paddingbytes), paddingbytes);
1260 const int inrate = stream->
src_rate;
1261 const int outrate = stream->
dst_rate;
1294 pre_resample_channels =
SDL_min(src_channels, dst_channels);
1306 retval->
rate_incr = ((double) dst_rate) / ((double) src_rate);
1309 if (src_rate == dst_rate) {
1323 #ifdef HAVE_LIBSAMPLERATE_H 1324 SetupLibSampleRateResampling(retval);
1328 const int chans = (int) pre_resample_channels;
1357 if (!retval->
queue) {
1368 int buflen = (int) _buflen;
1369 const void *origbuf =
buf;
1383 }
else if (buflen == 0) {
1386 return SDL_SetError(
"Can't add partial sample frames");
1392 if (workbuf ==
NULL) {
1409 if (workbuf ==
NULL) {
1414 if (buf != origbuf) {
1417 buflen = stream->
resampler_func(stream, buf, buflen, workbuf, workbuflen);
1425 if (workbuf ==
NULL) {
1428 if (buf == origbuf) {
1465 }
else if (len == 0) {
1468 return SDL_SetError(
"Can't request partial sample frames");
static SDL_AudioFilter ChooseCVTResampler(const int dst_channels)
static int ResamplerPadding(const int inrate, const int outrate)
int SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, const Uint32 len)
#define RESAMPLER_SAMPLES_PER_ZERO_CROSSING
#define LOG_DEBUG_CONVERT(from, to)
int SDL_AudioStreamAvailable(SDL_AudioStream *stream)
void SDL_FreeResampleFilter(void)
void(* SDL_CleanupAudioStreamResamplerFunc)(SDL_AudioStream *stream)
#define SDL_AUDIOCVT_MAX_FILTERS
Upper limit of filters in SDL_AudioCVT.
static void SDL_Convert71To51(SDL_AudioCVT *cvt, SDL_AudioFormat format)
GLenum GLsizei GLenum GLenum const void * table
int SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, const Uint32 _buflen)
SDL_AudioCVT cvt_before_resampling
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 Uint32 * e
int SDL_WriteToDataQueue(SDL_DataQueue *queue, const void *_data, const size_t _len)
int src_sample_frame_size
#define SDL_AUDIO_ISBIGENDIAN(x)
GLint GLint GLint GLint GLint x
void SDL_ChooseAudioConverters(void)
SDL_AudioCVT cvt_after_resampling
SDL_AudioFormat src_format
SDL_AudioFilter SDL_Convert_F32_to_S32
static void SDL_Convert51ToStereo(SDL_AudioCVT *cvt, SDL_AudioFormat format)
static SDL_bool SDL_SupportedAudioFormat(const SDL_AudioFormat fmt)
SDL_AudioFilter SDL_Convert_S16_to_F32
SDL_AudioFilter SDL_Convert_U16_to_F32
SDL_DataQueue * SDL_NewDataQueue(const size_t _packetlen, const size_t initialslack)
static void SDL_ConvertStereoToQuad(SDL_AudioCVT *cvt, SDL_AudioFormat format)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
static int SDL_ResampleAudio(const int chans, const int inrate, const int outrate, float *lpadding, float *rpadding, const float *inbuf, const int inbuflen, float *outbuf, const int outbuflen)
Uint16 SDL_AudioFormat
Audio format flags.
static SDL_SpinLock ResampleFilterSpinlock
static float * ResamplerFilter
void SDL_FreeAudioStream(SDL_AudioStream *stream)
static void SDL_Convert51ToQuad(SDL_AudioCVT *cvt, SDL_AudioFormat format)
#define SDL_AUDIO_MASK_ENDIAN
#define SDL_InvalidParamError(param)
static int SDL_BuildAudioTypeCVTToFloat(SDL_AudioCVT *cvt, const SDL_AudioFormat src_fmt)
static void SDL_Convert_Byteswap(SDL_AudioCVT *cvt, SDL_AudioFormat format)
static void kaiser_and_sinc(float *table, float *diffs, const int tablelen, const double beta)
static Uint8 * EnsureStreamBufferSize(SDL_AudioStream *stream, const int newlen)
static float * ResamplerFilterDifference
A structure to hold a set of audio conversion filters and buffers.
static double bessel(const double x)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
#define SDL_AUDIO_ISFLOAT(x)
int dst_sample_frame_size
SDL_AudioFormat dst_format
static void SDL_Convert51To71(SDL_AudioCVT *cvt, SDL_AudioFormat format)
static void SDL_ResetAudioStreamResampler(SDL_AudioStream *stream)
static int SDL_BuildAudioResampleCVT(SDL_AudioCVT *cvt, const int dst_channels, const int src_rate, const int dst_rate)
void * SDL_calloc(size_t nmemb, size_t size)
int SDL_PrepareResampleFilter(void)
SDL_AudioFilter filters[SDL_AUDIOCVT_MAX_FILTERS+1]
#define SDL_stack_alloc(type, count)
#define SDL_AUDIO_BITSIZE(x)
SDL_ResampleAudioStreamFunc resampler_func
void(* SDL_ResetAudioStreamResamplerFunc)(SDL_AudioStream *stream)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
int SDL_ConvertAudio(SDL_AudioCVT *cvt)
static void SDL_ResampleCVT(SDL_AudioCVT *cvt, const int chans, const SDL_AudioFormat format)
SDL_AudioFilter SDL_Convert_F32_to_S8
SDL_CleanupAudioStreamResamplerFunc cleanup_resampler_func
size_t SDL_ReadFromDataQueue(SDL_DataQueue *queue, void *_buf, const size_t _len)
static void SDL_ConvertQuadToStereo(SDL_AudioCVT *cvt, SDL_AudioFormat format)
SDL_AudioStream * SDL_NewAudioStream(const SDL_AudioFormat src_format, const Uint8 src_channels, const int src_rate, const SDL_AudioFormat dst_format, const Uint8 dst_channels, const int dst_rate)
#define RESAMPLER_FUNCS(chans)
SDL_AudioFormat src_format
GLenum GLuint GLenum GLsizei const GLchar * buf
static int SDL_ResampleAudioStream(SDL_AudioStream *stream, const void *_inbuf, const int inbuflen, void *_outbuf, const int outbuflen)
#define RESAMPLER_FILTER_SIZE
SDL_ResetAudioStreamResamplerFunc reset_resampler_func
SDL_AudioFilter SDL_Convert_F32_to_U8
void(* SDL_AudioFilter)(struct SDL_AudioCVT *cvt, SDL_AudioFormat format)
SDL_AudioFilter SDL_Convert_S8_to_F32
int SDL_BuildAudioCVT(SDL_AudioCVT *cvt, SDL_AudioFormat src_fmt, Uint8 src_channels, int src_rate, SDL_AudioFormat dst_fmt, Uint8 dst_channels, int dst_rate)
static void SDL_ConvertQuadTo51(SDL_AudioCVT *cvt, SDL_AudioFormat format)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
#define SDL_assert(condition)
SDL_AudioFilter SDL_Convert_U8_to_F32
#define SDL_OutOfMemory()
static SDL_bool SDL_SupportedChannelCount(const int channels)
void SDL_AudioStreamClear(SDL_AudioStream *stream)
void SDL_ClearDataQueue(SDL_DataQueue *queue, const size_t slack)
SDL_AudioFormat dst_format
Uint8 pre_resample_channels
SDL_AudioFilter SDL_Convert_F32_to_U16
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
static void SDL_ConvertMonoToStereo(SDL_AudioCVT *cvt, SDL_AudioFormat format)
size_t SDL_CountDataQueue(SDL_DataQueue *queue)
static void SDL_CleanupAudioStreamResampler(SDL_AudioStream *stream)
static int SDL_AddAudioCVTFilter(SDL_AudioCVT *cvt, const SDL_AudioFilter filter)
static int SDL_BuildAudioTypeCVTFromFloat(SDL_AudioCVT *cvt, const SDL_AudioFormat dst_fmt)
static void SDL_ConvertStereoTo51(SDL_AudioCVT *cvt, SDL_AudioFormat format)
void SDL_FreeDataQueue(SDL_DataQueue *queue)
#define SDL_stack_free(data)
SDL_AudioFilter SDL_Convert_S32_to_F32
SDL_AudioFilter SDL_Convert_F32_to_S16
static void SDL_ConvertStereoToMono(SDL_AudioCVT *cvt, SDL_AudioFormat format)
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
int(* SDL_ResampleAudioStreamFunc)(SDL_AudioStream *stream, const void *inbuf, const int inbuflen, void *outbuf, const int outbuflen)