/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "../SDL_internal.h"

/* Functions for audio drivers to perform runtime conversion of audio format */

#include "SDL_audio.h"
#include "SDL_audio_c.h"

#include "SDL_loadso.h"
#include "SDL_assert.h"
#include "../SDL_dataqueue.h"
#include "SDL_cpuinfo.h"

#ifdef __SSE3__
#define HAVE_SSE3_INTRINSICS 1
#endif

#if HAVE_SSE3_INTRINSICS
/* Effectively mix right and left channels into a single channel */
static void SDLCALL
SDL_ConvertStereoToMono_SSE3(SDL_AudioCVT * cvt, SDL_AudioFormat format)
{
    float *dst = (float *) cvt->buf;
    const float *src = dst;
    int i = cvt->len_cvt / 8;

    LOG_DEBUG_CONVERT("stereo", "mono (using SSE3)");
    SDL_assert(format == AUDIO_F32SYS);

    /* We can only do this if dst is aligned to 16 bytes; since src is the
       same pointer and it moves by 2, it can't be forcibly aligned. */
    if ((((size_t) dst) & 15) == 0) {
        /* Aligned! Do SSE blocks as long as we have 16 bytes available. */
        const __m128 divby2 = _mm_set1_ps(0.5f);
        while (i >= 4) {   /* 4 * float32 */
            _mm_store_ps(dst, _mm_mul_ps(_mm_hadd_ps(_mm_load_ps(src), _mm_load_ps(src+4)), divby2));
            i -= 4; src += 8; dst += 4;
        }
    }

    /* Finish off any leftovers with scalar operations. */
    while (i) {
        *dst = (src[0] + src[1]) * 0.5f;
        dst++; i--; src += 2;
    }

    cvt->len_cvt /= 2;
    if (cvt->filters[++cvt->filter_index]) {
        cvt->filters[cvt->filter_index] (cvt, format);
    }
}
#endif

/* Effectively mix right and left channels into a single channel */
static void SDLCALL
SDL_ConvertStereoToMono(SDL_AudioCVT * cvt, SDL_AudioFormat format)
{
    float *dst = (float *) cvt->buf;
    const float *src = dst;
    int i;

    LOG_DEBUG_CONVERT("stereo", "mono");
    SDL_assert(format == AUDIO_F32SYS);

    for (i = cvt->len_cvt / 8; i; --i, src += 2) {
        *(dst++) = (src[0] + src[1]) * 0.5f;
    }

    cvt->len_cvt /= 2;
    if (cvt->filters[++cvt->filter_index]) {
        cvt->filters[cvt->filter_index] (cvt, format);
    }
}


/* Convert from 5.1 to stereo. Average left and right, discard subwoofer. */
static void SDLCALL
SDL_Convert51ToStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format)
{
    float *dst = (float *) cvt->buf;
    const float *src = dst;
    int i;

    LOG_DEBUG_CONVERT("5.1", "stereo");
    SDL_assert(format == AUDIO_F32SYS);

    /* this assumes FL+FR+FC+subwoof+BL+BR layout. */
    for (i = cvt->len_cvt / (sizeof (float) * 6); i; --i, src += 6, dst += 2) {
        const double front_center = (double) src[2];
        dst[0] = (float) ((src[0] + front_center + src[4]) / 3.0);  /* left */
        dst[1] = (float) ((src[1] + front_center + src[5]) / 3.0);  /* right */
    }

    cvt->len_cvt /= 3;
    if (cvt->filters[++cvt->filter_index]) {
        cvt->filters[cvt->filter_index] (cvt, format);
    }
}


/* Convert from 5.1 to quad */
static void SDLCALL
SDL_Convert51ToQuad(SDL_AudioCVT * cvt, SDL_AudioFormat format)
{
    float *dst = (float *) cvt->buf;
    const float *src = dst;
    int i;

    LOG_DEBUG_CONVERT("5.1", "quad");
    SDL_assert(format == AUDIO_F32SYS);

    /* assumes quad is FL+FR+BL+BR layout and 5.1 is FL+FR+FC+subwoof+BL+BR */
    for (i = cvt->len_cvt / (sizeof (float) * 6); i; --i, src += 6, dst += 4) {
        /* FIXME: this is a good candidate for SIMD. */
        const double front_center = (double) src[2];
        dst[0] = (float) ((src[0] + front_center) * 0.5);  /* FL */
        dst[1] = (float) ((src[1] + front_center) * 0.5);  /* FR */
        dst[2] = (float) ((src[4] + front_center) * 0.5);  /* BL */
        dst[3] = (float) ((src[5] + front_center) * 0.5);  /* BR */
    }

    cvt->len_cvt /= 6;
    cvt->len_cvt *= 4;
    if (cvt->filters[++cvt->filter_index]) {
        cvt->filters[cvt->filter_index] (cvt, format);
    }
}


/* Duplicate a mono channel to both stereo channels */
static void SDLCALL
SDL_ConvertMonoToStereo(SDL_AudioCVT * cvt, SDL_AudioFormat format)
{
    const float *src = (const float *) (cvt->buf + cvt->len_cvt);
    float *dst = (float *) (cvt->buf + cvt->len_cvt * 2);
    int i;

    LOG_DEBUG_CONVERT("mono", "stereo");
    SDL_assert(format == AUDIO_F32SYS);

    for (i = cvt->len_cvt / sizeof (float); i; --i) {
        src--;
        dst -= 2;
        dst[0] = dst[1] = *src;
    }

    cvt->len_cvt *= 2;
    if (cvt->filters[++cvt->filter_index]) {
        cvt->filters[cvt->filter_index] (cvt, format);
    }
}


