/*
 * miniJSS - Mixing routines in C
 * Programmed and designed by Matti 'ccr' Hamalainen
 * (C) Copyright 2006-2007 Tecnic Software productions (TNSP)
 */

//#define JMIXER_DEBUG fprintf(stderr, "[%.8x:%.8x / %.8x]: %d\n", FP_GETH(tmpPos), FP_GETL(tmpPos), endPos, sp[FP_GETH(tmpPos)]);
#define JMIXER_DEBUG
#define JMIXER_ADDBUF_TYPE Sint32


/* Mono / Linear Interpolation
 */
#define JMIXER_SAMPLE_TYPE Sint16
#define JMIXER_INIT        
#define JMIXER_FUNC \
    const Sint32 vol = (FP_GETH(tmpVolume) * mixer->globalVol) / 256; \
    memmove(&tl[0], &tl[1], 4 * sizeof(tl[0])); \
    tl[4] = (((Sint32) sp[FP_GETH(tmpPos)]) * vol * 3 + tl[3] * 2 + tl[2] + tl[1] + tl[0]) / (256 * 8); *(ap++) += tl[4]; \

#define JMIXER_NAME        jvmMix_Mono_C_FW
#define JMIXER_NEXT        FP_ADD(tmpPos, tmpDelta);
#define JMIXER_ENDCOND     (tmpPos.dw < endPos.dw)
#include "jmixtmpl_c.h"

#define JMIXER_NAME        jvmMix_Mono_C_BW
#define JMIXER_NEXT        FP_SUB(tmpPos, tmpDelta);
#define JMIXER_ENDCOND     (tmpPos.dw > endPos.dw)
#include "jmixtmpl_c.h"


#undef JMIXER_SAMPLE_TYPE
#undef JMIXER_INIT
#undef JMIXER_FUNC


/* Stereo / Linear Interpolation
 */
#define JMIXER_SAMPLE_TYPE Sint16
#define JMIXER_INIT

#define JMIXER_FUNC \
    const Sint32 vol_l = (FP_GETH(tmpVolume) * mixer->globalVol) / 256, \
                 vol_r = (FP_GETH(tmpVolume) * mixer->globalVol) / 256; \
    memmove(&tl[0], &tl[1], 4 * sizeof(tl[0])); \
    memmove(&tr[0], &tr[1], 4 * sizeof(tr[0])); \
    tl[4] = (((Sint32) sp[FP_GETH(tmpPos)]) * vol_l * 3 + tl[3] * 2 + tl[2] + tl[1] + tl[0]) / (256 * 8); *(ap++) += tl[4]; \
    tr[4] = (((Sint32) sp[FP_GETH(tmpPos)]) * vol_r * 3 + tr[3] * 2 + tr[2] + tr[1] + tr[0]) / (256 * 8); *(ap++) += tr[4];

#define JMIXER_NAME        jvmMix_Stereo_C_FW
#define JMIXER_NEXT        FP_ADD(tmpPos, tmpDelta);
#define JMIXER_ENDCOND     (tmpPos.dw < endPos.dw)
#include "jmixtmpl_c.h"

#define JMIXER_NAME        jvmMix_Stereo_C_BW
#define JMIXER_NEXT        FP_SUB(tmpPos, tmpDelta);
#define JMIXER_ENDCOND     (tmpPos.dw > endPos.dw)
#include "jmixtmpl_c.h"


#undef JMIXER_SAMPLE_TYPE
#undef JMIXER_INIT
#undef JMIXER_FUNC


/* Post processing functions
 */
#define JMIXER_CLAMP \
    if (t < JVM_LIMIT_16_NEG) t = JVM_LIMIT_16_NEG; else    \
    if (t > JVM_LIMIT_16_POS) t = JVM_LIMIT_16_POS;

#define JMIXER_NAME jvmPostProcess_U8_C
#define JMIXER_TYPE Uint8
#define JMIXER_FUNCTION *(sp++) = (t + JVM_ADD_16) >> 8;
#include "jmix_post_c.h"


#define JMIXER_NAME jvmPostProcess_S8_C
#define JMIXER_TYPE Sint8
#define JMIXER_FUNCTION *(sp++) = t >> 8;
#include "jmix_post_c.h"


#define JMIXER_NAME jvmPostProcess_U16_C
#define JMIXER_TYPE Uint16
#define JMIXER_FUNCTION *(sp++) = t + JVM_ADD_16;
#include "jmix_post_c.h"


#define JMIXER_NAME jvmPostProcess_S16_C
#define JMIXER_TYPE Sint16
#define JMIXER_FUNCTION *(sp++) = t;
#include "jmix_post_c.h"
