#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "mixer68.h"
#define SWAP_16BITWORD(V) (((u32)(V)>>16)+(V<<16))
void mixer68_stereo_16_LR(u32 * dst, u32 * src, int nb, const u32 sign)
{
u32 *end;
if (!sign && dst == src) {
return;
}
end = dst+nb;
if (nb&1) {
*dst++ = (*src++) ^ sign;
}
if (nb&2) {
*dst++ = (*src++) ^ sign;
*dst++ = (*src++) ^ sign;
}
if (dst<end) {
do {
*dst++ = (*src++) ^ sign;
*dst++ = (*src++) ^ sign;
*dst++ = (*src++) ^ sign;
*dst++ = (*src++) ^ sign;
} while (dst < end);
}
}
void mixer68_stereo_16_RL(u32 * dst, u32 * src, int nb, const u32 sign)
{
u32 *end;
#undef MIX_ONE
#define MIX_ONE \
v = (*src++); \
*dst++ = SWAP_16BITWORD(v) ^ sign
end = dst+nb;
if (nb&1) {
u32 v;
MIX_ONE;
}
if (nb&2) {
u32 v;
MIX_ONE;
MIX_ONE;
}
if (dst<end) {
do {
u32 v;
MIX_ONE;
MIX_ONE;
MIX_ONE;
MIX_ONE;
} while (dst < end);
}
}
void mixer68_stereo_FL_LR (float * dst, u32 * src, int nb,
const u32 sign, const float norm)
{
const float mult = norm / 32768.0f;
int v;
float * const end = dst + (nb<<1);
if (dst < end) {
do {
v = (int)(s32)(*src++ ^ sign);
*dst++ = mult * (float)(s16)(v);
*dst++ = mult * (float)(v>>16);
} while (dst < end);
}
}
void mixer68_dup_L_to_R(u32 *dst, u32 *src, int nb,
const u32 sign)
{
u32 * const end = dst+nb;
if (nb&1) {
u32 v;
v = (u16)*src++; *dst++ = ((v<<16)|v) ^ sign;
}
if (nb&2) {
u32 v;
v = (u16)*src++; *dst++ = ((v<<16)|v) ^ sign;
v = (u16)*src++; *dst++ = ((v<<16)|v) ^ sign;
}
if (dst < end) {
do {
u32 v;
v = (u16)*src++; *dst++ = ((v<<16)|v) ^ sign;
v = (u16)*src++; *dst++ = ((v<<16)|v) ^ sign;
v = (u16)*src++; *dst++ = ((v<<16)|v) ^ sign;
v = (u16)*src++; *dst++ = ((v<<16)|v) ^ sign;
} while (dst < end);
}
}
void mixer68_dup_R_to_L(u32 *dst, u32 *src, int nb, const u32 sign)
{
u32 * const end = dst+nb;
if (nb&1) {
u32 v;
v = *src++&0xFFFF0000; *dst++ = ((v>>16)|v) ^ sign;
}
if (nb&2) {
u32 v;
v = *src++&0xFFFF0000; *dst++ = ((v>>16)|v) ^ sign;
v = *src++&0xFFFF0000; *dst++ = ((v>>16)|v) ^ sign;
}
if (dst < end) {
do {
u32 v;
v = *src++&0xFFFF0000; *dst++ = ((v>>16)|v) ^ sign;
v = *src++&0xFFFF0000; *dst++ = ((v>>16)|v) ^ sign;
v = *src++&0xFFFF0000; *dst++ = ((v>>16)|v) ^ sign;
v = *src++&0xFFFF0000; *dst++ = ((v>>16)|v) ^ sign;
} while (dst < end);
}
}
void mixer68_blend_LR(u32 * dst, u32 * src, int nb,
int factor,
const u32 sign_r, const u32 sign_w)
{
u32 *end;
int oof;
if (factor < 0) {
factor = 0;
} else if (factor > 65536) {
factor = 65536;
}
#undef MIX_ONE
#define MIX_ONE \
r = (int)(s32)(*src++ ^ sign_r); \
l = r >> 16; \
r = (int)(s16)r; \
*dst++ = ( \
((l*oof+r*factor)&0xFFFF0000) \
| \
((u32)(r*oof+l*factor) >> 16) \
) ^ sign_w
oof = 65536-factor;
end = dst+nb;
if (nb&1) {
int l,r;
MIX_ONE;
}
if (nb&2) {
int l,r;
MIX_ONE;
MIX_ONE;
}
if (dst < end) {
do {
int l,r;
MIX_ONE;
MIX_ONE;
MIX_ONE;
MIX_ONE;
} while (dst < end);
}
}
void mixer68_mult_LR(u32 *dst, u32 *src, int nb,
const int ml, const int mr,
const u32 sign_r, const u32 sign_w)
{
u32 * end;
if (ml == 65536 && mr == 65536) {
mixer68_stereo_16_LR(dst, src, nb, sign_r ^ sign_w);
return;
}
if (ml==0 && mr==0) {
mixer68_fill(dst, nb, sign_w);
return;
}
#undef MIX_ONE
#define MIX_ONE \
r = (int)(s32)(*src++ ^ sign_r); \
l = (int)(s16)r; \
r = r >> 16; \
*dst++ = ((((u32)(l*ml))>>16) | ((r*mr)&0xFFFF0000)) ^ sign_w
end = dst+nb;
if (nb&1) {
int l,r;
MIX_ONE;
}
if (nb&2) {
int l,r;
MIX_ONE;
MIX_ONE;
}
if (dst < end) {
do {
int l,r;
MIX_ONE;
MIX_ONE;
MIX_ONE;
MIX_ONE;
} while (dst < end);
}
}
void mixer68_fill(u32 * dst, int nb, const u32 sign)
{
u32 * const end = dst+nb;;
if (nb&1) {
*dst++ = sign;
}
if (nb&2) {
*dst++ = sign;
*dst++ = sign;
}
if (dst < end) {
do {
*dst++ = sign;
*dst++ = sign;
*dst++ = sign;
*dst++ = sign;
} while (dst < end);
}
}
void mixer68_copy(u32 * dst, u32 * src, int nb)
{
if (dst == src || nb <= 0) {
return;
} else {
u32 * const end = dst+nb;
if (nb&1) {
*dst++ = *src++;
}
if (nb&2) {
*dst++ = *src++;
*dst++ = *src++;
}
if (dst<end) {
do {
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
} while (dst < end);
}
}
}