/* Duplicate a stereo channel to a pseudo-5.1 stream */
static void SDLCALL
SDL_ConvertStereoTo51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
{
    int i;
    float lf, rf, ce;
    const float *src = (const float *) (cvt->buf + cvt->len_cvt);
    float *dst = (float *) (cvt->buf + cvt->len_cvt * 3);

    LOG_DEBUG_CONVERT("stereo", "5.1");
    SDL_assert(format == AUDIO_F32SYS);

    for (i = cvt->len_cvt / 8; i; --i) {
        dst -= 6;
        src -= 2;
        lf = src[0];
        rf = src[1];
        ce = (lf + rf) * 0.5f;
        dst[0] = lf + (lf - ce);  /* FL */
        dst[1] = rf + (rf - ce);  /* FR */
        dst[2] = ce;  /* FC */
        dst[3] = ce;  /* !!! FIXME: wrong! This is the subwoofer. */
        dst[4] = lf;  /* BL */
        dst[5] = rf;  /* BR */
    }

    cvt->len_cvt *= 3;
    if (cvt->filters[++cvt->filter_index]) {
        cvt->filters[cvt->filter_index] (cvt, format);
    }
}


/* Duplicate a stereo channel to a pseudo-4.0 stream */
static void SDLCALL
SDL_ConvertStereoToQuad(SDL_AudioCVT * cvt, SDL_AudioFormat format)
{
    const float *src = (const float *) (cvt->buf + cvt->len_cvt);
    float *dst = (float *) (cvt->buf + cvt->len_cvt * 2);
    float lf, rf;
    int i;

    LOG_DEBUG_CONVERT("stereo", "quad");
    SDL_assert(format == AUDIO_F32SYS);

    for (i = cvt->len_cvt / 8; i; --i) {
        dst -= 4;
        src -= 2;
        lf = src[0];
        rf = src[1];
        dst[0] = lf;  /* FL */
        dst[1] = rf;  /* FR */
        dst[2] = lf;  /* BL */
        dst[3] = rf;  /* BR */
    }

    cvt->len_cvt *= 2;
    if (cvt->filters[++cvt->filter_index]) {
        cvt->filters[cvt->filter_index] (cvt, format);
    }
}

static int
SDL_ResampleAudioSimple(const int chans, const double rate_incr,
                        float *last_sample, const float *inbuf,
                        const int inbuflen, float *outbuf, const int outbuflen)
{
    const int framelen = chans * (int)sizeof (float);
    const int total = (inbuflen / framelen);
    const int finalpos = (total * chans) - chans;
    const int dest_samples = (int)(((double)total) * rate_incr);
    const double src_incr = 1.0 / rate_incr;
    float *dst;
    double idx;
    int i;

    SDL_assert((dest_samples * framelen) <= outbuflen);
    SDL_assert((inbuflen % framelen) == 0);

    if (rate_incr > 1.0) {  /* upsample */
        float *target = (outbuf + chans);
        dst = outbuf + (dest_samples * chans);
        idx = (double) total;

        if (chans == 1) {
            const float final_sample = inbuf[finalpos];
            float earlier_sample = inbuf[finalpos];
            while (dst > target) {
                const int pos = ((int) idx) * chans;
                const float *src = &inbuf[pos];
                const float val = *(--src);
                SDL_assert(pos >= 0.0);
                *(--dst) = (val + earlier_sample) * 0.5f;
                earlier_sample = val;
                idx -= src_incr;
            }
            /* do last sample, interpolated against previous run's state. */
            *(--dst) = (inbuf[0] + last_sample[0]) * 0.5f;
            *last_sample = final_sample;
        } else if (chans == 2) {
            const float final_sample2 = inbuf[finalpos+1];
            const float final_sample1 = inbuf[finalpos];
            float earlier_sample2 = inbuf[finalpos];
            float earlier_sample1 = inbuf[finalpos-1];
            while (dst > target) {
                const int pos = ((int) idx) * chans;
                const float *src = &inbuf[pos];
                const float val2 = *(--src);
                const float val1 = *(--src);
                SDL_assert(pos >= 0.0);
                *(--dst) = (val2 + earlier_sample2) * 0.5f;
                *(--dst) = (val1 + earlier_sample1) * 0.5f;
                earlier_sample2 = val2;
                earlier_sample1 = val1;
                idx -= src_incr;
            }
            /* do last sample, interpolated against previous run's state. */
            *(--dst) = (inbuf[1] + last_sample[1]) * 0.5f;
            *(--dst) = (inbuf[0] + last_sample[0]) * 0.5f;
            last_sample[1] = final_sample2;
            last_sample[0] = final_sample1;
        } else {
            const float *earlier_sample = &inbuf[finalpos];
            float final_sample[8];
            SDL_memcpy(final_sample, &inbuf[finalpos], framelen);
            while (dst > target) {
                const int pos = ((int) idx) * chans;
                const float *src = &inbuf[pos];
                SDL_assert(pos >= 0.0);
                for (i = chans - 1; i >= 0; i--) {
                    const float val = *(--src);
                    *(--dst) = (val + earlier_sample[i]) * 0.5f;
                }
                earlier_sample = src;
                idx -= src_incr;
            }
            /* do last sample, interpolated against previous run's state. */
            for (i = chans - 1; i >= 0; i--) {
                const float val = inbuf[i];
                *(--dst) = (val + last_sample[i]) * 0.5f;
            }
            SDL_memcpy(last_sample, final_sample, framelen);
        }

        dst = (outbuf + (dest_samples * chans));
    } else {  /* downsample */
        float *target = (outbuf + (dest_samples * chans));
        dst = outbuf;
        idx = 0.0;
        if (chans == 1) {
            float last = *last_sample;
            while (dst < target) {
                const int pos = ((int) idx) * chans;
                const float val = inbuf[pos];
                SDL_assert(pos <= finalpos);
                *(dst++) = (val + last) * 0.5f;
                last = val;
                idx += src_incr;
            }
            *last_sample = last;
        } else if (chans == 2) {
            float last1 = last_sample[0];
            float last2 = last_sample[1];
            while (dst < target) {
                const int pos = ((int) idx) * chans;
                const float val1 = inbuf[pos];
                const float val2 = inbuf[pos+1];
                SDL_assert(pos <= finalpos);
                *(dst++) = (val1 + last1) * 0.5f;
                *(dst++) = (val2 + last2) * 0.5f;
                last1 = val1;
                last2 = val2;
                idx += src_incr;
            }
            last_sample[0] = last1;
            last_sample[1] = last2;
        } else {
            while (dst < target) {
                const int pos = ((int) idx) * chans;
                const float *src = &inbuf[pos];
                SDL_assert(pos <= finalpos);
                for (i = 0; i < chans; i++) {
                    const float val = *(src++);
                    *(dst++) = (val + last_sample[i]) * 0.5f;
                    last_sample[i] = val;
                }
                idx += src_incr;
            }
        }
    }

    return (int) ((dst - outbuf) * ((int) sizeof (float)));
}

/* We keep one special-case fast path around for an extremely common audio format. */
static int
SDL_ResampleAudioSimple_si16_c2(const double rate_incr,
                        Sint16 *last_sample, const Sint16 *inbuf,
                        const int inbuflen, Sint16 *outbuf, const int outbuflen)
{
    const int chans = 2;
    const int framelen = 4;  /* stereo 16 bit */
    const int total = (inbuflen / framelen);
    const int finalpos = (total * chans) - chans;
    const int dest_samples = (int)(((double)total) * rate_incr);
    const double src_incr = 1.0 / rate_incr;
    Sint16 *dst;
    double idx;

    SDL_assert((dest_samples * framelen) <= outbuflen);
    SDL_assert((inbuflen % framelen) == 0);

    if (rate_incr > 1.0) {
        Sint16 *target = (outbuf + chans);
        const Sint16 final_right = inbuf[finalpos+1];
        const Sint16 final_left = inbuf[finalpos];
        Sint16 earlier_right = inbuf[finalpos-1];
        Sint16 earlier_left = inbuf[finalpos-2];
        dst = outbuf + (dest_samples * chans);
        idx = (double) total;

        while (dst > target) {
            const int pos = ((int) idx) * chans;
            const Sint16 *src = &inbuf[pos];
            const Sint16 right = *(--src);
            const Sint16 left = *(--src);
            SDL_assert(pos >= 0.0);
            *(--dst) = (((Sint32) right) + ((Sint32) earlier_right)) >> 1;
            *(--dst) = (((Sint32) left) + ((Sint32) earlier_left)) >> 1;
            earlier_right = right;
            earlier_left = left;
            idx -= src_incr;
        }

        /* do last sample, interpolated against previous run's state. */
        *(--dst) = (((Sint32) inbuf[1]) + ((Sint32) last_sample[1])) >> 1;
        *(--dst) = (((Sint32) inbuf[0]) + ((Sint32) last_sample[0])) >> 1;
        last_sample[1] = final_right;
        last_sample[0] = final_left;

        dst = (outbuf + (dest_samples * chans));
    } else {
        Sint16 *target = (outbuf + (dest_samples * chans));
        dst = outbuf;
        idx = 0.0;
        while (dst < target) {
            const int pos = ((int) idx) * chans;
            const Sint16 *src = &inbuf[pos];
            const Sint16 left = *(src++);
            const Sint16 right = *(src++);
            SDL_assert(pos <= finalpos);
            *(dst++) = (((Sint32) left) + ((Sint32) last_sample[0])) >> 1;
            *(dst++) = (((Sint32) right) + ((Sint32) last_sample[1])) >> 1;
            last_sample[0] = left;
            last_sample[1] = right;
            idx += src_incr;
        }
    }

    return (int) ((dst - outbuf) * ((int) sizeof (Sint16)));
}

static void SDLCALL
SDL_ResampleCVT_si16_c2(SDL_AudioCVT *cvt, SDL_AudioFormat format)
{
    const Sint16 *src = (const Sint16 *) cvt->buf;
    const int srclen = cvt->len_cvt;
    Sint16 *dst = (Sint16 *) cvt->buf;
    const int dstlen = (cvt->len * cvt->len_mult);
    Sint16 state[2];

    state[0] = src[0];
    state[1] = src[1];

    SDL_assert(format == AUDIO_S16SYS);

    cvt->len_cvt = SDL_ResampleAudioSimple_si16_c2(cvt->rate_incr, state, src, srclen, dst, dstlen);
    if (cvt->filters[++cvt->filter_index]) {
        cvt->filters[cvt->filter_index](cvt, format);
    }
}


int
SDL_ConvertAudio(SDL_AudioCVT * cvt)
{
    /* !!! FIXME: (cvt) should be const; stack-copy it here. */
    /* !!! FIXME: (actually, we can't...len_cvt needs to be updated. Grr.) */

    /* Make sure there's data to convert */
    if (cvt->buf == NULL) {
        return SDL_SetError("No buffer allocated for conversion");
    }

    /* Return okay if no conversion is necessary */
    cvt->len_cvt = cvt->len;
    if (cvt->filters[0] == NULL) {
        return 0;
    }

    /* Set up the conversion and go! */
    cvt->filter_index = 0;
    cvt->filters[0] (cvt, cvt->src_format);
    return 0;
}

static void SDLCALL
SDL_Convert_Byteswap(SDL_AudioCVT *cvt, SDL_AudioFormat format)
{
#if DEBUG_CONVERT
    printf("Converting byte order\n");
#endif

    switch (SDL_AUDIO_BITSIZE(format)) {
        #define CASESWAP(b) \
            case b: { \
                Uint##b *ptr = (Uint##b *) cvt->buf; \
                int i; \
                for (i = cvt->len_cvt / sizeof (*ptr); i; --i, ++ptr) { \
                    *ptr = SDL_Swap##b(*ptr); \
                } \
                break; \
            }

        CASESWAP(16);
        CASESWAP(32);
        CASESWAP(64);

        #undef CASESWAP

        default: SDL_assert(!"unhandled byteswap datatype!"); break;
    }

    if (cvt->filters[++cvt->filter_index]) {
        /* flip endian flag for data. */
        if (format & SDL_AUDIO_MASK_ENDIAN) {
            format &= ~SDL_AUDIO_MASK_ENDIAN;
        } else {
            format |= SDL_AUDIO_MASK_ENDIAN;
        }
        cvt->filters[cvt->filter_index](cvt, format);
    }
}


static int
SDL_BuildAudioTypeCVTToFloat(SDL_AudioCVT *cvt, const SDL_AudioFormat src_fmt)
{
    int retval = 0;  /* 0 == no conversion necessary. */

    if ((SDL_AUDIO_ISBIGENDIAN(src_fmt) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN)) {
        cvt->filters[cvt->filter_index++] = SDL_Convert_Byteswap;
        retval = 1;  /* added a converter. */
    }

    if (!SDL_AUDIO_ISFLOAT(src_fmt)) {
        const Uint16 src_bitsize = SDL_AUDIO_BITSIZE(src_fmt);
        const Uint16 dst_bitsize = 32;
        SDL_AudioFilter filter = NULL;

        switch (src_fmt & ~SDL_AUDIO_MASK_ENDIAN) {
            case AUDIO_S8: filter = SDL_Convert_S8_to_F32; break;
            case AUDIO_U8: filter = SDL_Convert_U8_to_F32; break;
            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;
            default: SDL_assert(!"Unexpected audio format!"); break;
        }

        if (!filter) {
            return SDL_SetError("No conversion available for these formats");
        }

        cvt->filters[cvt->filter_index++] = filter;
        if (src_bitsize < dst_bitsize) {
            const int mult = (dst_bitsize / src_bitsize);
            cvt->len_mult *= mult;
            cvt->len_ratio *= mult;
        } else if (src_bitsize > dst_bitsize) {
            cvt->len_ratio /= (src_bitsize / dst_bitsize);
        }

        retval = 1;  /* added a converter. */
    }

    return retval;
}

static int
SDL_BuildAudioTypeCVTFromFloat(SDL_AudioCVT *cvt, const SDL_AudioFormat dst_fmt)
{
    int retval = 0;  /* 0 == no conversion necessary. */

    if (!SDL_AUDIO_ISFLOAT(dst_fmt)) {
        const Uint16 dst_bitsize = SDL_AUDIO_BITSIZE(dst_fmt);
        const Uint16 src_bitsize = 32;
        SDL_AudioFilter filter = NULL;
        switch (dst_fmt & ~SDL_AUDIO_MASK_ENDIAN) {
            case AUDIO_S8: filter = SDL_Convert_F32_to_S8; break;
            case AUDIO_U8: filter = SDL_Convert_F32_to_U8; break;
            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;
            default: SDL_assert(!"Unexpected audio format!"); break;
        }

        if (!filter) {
            return SDL_SetError("No conversion available for these formats");
        }

        cvt->filters[cvt->filter_index++] = filter;
        if (src_bitsize < dst_bitsize) {
            const int mult = (dst_bitsize / src_bitsize);
            cvt->len_mult *= mult;
            cvt->len_ratio *= mult;
        } else if (src_bitsize > dst_bitsize) {
            cvt->len_ratio /= (src_bitsize / dst_bitsize);
        }
        retval = 1;  /* added a converter. */
    }

    if ((SDL_AUDIO_ISBIGENDIAN(dst_fmt) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN)) {
        cvt->filters[cvt->filter_index++] = SDL_Convert_Byteswap;
        retval = 1;  /* added a converter. */
    }

    return retval;
}

static void
SDL_ResampleCVT(SDL_AudioCVT *cvt, const int chans, const SDL_AudioFormat format)
{
    const float *src = (const float *) cvt->buf;
    const int srclen = cvt->len_cvt;
    float *dst = (float *) cvt->buf;
    const int dstlen = (cvt->len * cvt->len_mult);
    float state[8];

    SDL_assert(format == AUDIO_F32SYS);

    SDL_memcpy(state, src, chans*sizeof(*src));

    cvt->len_cvt = SDL_ResampleAudioSimple(chans, cvt->rate_incr, state, src, srclen, dst, dstlen);
    if (cvt->filters[++cvt->filter_index]) {
        cvt->filters[cvt->filter_index](cvt, format);
    }
}

/* !!! FIXME: We only have this macro salsa because SDL_AudioCVT doesn't
   !!! FIXME:  store channel info, so we have to have function entry
   !!! FIXME:  points for each supported channel count and multiple
   !!! FIXME:  vs arbitrary. When we rev the ABI, clean this up. */
#define RESAMPLER_FUNCS(chans) \
    static void SDLCALL \
    SDL_ResampleCVT_c##chans(SDL_AudioCVT *cvt, SDL_AudioFormat format) { \
        SDL_ResampleCVT(cvt, chans, format); \
    }
RESAMPLER_FUNCS(1)
RESAMPLER_FUNCS(2)
RESAMPLER_FUNCS(4)
RESAMPLER_FUNCS(6)
RESAMPLER_FUNCS(8)
#undef RESAMPLER_FUNCS

static SDL_AudioFilter
ChooseCVTResampler(const int dst_channels)
{
    switch (dst_channels) {
        case 1: return SDL_ResampleCVT_c1;
        case 2: return SDL_ResampleCVT_c2;
        case 4: return SDL_ResampleCVT_c4;
        case 6: return SDL_ResampleCVT_c6;
        case 8: return SDL_ResampleCVT_c8;
        default: break;
    }

    return NULL;
}

static int
SDL_BuildAudioResampleCVT(SDL_AudioCVT * cvt, const int dst_channels,
                          const int src_rate, const int dst_rate)
{
    SDL_AudioFilter filter;

    if (src_rate == dst_rate) {
        return 0;  /* no conversion necessary. */
    }

    filter = ChooseCVTResampler(dst_channels);
    if (filter == NULL) {
        return SDL_SetError("No conversion available for these rates");
    }

    /* Update (cvt) with filter details... */
    cvt->filters[cvt->filter_index++] = filter;
    if (src_rate < dst_rate) {
        const double mult = ((double) dst_rate) / ((double) src_rate);
        cvt->len_mult *= (int) SDL_ceil(mult);
        cvt->len_ratio *= mult;
    } else {
        cvt->len_ratio /= ((double) src_rate) / ((double) dst_rate);
    }

    return 1;               /* added a converter. */
}


/* Creates a set of audio filters to convert from one format to another.
   Returns -1 if the format conversion is not supported, 0 if there's
   no conversion needed, or 1 if the audio filter is set up.
*/

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)
{
    /* Sanity check target pointer */
    if (cvt == NULL) {
        return SDL_InvalidParamError("cvt");
    }

    /* Make sure we zero out the audio conversion before error checking */
    SDL_zerop(cvt);

    /* there are no unsigned types over 16 bits, so catch this up front. */
    if ((SDL_AUDIO_BITSIZE(src_fmt) > 16) && (!SDL_AUDIO_ISSIGNED(src_fmt))) {
        return SDL_SetError("Invalid source format");
    }
    if ((SDL_AUDIO_BITSIZE(dst_fmt) > 16) && (!SDL_AUDIO_ISSIGNED(dst_fmt))) {
        return SDL_SetError("Invalid destination format");
    }

    /* prevent possible divisions by zero, etc. */
    if ((src_channels == 0) || (dst_channels == 0)) {
        return SDL_SetError("Source or destination channels is zero");
    }
    if ((src_rate == 0) || (dst_rate == 0)) {
        return SDL_SetError("Source or destination rate is zero");
    }
#if DEBUG_CONVERT
    printf("Build format %04x->%04x, channels %u->%u, rate %d->%d\n",
           src_fmt, dst_fmt, src_channels, dst_channels, src_rate, dst_rate);
#endif

    /* Start off with no conversion necessary */
    cvt->src_format = src_fmt;
    cvt->dst_format = dst_fmt;
    cvt->needed = 0;
    cvt->filter_index = 0;
    cvt->filters[0] = NULL;
    cvt->len_mult = 1;
    cvt->len_ratio = 1.0;
    cvt->rate_incr = ((double) dst_rate) / ((double) src_rate);

    /* SDL now favors float32 as its preferred internal format, and considers
       everything else to be a degenerate case that we might have to make
       multiple passes over the data to convert to and from float32 as
       necessary. That being said, we keep one special case around for
       efficiency: stereo data in Sint16 format, in the native byte order,
       that only needs resampling. This is likely to be the most popular
       legacy format, that apps, hardware and the OS are likely to be able
       to process directly, so we handle this one case directly without
       unnecessary conversions. This means that apps on embedded devices
       without floating point hardware should consider aiming for this
       format as well. */
    if ((src_channels == 2) && (dst_channels == 2) && (src_fmt == AUDIO_S16SYS) && (dst_fmt == AUDIO_S16SYS) && (src_rate != dst_rate)) {
        cvt->needed = 1;
        cvt->filters[cvt->filter_index++] = SDL_ResampleCVT_si16_c2;
        if (src_rate < dst_rate) {
            const double mult = ((double) dst_rate) / ((double) src_rate);
            cvt->len_mult *= (int) SDL_ceil(mult);
            cvt->len_ratio *= mult;
        } else {
            cvt->len_ratio /= ((double) src_rate) / ((double) dst_rate);
        }
        return 1;
    }

    /* Type conversion goes like this now:
        - byteswap to CPU native format first if necessary.
        - convert to native Float32 if necessary.
        - resample and change channel count if necessary.
        - convert back to native format.
        - byteswap back to foreign format if necessary.

       The expectation is we can process data faster in float32
       (possibly with SIMD), and making several passes over the same
       buffer is likely to be CPU cache-friendly, avoiding the
       biggest performance hit in modern times. Previously we had
       (script-generated) custom converters for every data type and
       it was a bloat on SDL compile times and final library size. */

    /* see if we can skip float conversion entirely. */
    if (src_rate == dst_rate && src_channels == dst_channels) {
        if (src_fmt == dst_fmt) {
            return 0;
        }

        /* just a byteswap needed? */
        if ((src_fmt & ~SDL_AUDIO_MASK_ENDIAN) == (dst_fmt & ~SDL_AUDIO_MASK_ENDIAN)) {
            cvt->filters[cvt->filter_index++] = SDL_Convert_Byteswap;
            cvt->needed = 1;
            return 1;
        }
    }

    /* Convert data types, if necessary. Updates (cvt). */
    if (SDL_BuildAudioTypeCVTToFloat(cvt, src_fmt) < 0) {
        return -1;              /* shouldn't happen, but just in case... */
    }

    /* Channel conversion */
    if (src_channels != dst_channels) {
        if ((src_channels == 1) && (dst_channels > 1)) {
            cvt->filters[cvt->filter_index++] = SDL_ConvertMonoToStereo;
            cvt->len_mult *= 2;
            src_channels = 2;
            cvt->len_ratio *= 2;
        }
        if ((src_channels == 2) && (dst_channels == 6)) {
            cvt->filters[cvt->filter_index++] = SDL_ConvertStereoTo51;
            src_channels = 6;
            cvt->len_mult *= 3;
            cvt->len_ratio *= 3;
        }
        if ((src_channels == 2) && (dst_channels == 4)) {
            cvt->filters[cvt->filter_index++] = SDL_ConvertStereoToQuad;
            src_channels = 4;
            cvt->len_mult *= 2;
            cvt->len_ratio *= 2;
        }
        while ((src_channels * 2) <= dst_channels) {
            cvt->filters[cvt->filter_index++] = SDL_ConvertMonoToStereo;
            cvt->len_mult *= 2;
            src_channels *= 2;
            cvt->len_ratio *= 2;
        }
        if ((src_channels == 6) && (dst_channels <= 2)) {
            cvt->filters[cvt->filter_index++] = SDL_Convert51ToStereo;
            src_channels = 2;
            cvt->len_ratio /= 3;
        }
        if ((src_channels == 6) && (dst_channels == 4)) {
            cvt->filters[cvt->filter_index++] = SDL_Convert51ToQuad;
            src_channels = 4;
            cvt->len_ratio /= 2;
        }
        /* This assumes that 4 channel audio is in the format:
           Left {front/back} + Right {front/back}
           so converting to L/R stereo works properly.
         */
        while (((src_channels % 2) == 0) &&
               ((src_channels / 2) >= dst_channels)) {
            SDL_AudioFilter filter = NULL;

            #if HAVE_SSE3_INTRINSICS
            if (SDL_HasSSE3()) {
                filter = SDL_ConvertStereoToMono_SSE3;
            }
            #endif

            if (!filter) {
                filter = SDL_ConvertStereoToMono;
            }

            cvt->filters[cvt->filter_index++] = filter;

            src_channels /= 2;
            cvt->len_ratio /= 2;
        }
        if (src_channels != dst_channels) {
            /* Uh oh.. */ ;
        }
    }

    /* Do rate conversion, if necessary. Updates (cvt). */
    if (SDL_BuildAudioResampleCVT(cvt, dst_channels, src_rate, dst_rate) < 0) {
        return -1;              /* shouldn't happen, but just in case... */
    }

    /* Move to final data type. */
    if (SDL_BuildAudioTypeCVTFromFloat(cvt, dst_fmt) < 0) {
        return -1;              /* shouldn't happen, but just in case... */
    }

    cvt->needed = (cvt->filter_index != 0);
    return (cvt->needed);
}

typedef int (*SDL_ResampleAudioStreamFunc)(SDL_AudioStream *stream, const void *inbuf, const int inbuflen, void *outbuf, const int outbuflen);
typedef void (*SDL_ResetAudioStreamResamplerFunc)(SDL_AudioStream *stream);
typedef void (*SDL_CleanupAudioStreamResamplerFunc)(SDL_AudioStream *stream);

struct SDL_AudioStream
{
    SDL_AudioCVT cvt_before_resampling;
    SDL_AudioCVT cvt_after_resampling;
    SDL_DataQueue *queue;
    Uint8 *work_buffer_base;  /* maybe unaligned pointer from SDL_realloc(). */
    int work_buffer_len;
    int src_sample_frame_size;
    SDL_AudioFormat src_format;
    Uint8 src_channels;
    int src_rate;
    int dst_sample_frame_size;
    SDL_AudioFormat dst_format;
    Uint8 dst_channels;
    int dst_rate;
    double rate_incr;
    Uint8 pre_resample_channels;
    int packetlen;
    void *resampler_state;
    SDL_ResampleAudioStreamFunc resampler_func;
    SDL_ResetAudioStreamResamplerFunc reset_resampler_func;
    SDL_CleanupAudioStreamResamplerFunc cleanup_resampler_func;
};

static Uint8 *
EnsureStreamBufferSize(SDL_AudioStream *stream, const int newlen)
{
    Uint8 *ptr;
    size_t offset;

    if (stream->work_buffer_len >= newlen) {
        ptr = stream->work_buffer_base;
    } else {
        ptr = (Uint8 *) SDL_realloc(stream->work_buffer_base, newlen + 32);
        if (!ptr) {
            SDL_OutOfMemory();
            return NULL;
        }
        /* Make sure we're aligned to 16 bytes for SIMD code. */
        stream->work_buffer_base = ptr;
        stream->work_buffer_len = newlen;
    }

    offset = ((size_t) ptr) & 15;
    return offset ? ptr + (16 - offset) : ptr;
}

#ifdef HAVE_LIBSAMPLERATE_H
static int
SDL_ResampleAudioStream_SRC(SDL_AudioStream *stream, const void *_inbuf, const int inbuflen, void *_outbuf, const int outbuflen)
{
    const float *inbuf = (const float *) _inbuf;
    float *outbuf = (float *) _outbuf;
    const int framelen = sizeof(float) * stream->pre_resample_channels;
    SRC_STATE *state = (SRC_STATE *)stream->resampler_state;
    SRC_DATA data;
    int result;

    if (inbuf == ((const float *) outbuf)) {  /* libsamplerate can't work in-place. */
        Uint8 *ptr = EnsureStreamBufferSize(stream, inbuflen + outbuflen);
        if (ptr == NULL) {
            SDL_OutOfMemory();
            return 0;
        }
        SDL_memcpy(ptr + outbuflen, ptr, inbuflen);
        inbuf = (const float *) (ptr + outbuflen);
        outbuf = (float *) ptr;
    }

    data.data_in = (float *)inbuf; /* Older versions of libsamplerate had a non-const pointer, but didn't write to it */
    data.input_frames = inbuflen / framelen;
    data.input_frames_used = 0;

    data.data_out = outbuf;
    data.output_frames = outbuflen / framelen;

    data.end_of_input = 0;
    data.src_ratio = stream->rate_incr;

    result = SRC_src_process(state, &data);
    if (result != 0) {
        SDL_SetError("src_process() failed: %s", SRC_src_strerror(result));
        return 0;
    }

    /* If this fails, we need to store them off somewhere */
    SDL_assert(data.input_frames_used == data.input_frames);

    return data.output_frames_gen * (sizeof(float) * stream->pre_resample_channels);
}

static void
SDL_ResetAudioStreamResampler_SRC(SDL_AudioStream *stream)
{
    SRC_src_reset((SRC_STATE *)stream->resampler_state);
}

static void
SDL_CleanupAudioStreamResampler_SRC(SDL_AudioStream *stream)
{
    SRC_STATE *state = (SRC_STATE *)stream->resampler_state;
    if (state) {
        SRC_src_delete(state);
    }

    stream->resampler_state = NULL;
    stream->resampler_func = NULL;
    stream->reset_resampler_func = NULL;
    stream->cleanup_resampler_func = NULL;
}

static SDL_bool
SetupLibSampleRateResampling(SDL_AudioStream *stream)
{
    int result = 0;
    SRC_STATE *state = NULL;

    if (SRC_available) {
        state = SRC_src_new(SRC_converter, stream->pre_resample_channels, &result);
        if (!state) {
            SDL_SetError("src_new() failed: %s", SRC_src_strerror(result));
        }
    }

    if (!state) {
        SDL_CleanupAudioStreamResampler_SRC(stream);
        return SDL_FALSE;
    }

    stream->resampler_state = state;
    stream->resampler_func = SDL_ResampleAudioStream_SRC;
    stream->reset_resampler_func = SDL_ResetAudioStreamResampler_SRC;
    stream->cleanup_resampler_func = SDL_CleanupAudioStreamResampler_SRC;

    return SDL_TRUE;
}
#endif /* HAVE_LIBSAMPLERATE_H */


typedef struct
{
    SDL_bool resampler_seeded;
    union
    {
        float f[8];
        Sint16 si16[2];
    } resampler_state;
} SDL_AudioStreamResamplerState;

static int
SDL_ResampleAudioStream(SDL_AudioStream *stream, const void *_inbuf, const int inbuflen, void *_outbuf, const int outbuflen)
{
    const float *inbuf = (const float *) _inbuf;
    float *outbuf = (float *) _outbuf;
    SDL_AudioStreamResamplerState *state = (SDL_AudioStreamResamplerState*)stream->resampler_state;
    const int chans = (int)stream->pre_resample_channels;

    SDL_assert(chans <= SDL_arraysize(state->resampler_state.f));

    if (!state->resampler_seeded) {
        SDL_memcpy(state->resampler_state.f, inbuf, chans * sizeof (float));
        state->resampler_seeded = SDL_TRUE;
    }

    return SDL_ResampleAudioSimple(chans, stream->rate_incr, state->resampler_state.f, inbuf, inbuflen, outbuf, outbuflen);
}

static int
SDL_ResampleAudioStream_si16_c2(SDL_AudioStream *stream, const void *_inbuf, const int inbuflen, void *_outbuf, const int outbuflen)
{
    const Sint16 *inbuf = (const Sint16 *) _inbuf;
    Sint16 *outbuf = (Sint16 *) _outbuf;
    SDL_AudioStreamResamplerState *state = (SDL_AudioStreamResamplerState*)stream->resampler_state;

    SDL_assert(((int)stream->pre_resample_channels) <= SDL_arraysize(state->resampler_state.si16));

    if (!state->resampler_seeded) {
        state->resampler_state.si16[0] = inbuf[0];
        state->resampler_state.si16[1] = inbuf[1];
        state->resampler_seeded = SDL_TRUE;
    }

    return SDL_ResampleAudioSimple_si16_c2(stream->rate_incr, state->resampler_state.si16, inbuf, inbuflen, outbuf, outbuflen);
}

static void
SDL_ResetAudioStreamResampler(SDL_AudioStream *stream)
{
    SDL_AudioStreamResamplerState *state = (SDL_AudioStreamResamplerState*)stream->resampler_state;
    state->resampler_seeded = SDL_FALSE;
}

static void
SDL_CleanupAudioStreamResampler(SDL_AudioStream *stream)
{
    SDL_free(stream->resampler_state);
}

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)
{
    const int packetlen = 4096;  /* !!! FIXME: good enough for now. */
    Uint8 pre_resample_channels;
    SDL_AudioStream *retval;
#ifndef HAVE_LIBSAMPLERATE_H
    const SDL_bool SRC_available = SDL_FALSE;
#endif

    retval = (SDL_AudioStream *) SDL_calloc(1, sizeof (SDL_AudioStream));
    if (!retval) {
        return NULL;
    }

    /* If increasing channels, do it after resampling, since we'd just
       do more work to resample duplicate channels. If we're decreasing, do
       it first so we resample the interpolated data instead of interpolating
       the resampled data (!!! FIXME: decide if that works in practice, though!). */
    pre_resample_channels = SDL_min(src_channels, dst_channels);

    retval->src_sample_frame_size = (SDL_AUDIO_BITSIZE(src_format) / 8) * src_channels;
    retval->src_format = src_format;
    retval->src_channels = src_channels;
    retval->src_rate = src_rate;
    retval->dst_sample_frame_size = (SDL_AUDIO_BITSIZE(dst_format) / 8) * dst_channels;
    retval->dst_format = dst_format;
    retval->dst_channels = dst_channels;
    retval->dst_rate = dst_rate;
    retval->pre_resample_channels = pre_resample_channels;
    retval->packetlen = packetlen;
    retval->rate_incr = ((double) dst_rate) / ((double) src_rate);

    /* Not resampling? It's an easy conversion (and maybe not even that!). */
    if (src_rate == dst_rate) {
        retval->cvt_before_resampling.needed = SDL_FALSE;
        if (SDL_BuildAudioCVT(&retval->cvt_after_resampling, src_format, src_channels, dst_rate, dst_format, dst_channels, dst_rate) < 0) {
            SDL_FreeAudioStream(retval);
            return NULL;  /* SDL_BuildAudioCVT should have called SDL_SetError. */
        }
    /* fast path special case for stereo Sint16 data that just needs resampling. */
    } else if ((!SRC_available) && (src_channels == 2) && (dst_channels == 2) && (src_format == AUDIO_S16SYS) && (dst_format == AUDIO_S16SYS)) {
        SDL_assert(src_rate != dst_rate);
        retval->resampler_state = SDL_calloc(1, sizeof(SDL_AudioStreamResamplerState));
        if (!retval->resampler_state) {
            SDL_FreeAudioStream(retval);
            SDL_OutOfMemory();
            return NULL;
        }
        retval->resampler_func = SDL_ResampleAudioStream_si16_c2;
        retval->reset_resampler_func = SDL_ResetAudioStreamResampler;
        retval->cleanup_resampler_func = SDL_CleanupAudioStreamResampler;
    } else {
        /* Don't resample at first. Just get us to Float32 format. */
        /* !!! FIXME: convert to int32 on devices without hardware float. */
        if (SDL_BuildAudioCVT(&retval->cvt_before_resampling, src_format, src_channels, src_rate, AUDIO_F32SYS, pre_resample_channels, src_rate) < 0) {
            SDL_FreeAudioStream(retval);
            return NULL;  /* SDL_BuildAudioCVT should have called SDL_SetError. */
        }

#ifdef HAVE_LIBSAMPLERATE_H
        SetupLibSampleRateResampling(retval);
#endif

        if (!retval->resampler_func) {
            retval->resampler_state = SDL_calloc(1, sizeof(SDL_AudioStreamResamplerState));
            if (!retval->resampler_state) {
                SDL_FreeAudioStream(retval);
                SDL_OutOfMemory();
                return NULL;
            }
            retval->resampler_func = SDL_ResampleAudioStream;
            retval->reset_resampler_func = SDL_ResetAudioStreamResampler;
            retval->cleanup_resampler_func = SDL_CleanupAudioStreamResampler;
        }

        /* Convert us to the final format after resampling. */
        if (SDL_BuildAudioCVT(&retval->cvt_after_resampling, AUDIO_F32SYS, pre_resample_channels, dst_rate, dst_format, dst_channels, dst_rate) < 0) {
            SDL_FreeAudioStream(retval);
            return NULL;  /* SDL_BuildAudioCVT should have called SDL_SetError. */
        }
    }

    retval->queue = SDL_NewDataQueue(packetlen, packetlen * 2);
    if (!retval->queue) {
        SDL_FreeAudioStream(retval);
        return NULL;  /* SDL_NewDataQueue should have called SDL_SetError. */
    }

    return retval;
}

int
SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, const Uint32 _buflen)
{
    int buflen = (int) _buflen;
    const void *origbuf = buf;

    /* !!! FIXME: several converters can take advantage of SIMD, but only
       !!! FIXME:  if the data is aligned to 16 bytes. EnsureStreamBufferSize()
       !!! FIXME:  guarantees the buffer will align, but the
       !!! FIXME:  converters will iterate over the data backwards if
       !!! FIXME:  the output grows, and this means we won't align if buflen
       !!! FIXME:  isn't a multiple of 16. In these cases, we should chop off
       !!! FIXME:  a few samples at the end and convert them separately. */

    if (!stream) {
        return SDL_InvalidParamError("stream");
    } else if (!buf) {
        return SDL_InvalidParamError("buf");
    } else if (buflen == 0) {
        return 0;  /* nothing to do. */
    } else if ((buflen % stream->src_sample_frame_size) != 0) {
        return SDL_SetError("Can't add partial sample frames");
    }

    if (stream->cvt_before_resampling.needed) {
        const int workbuflen = buflen * stream->cvt_before_resampling.len_mult;  /* will be "* 1" if not needed */
        Uint8 *workbuf = EnsureStreamBufferSize(stream, workbuflen);
        if (workbuf == NULL) {
            return -1;  /* probably out of memory. */
        }
        SDL_assert(buf == origbuf);
        SDL_memcpy(workbuf, buf, buflen);
        stream->cvt_before_resampling.buf = workbuf;
        stream->cvt_before_resampling.len = buflen;
        if (SDL_ConvertAudio(&stream->cvt_before_resampling) == -1) {
            return -1;   /* uhoh! */
        }
        buf = workbuf;
        buflen = stream->cvt_before_resampling.len_cvt;
    }

    if (stream->dst_rate != stream->src_rate) {
        const int workbuflen = buflen * ((int) SDL_ceil(stream->rate_incr));
        Uint8 *workbuf = EnsureStreamBufferSize(stream, workbuflen);
        if (workbuf == NULL) {
            return -1;  /* probably out of memory. */
        }
        /* don't SDL_memcpy(workbuf, buf, buflen) here; our resampler can work inplace or not,
           libsamplerate needs buffers to be separate; either way, avoid a copy here if possible. */
        if (buf != origbuf) {
            buf = workbuf;  /* in case we realloc()'d the pointer. */
        }
        buflen = stream->resampler_func(stream, buf, buflen, workbuf, workbuflen);
        buf = EnsureStreamBufferSize(stream, workbuflen);
        SDL_assert(buf != NULL);  /* shouldn't be growing, just aligning. */
    }

    if (stream->cvt_after_resampling.needed) {
        const int workbuflen = buflen * stream->cvt_after_resampling.len_mult;  /* will be "* 1" if not needed */
        Uint8 *workbuf = EnsureStreamBufferSize(stream, workbuflen);
        if (workbuf == NULL) {
            return -1;  /* probably out of memory. */
        }
        if (buf == origbuf) {  /* copy if we haven't before. */
            SDL_memcpy(workbuf, buf, buflen);
        }
        stream->cvt_after_resampling.buf = workbuf;
        stream->cvt_after_resampling.len = buflen;
        if (SDL_ConvertAudio(&stream->cvt_after_resampling) == -1) {
            return -1;   /* uhoh! */
        }
        buf = workbuf;
        buflen = stream->cvt_after_resampling.len_cvt;
    }

    return SDL_WriteToDataQueue(stream->queue, buf, buflen);
}

void
SDL_AudioStreamClear(SDL_AudioStream *stream)
{
    if (!stream) {
        SDL_InvalidParamError("stream");
    } else {
        SDL_ClearDataQueue(stream->queue, stream->packetlen * 2);
        if (stream->reset_resampler_func) {
            stream->reset_resampler_func(stream);
        }
    }
}


/* get converted/resampled data from the stream */
int
SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, const Uint32 len)
{
    if (!stream) {
        return SDL_InvalidParamError("stream");
    } else if (!buf) {
        return SDL_InvalidParamError("buf");
    } else if (len == 0) {
        return 0;  /* nothing to do. */
    } else if ((len % stream->dst_sample_frame_size) != 0) {
        return SDL_SetError("Can't request partial sample frames");
    }

    return (int) SDL_ReadFromDataQueue(stream->queue, buf, len);
}

/* number of converted/resampled bytes available */
int
SDL_AudioStreamAvailable(SDL_AudioStream *stream)
{
    return stream ? (int) SDL_CountDataQueue(stream->queue) : 0;
}

/* dispose of a stream */
void
SDL_FreeAudioStream(SDL_AudioStream *stream)
{
    if (stream) {
        if (stream->cleanup_resampler_func) {
            stream->cleanup_resampler_func(stream);
        }
        SDL_FreeDataQueue(stream->queue);
        SDL_free(stream->work_buffer_base);
        SDL_free(stream);
    }
}

/* vi: set ts=4 sw=4 expandtab: */

