|
Packit |
4a16fb |
#if 0
|
|
Packit |
4a16fb |
//#if defined(__i386__) || defined(__x86_64__)
|
|
Packit |
4a16fb |
#define LOCK_PREFIX "lock ; "
|
|
Packit |
4a16fb |
#define ARCH_ADD(p,a) \
|
|
Packit |
4a16fb |
__asm__ __volatile__(LOCK_PREFIX "addl %1,%0" \
|
|
Packit |
4a16fb |
:"=m" (*p) \
|
|
Packit |
4a16fb |
:"ir" (a), "m" (*p))
|
|
Packit |
4a16fb |
struct __xchg_dummy { unsigned long a[100]; };
|
|
Packit |
4a16fb |
#define __xg(x) ((struct __xchg_dummy *)(x))
|
|
Packit |
4a16fb |
static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
|
|
Packit |
4a16fb |
unsigned long new, int size)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
unsigned long prev;
|
|
Packit |
4a16fb |
switch (size) {
|
|
Packit |
4a16fb |
case 1:
|
|
Packit |
4a16fb |
__asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
|
|
Packit |
4a16fb |
: "=a"(prev)
|
|
Packit |
4a16fb |
: "q"(new), "m"(*__xg(ptr)), "0"(old)
|
|
Packit |
4a16fb |
: "memory");
|
|
Packit |
4a16fb |
return prev;
|
|
Packit |
4a16fb |
case 2:
|
|
Packit |
4a16fb |
__asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
|
|
Packit |
4a16fb |
: "=a"(prev)
|
|
Packit |
4a16fb |
: "q"(new), "m"(*__xg(ptr)), "0"(old)
|
|
Packit |
4a16fb |
: "memory");
|
|
Packit |
4a16fb |
return prev;
|
|
Packit |
4a16fb |
case 4:
|
|
Packit |
4a16fb |
__asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
|
|
Packit |
4a16fb |
: "=a"(prev)
|
|
Packit |
4a16fb |
: "q"(new), "m"(*__xg(ptr)), "0"(old)
|
|
Packit |
4a16fb |
: "memory");
|
|
Packit |
4a16fb |
return prev;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
return old;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
#define ARCH_CMPXCHG(ptr,o,n)\
|
|
Packit |
4a16fb |
((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
|
|
Packit |
4a16fb |
(unsigned long)(n),sizeof(*(ptr))))
|
|
Packit |
4a16fb |
#define IS_CONCURRENT 1 /* check race */
|
|
Packit |
4a16fb |
#endif
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
#ifndef ARCH_ADD
|
|
Packit |
4a16fb |
#define ARCH_ADD(p,a) (*(p) += (a))
|
|
Packit |
4a16fb |
#define ARCH_CMPXCHG(p,a,b) (*(p)) /* fake */
|
|
Packit |
4a16fb |
#define NO_CONCURRENT_ACCESS /* use semaphore to avoid race */
|
|
Packit |
4a16fb |
#define IS_CONCURRENT 0 /* no race check */
|
|
Packit |
4a16fb |
#endif
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
#if IS_CONCURRENT
|
|
Packit |
4a16fb |
static void mix_areas_16(unsigned int size,
|
|
Packit |
4a16fb |
volatile signed short *dst, signed short *src,
|
|
Packit |
4a16fb |
volatile signed int *sum, size_t dst_step,
|
|
Packit |
4a16fb |
size_t src_step, size_t sum_step)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
register signed int sample, old_sample;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
for (;;) {
|
|
Packit |
4a16fb |
sample = *src;
|
|
Packit |
4a16fb |
old_sample = *sum;
|
|
Packit |
4a16fb |
if (ARCH_CMPXCHG(dst, 0, 1) == 0)
|
|
Packit |
4a16fb |
sample -= old_sample;
|
|
Packit |
4a16fb |
ARCH_ADD(sum, sample);
|
|
Packit |
4a16fb |
do {
|
|
Packit |
4a16fb |
old_sample = *sum;
|
|
Packit |
4a16fb |
if (old_sample > 0x7fff)
|
|
Packit |
4a16fb |
sample = 0x7fff;
|
|
Packit |
4a16fb |
else if (old_sample < -0x8000)
|
|
Packit |
4a16fb |
sample = -0x8000;
|
|
Packit |
4a16fb |
else
|
|
Packit |
4a16fb |
sample = old_sample;
|
|
Packit |
4a16fb |
*dst = sample;
|
|
Packit |
4a16fb |
} while (IS_CONCURRENT && *sum != old_sample);
|
|
Packit |
4a16fb |
if (!--size)
|
|
Packit |
4a16fb |
return;
|
|
Packit |
4a16fb |
src = (signed short *) ((char *)src + src_step);
|
|
Packit |
4a16fb |
dst = (signed short *) ((char *)dst + dst_step);
|
|
Packit |
4a16fb |
sum = (signed int *) ((char *)sum + sum_step);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
static void mix_areas_32(unsigned int size,
|
|
Packit |
4a16fb |
volatile signed int *dst, signed int *src,
|
|
Packit |
4a16fb |
volatile signed int *sum, size_t dst_step,
|
|
Packit |
4a16fb |
size_t src_step, size_t sum_step)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
register signed int sample, old_sample;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
for (;;) {
|
|
Packit |
4a16fb |
sample = *src >> 8;
|
|
Packit |
4a16fb |
old_sample = *sum;
|
|
Packit |
4a16fb |
if (ARCH_CMPXCHG(dst, 0, 1) == 0)
|
|
Packit |
4a16fb |
sample -= old_sample;
|
|
Packit |
4a16fb |
ARCH_ADD(sum, sample);
|
|
Packit |
4a16fb |
do {
|
|
Packit |
4a16fb |
old_sample = *sum;
|
|
Packit |
4a16fb |
if (old_sample > 0x7fffff)
|
|
Packit |
4a16fb |
sample = 0x7fffffff;
|
|
Packit |
4a16fb |
else if (old_sample < -0x800000)
|
|
Packit |
4a16fb |
sample = -0x80000000;
|
|
Packit |
4a16fb |
else
|
|
Packit |
4a16fb |
sample = old_sample * 256;
|
|
Packit |
4a16fb |
*dst = sample;
|
|
Packit |
4a16fb |
} while (IS_CONCURRENT && *sum != old_sample);
|
|
Packit |
4a16fb |
if (!--size)
|
|
Packit |
4a16fb |
return;
|
|
Packit |
4a16fb |
src = (signed int *) ((char *)src + src_step);
|
|
Packit |
4a16fb |
dst = (signed int *) ((char *)dst + dst_step);
|
|
Packit |
4a16fb |
sum = (signed int *) ((char *)sum + sum_step);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
static void mix_select_callbacks(snd_pcm_direct_t *dmix)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
dmix->u.dmix.mix_areas_16 = mix_areas_16;
|
|
Packit |
4a16fb |
dmix->u.dmix.mix_areas_32 = mix_areas_32;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
#else
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* non-concurrent version, supporting both endians */
|
|
Packit |
4a16fb |
#define generic_dmix_supported_format \
|
|
Packit |
4a16fb |
((1ULL << SND_PCM_FORMAT_S16_LE) | (1ULL << SND_PCM_FORMAT_S32_LE) |\
|
|
Packit |
4a16fb |
(1ULL << SND_PCM_FORMAT_S16_BE) | (1ULL << SND_PCM_FORMAT_S32_BE) |\
|
|
Packit |
4a16fb |
(1ULL << SND_PCM_FORMAT_S24_LE) | (1ULL << SND_PCM_FORMAT_S24_3LE) | \
|
|
Packit |
4a16fb |
(1ULL << SND_PCM_FORMAT_U8))
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
#include "bswap.h"
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
static void generic_mix_areas_16_native(unsigned int size,
|
|
Packit |
4a16fb |
volatile signed short *dst,
|
|
Packit |
4a16fb |
signed short *src,
|
|
Packit |
4a16fb |
volatile signed int *sum,
|
|
Packit |
4a16fb |
size_t dst_step,
|
|
Packit |
4a16fb |
size_t src_step,
|
|
Packit |
4a16fb |
size_t sum_step)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
register signed int sample;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
for (;;) {
|
|
Packit |
4a16fb |
sample = *src;
|
|
Packit |
4a16fb |
if (! *dst) {
|
|
Packit |
4a16fb |
*sum = sample;
|
|
Packit |
4a16fb |
*dst = *src;
|
|
Packit |
4a16fb |
} else {
|
|
Packit |
4a16fb |
sample += *sum;
|
|
Packit |
4a16fb |
*sum = sample;
|
|
Packit |
4a16fb |
if (sample > 0x7fff)
|
|
Packit |
4a16fb |
sample = 0x7fff;
|
|
Packit |
4a16fb |
else if (sample < -0x8000)
|
|
Packit |
4a16fb |
sample = -0x8000;
|
|
Packit |
4a16fb |
*dst = sample;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
if (!--size)
|
|
Packit |
4a16fb |
return;
|
|
Packit |
4a16fb |
src = (signed short *) ((char *)src + src_step);
|
|
Packit |
4a16fb |
dst = (signed short *) ((char *)dst + dst_step);
|
|
Packit |
4a16fb |
sum = (signed int *) ((char *)sum + sum_step);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
static void generic_remix_areas_16_native(unsigned int size,
|
|
Packit |
4a16fb |
volatile signed short *dst,
|
|
Packit |
4a16fb |
signed short *src,
|
|
Packit |
4a16fb |
volatile signed int *sum,
|
|
Packit |
4a16fb |
size_t dst_step,
|
|
Packit |
4a16fb |
size_t src_step,
|
|
Packit |
4a16fb |
size_t sum_step)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
register signed int sample;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
for (;;) {
|
|
Packit |
4a16fb |
sample = *src;
|
|
Packit |
4a16fb |
if (! *dst) {
|
|
Packit |
4a16fb |
*sum = -sample;
|
|
Packit |
4a16fb |
*dst = -sample;
|
|
Packit |
4a16fb |
} else {
|
|
Packit |
4a16fb |
*sum = sample = *sum - sample;
|
|
Packit |
4a16fb |
if (sample > 0x7fff)
|
|
Packit |
4a16fb |
sample = 0x7fff;
|
|
Packit |
4a16fb |
else if (sample < -0x8000)
|
|
Packit |
4a16fb |
sample = -0x8000;
|
|
Packit |
4a16fb |
*dst = sample;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
if (!--size)
|
|
Packit |
4a16fb |
return;
|
|
Packit |
4a16fb |
src = (signed short *) ((char *)src + src_step);
|
|
Packit |
4a16fb |
dst = (signed short *) ((char *)dst + dst_step);
|
|
Packit |
4a16fb |
sum = (signed int *) ((char *)sum + sum_step);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
static void generic_mix_areas_32_native(unsigned int size,
|
|
Packit |
4a16fb |
volatile signed int *dst,
|
|
Packit |
4a16fb |
signed int *src,
|
|
Packit |
4a16fb |
volatile signed int *sum,
|
|
Packit |
4a16fb |
size_t dst_step,
|
|
Packit |
4a16fb |
size_t src_step,
|
|
Packit |
4a16fb |
size_t sum_step)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
register signed int sample;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
for (;;) {
|
|
Packit |
4a16fb |
sample = *src >> 8;
|
|
Packit |
4a16fb |
if (! *dst) {
|
|
Packit |
4a16fb |
*sum = sample;
|
|
Packit |
4a16fb |
*dst = *src;
|
|
Packit |
4a16fb |
} else {
|
|
Packit |
4a16fb |
sample += *sum;
|
|
Packit |
4a16fb |
*sum = sample;
|
|
Packit |
4a16fb |
if (sample > 0x7fffff)
|
|
Packit |
4a16fb |
sample = 0x7fffffff;
|
|
Packit |
4a16fb |
else if (sample < -0x800000)
|
|
Packit |
4a16fb |
sample = -0x80000000;
|
|
Packit |
4a16fb |
else
|
|
Packit |
4a16fb |
sample *= 256;
|
|
Packit |
4a16fb |
*dst = sample;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
if (!--size)
|
|
Packit |
4a16fb |
return;
|
|
Packit |
4a16fb |
src = (signed int *) ((char *)src + src_step);
|
|
Packit |
4a16fb |
dst = (signed int *) ((char *)dst + dst_step);
|
|
Packit |
4a16fb |
sum = (signed int *) ((char *)sum + sum_step);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
static void generic_remix_areas_32_native(unsigned int size,
|
|
Packit |
4a16fb |
volatile signed int *dst,
|
|
Packit |
4a16fb |
signed int *src,
|
|
Packit |
4a16fb |
volatile signed int *sum,
|
|
Packit |
4a16fb |
size_t dst_step,
|
|
Packit |
4a16fb |
size_t src_step,
|
|
Packit |
4a16fb |
size_t sum_step)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
register signed int sample;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
for (;;) {
|
|
Packit |
4a16fb |
sample = *src >> 8;
|
|
Packit |
4a16fb |
if (! *dst) {
|
|
Packit |
4a16fb |
*sum = -sample;
|
|
Packit |
4a16fb |
*dst = -*src;
|
|
Packit |
4a16fb |
} else {
|
|
Packit |
4a16fb |
*sum = sample = *sum - sample;
|
|
Packit |
4a16fb |
if (sample > 0x7fffff)
|
|
Packit |
4a16fb |
sample = 0x7fffffff;
|
|
Packit |
4a16fb |
else if (sample < -0x800000)
|
|
Packit |
4a16fb |
sample = -0x80000000;
|
|
Packit |
4a16fb |
else
|
|
Packit |
4a16fb |
sample *= 256;
|
|
Packit |
4a16fb |
*dst = sample;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
if (!--size)
|
|
Packit |
4a16fb |
return;
|
|
Packit |
4a16fb |
src = (signed int *) ((char *)src + src_step);
|
|
Packit |
4a16fb |
dst = (signed int *) ((char *)dst + dst_step);
|
|
Packit |
4a16fb |
sum = (signed int *) ((char *)sum + sum_step);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
static void generic_mix_areas_16_swap(unsigned int size,
|
|
Packit |
4a16fb |
volatile signed short *dst,
|
|
Packit |
4a16fb |
signed short *src,
|
|
Packit |
4a16fb |
volatile signed int *sum,
|
|
Packit |
4a16fb |
size_t dst_step,
|
|
Packit |
4a16fb |
size_t src_step,
|
|
Packit |
4a16fb |
size_t sum_step)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
register signed int sample;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
for (;;) {
|
|
Packit |
4a16fb |
sample = (signed short) bswap_16(*src);
|
|
Packit |
4a16fb |
if (! *dst) {
|
|
Packit |
4a16fb |
*sum = sample;
|
|
Packit |
4a16fb |
*dst = *src;
|
|
Packit |
4a16fb |
} else {
|
|
Packit |
4a16fb |
sample += *sum;
|
|
Packit |
4a16fb |
*sum = sample;
|
|
Packit |
4a16fb |
if (sample > 0x7fff)
|
|
Packit |
4a16fb |
sample = 0x7fff;
|
|
Packit |
4a16fb |
else if (sample < -0x8000)
|
|
Packit |
4a16fb |
sample = -0x8000;
|
|
Packit |
4a16fb |
*dst = (signed short) bswap_16((signed short) sample);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
if (!--size)
|
|
Packit |
4a16fb |
return;
|
|
Packit |
4a16fb |
src = (signed short *) ((char *)src + src_step);
|
|
Packit |
4a16fb |
dst = (signed short *) ((char *)dst + dst_step);
|
|
Packit |
4a16fb |
sum = (signed int *) ((char *)sum + sum_step);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
static void generic_remix_areas_16_swap(unsigned int size,
|
|
Packit |
4a16fb |
volatile signed short *dst,
|
|
Packit |
4a16fb |
signed short *src,
|
|
Packit |
4a16fb |
volatile signed int *sum,
|
|
Packit |
4a16fb |
size_t dst_step,
|
|
Packit |
4a16fb |
size_t src_step,
|
|
Packit |
4a16fb |
size_t sum_step)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
register signed int sample;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
for (;;) {
|
|
Packit |
4a16fb |
sample = (signed short) bswap_16(*src);
|
|
Packit |
4a16fb |
if (! *dst) {
|
|
Packit |
4a16fb |
*sum = -sample;
|
|
Packit |
4a16fb |
*dst = (signed short) bswap_16((signed short) -sample);
|
|
Packit |
4a16fb |
} else {
|
|
Packit |
4a16fb |
*sum = sample = *sum - sample;
|
|
Packit |
4a16fb |
if (sample > 0x7fff)
|
|
Packit |
4a16fb |
sample = 0x7fff;
|
|
Packit |
4a16fb |
else if (sample < -0x8000)
|
|
Packit |
4a16fb |
sample = -0x8000;
|
|
Packit |
4a16fb |
*dst = (signed short) bswap_16((signed short) sample);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
if (!--size)
|
|
Packit |
4a16fb |
return;
|
|
Packit |
4a16fb |
src = (signed short *) ((char *)src + src_step);
|
|
Packit |
4a16fb |
dst = (signed short *) ((char *)dst + dst_step);
|
|
Packit |
4a16fb |
sum = (signed int *) ((char *)sum + sum_step);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
static void generic_mix_areas_32_swap(unsigned int size,
|
|
Packit |
4a16fb |
volatile signed int *dst,
|
|
Packit |
4a16fb |
signed int *src,
|
|
Packit |
4a16fb |
volatile signed int *sum,
|
|
Packit |
4a16fb |
size_t dst_step,
|
|
Packit |
4a16fb |
size_t src_step,
|
|
Packit |
4a16fb |
size_t sum_step)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
register signed int sample;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
for (;;) {
|
|
Packit |
4a16fb |
sample = bswap_32(*src) >> 8;
|
|
Packit |
4a16fb |
if (! *dst) {
|
|
Packit |
4a16fb |
*sum = sample;
|
|
Packit |
4a16fb |
*dst = *src;
|
|
Packit |
4a16fb |
} else {
|
|
Packit |
4a16fb |
sample += *sum;
|
|
Packit |
4a16fb |
*sum = sample;
|
|
Packit |
4a16fb |
if (sample > 0x7fffff)
|
|
Packit |
4a16fb |
sample = 0x7fffffff;
|
|
Packit |
4a16fb |
else if (sample < -0x800000)
|
|
Packit |
4a16fb |
sample = -0x80000000;
|
|
Packit |
4a16fb |
else
|
|
Packit |
4a16fb |
sample *= 256;
|
|
Packit |
4a16fb |
*dst = bswap_32(sample);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
if (!--size)
|
|
Packit |
4a16fb |
return;
|
|
Packit |
4a16fb |
src = (signed int *) ((char *)src + src_step);
|
|
Packit |
4a16fb |
dst = (signed int *) ((char *)dst + dst_step);
|
|
Packit |
4a16fb |
sum = (signed int *) ((char *)sum + sum_step);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
static void generic_remix_areas_32_swap(unsigned int size,
|
|
Packit |
4a16fb |
volatile signed int *dst,
|
|
Packit |
4a16fb |
signed int *src,
|
|
Packit |
4a16fb |
volatile signed int *sum,
|
|
Packit |
4a16fb |
size_t dst_step,
|
|
Packit |
4a16fb |
size_t src_step,
|
|
Packit |
4a16fb |
size_t sum_step)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
register signed int sample;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
for (;;) {
|
|
Packit |
4a16fb |
sample = bswap_32(*src) >> 8;
|
|
Packit |
4a16fb |
if (! *dst) {
|
|
Packit |
4a16fb |
*sum = -sample;
|
|
Packit |
4a16fb |
*dst = bswap_32(-sample);
|
|
Packit |
4a16fb |
} else {
|
|
Packit |
4a16fb |
*sum = sample = *sum - sample;
|
|
Packit |
4a16fb |
if (sample > 0x7fffff)
|
|
Packit |
4a16fb |
sample = 0x7fffffff;
|
|
Packit |
4a16fb |
else if (sample < -0x800000)
|
|
Packit |
4a16fb |
sample = -0x80000000;
|
|
Packit |
4a16fb |
else
|
|
Packit |
4a16fb |
sample *= 256;
|
|
Packit |
4a16fb |
*dst = bswap_32(sample);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
if (!--size)
|
|
Packit |
4a16fb |
return;
|
|
Packit |
4a16fb |
src = (signed int *) ((char *)src + src_step);
|
|
Packit |
4a16fb |
dst = (signed int *) ((char *)dst + dst_step);
|
|
Packit |
4a16fb |
sum = (signed int *) ((char *)sum + sum_step);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
/* always little endian */
|
|
Packit |
4a16fb |
static void generic_mix_areas_24(unsigned int size,
|
|
Packit |
4a16fb |
volatile unsigned char *dst,
|
|
Packit |
4a16fb |
unsigned char *src,
|
|
Packit |
4a16fb |
volatile signed int *sum,
|
|
Packit |
4a16fb |
size_t dst_step,
|
|
Packit |
4a16fb |
size_t src_step,
|
|
Packit |
4a16fb |
size_t sum_step)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
register signed int sample;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
for (;;) {
|
|
Packit |
4a16fb |
sample = src[0] | (src[1] << 8) | (((signed char *)src)[2] << 16);
|
|
Packit |
4a16fb |
if (!(dst[0] | dst[1] | dst[2])) {
|
|
Packit |
4a16fb |
*sum = sample;
|
|
Packit |
4a16fb |
} else {
|
|
Packit |
4a16fb |
sample += *sum;
|
|
Packit |
4a16fb |
*sum = sample;
|
|
Packit |
4a16fb |
if (sample > 0x7fffff)
|
|
Packit |
4a16fb |
sample = 0x7fffff;
|
|
Packit |
4a16fb |
else if (sample < -0x800000)
|
|
Packit |
4a16fb |
sample = -0x800000;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
dst[0] = sample;
|
|
Packit |
4a16fb |
dst[1] = sample >> 8;
|
|
Packit |
4a16fb |
dst[2] = sample >> 16;
|
|
Packit |
4a16fb |
if (!--size)
|
|
Packit |
4a16fb |
return;
|
|
Packit |
4a16fb |
dst += dst_step;
|
|
Packit |
4a16fb |
src += src_step;
|
|
Packit |
4a16fb |
sum = (signed int *) ((char *)sum + sum_step);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
static void generic_remix_areas_24(unsigned int size,
|
|
Packit |
4a16fb |
volatile unsigned char *dst,
|
|
Packit |
4a16fb |
unsigned char *src,
|
|
Packit |
4a16fb |
volatile signed int *sum,
|
|
Packit |
4a16fb |
size_t dst_step,
|
|
Packit |
4a16fb |
size_t src_step,
|
|
Packit |
4a16fb |
size_t sum_step)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
register signed int sample;
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
for (;;) {
|
|
Packit |
4a16fb |
sample = src[0] | (src[1] << 8) | (((signed char *)src)[2] << 16);
|
|
Packit |
4a16fb |
if (!(dst[0] | dst[1] | dst[2])) {
|
|
Packit |
4a16fb |
sample = -sample;
|
|
Packit |
4a16fb |
*sum = sample;
|
|
Packit |
4a16fb |
} else {
|
|
Packit |
4a16fb |
*sum = sample = *sum - sample;
|
|
Packit |
4a16fb |
if (sample > 0x7fffff)
|
|
Packit |
4a16fb |
sample = 0x7fffff;
|
|
Packit |
4a16fb |
else if (sample < -0x800000)
|
|
Packit |
4a16fb |
sample = -0x800000;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
dst[0] = sample;
|
|
Packit |
4a16fb |
dst[1] = sample >> 8;
|
|
Packit |
4a16fb |
dst[2] = sample >> 16;
|
|
Packit |
4a16fb |
if (!--size)
|
|
Packit |
4a16fb |
return;
|
|
Packit |
4a16fb |
dst += dst_step;
|
|
Packit |
4a16fb |
src += src_step;
|
|
Packit |
4a16fb |
sum = (signed int *) ((char *)sum + sum_step);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
static void generic_mix_areas_u8(unsigned int size,
|
|
Packit |
4a16fb |
volatile unsigned char *dst,
|
|
Packit |
4a16fb |
unsigned char *src,
|
|
Packit |
4a16fb |
volatile signed int *sum,
|
|
Packit |
4a16fb |
size_t dst_step,
|
|
Packit |
4a16fb |
size_t src_step,
|
|
Packit |
4a16fb |
size_t sum_step)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
for (;;) {
|
|
Packit |
4a16fb |
register int sample = *src - 0x80;
|
|
Packit |
4a16fb |
if (*dst == 0x80) {
|
|
Packit |
4a16fb |
*sum = sample;
|
|
Packit |
4a16fb |
} else {
|
|
Packit |
4a16fb |
sample += *sum;
|
|
Packit |
4a16fb |
*sum = sample;
|
|
Packit |
4a16fb |
if (sample > 0x7f)
|
|
Packit |
4a16fb |
sample = 0x7f;
|
|
Packit |
4a16fb |
else if (sample < -0x80)
|
|
Packit |
4a16fb |
sample = -0x80;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
*dst = sample + 0x80;
|
|
Packit |
4a16fb |
if (!--size)
|
|
Packit |
4a16fb |
return;
|
|
Packit |
4a16fb |
dst += dst_step;
|
|
Packit |
4a16fb |
src += src_step;
|
|
Packit |
4a16fb |
sum = (signed int *) ((char *)sum + sum_step);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
static void generic_remix_areas_u8(unsigned int size,
|
|
Packit |
4a16fb |
volatile unsigned char *dst,
|
|
Packit |
4a16fb |
unsigned char *src,
|
|
Packit |
4a16fb |
volatile signed int *sum,
|
|
Packit |
4a16fb |
size_t dst_step,
|
|
Packit |
4a16fb |
size_t src_step,
|
|
Packit |
4a16fb |
size_t sum_step)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
for (;;) {
|
|
Packit |
4a16fb |
register int sample = *src - 0x80;
|
|
Packit |
4a16fb |
if (*dst == 0x80) {
|
|
Packit |
4a16fb |
sample = -sample;
|
|
Packit |
4a16fb |
*sum = sample;
|
|
Packit |
4a16fb |
} else {
|
|
Packit |
4a16fb |
*sum = sample = *sum - sample;
|
|
Packit |
4a16fb |
if (sample > 0x7f)
|
|
Packit |
4a16fb |
sample = 0x7f;
|
|
Packit |
4a16fb |
else if (sample < -0x80)
|
|
Packit |
4a16fb |
sample = -0x80;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
*dst = sample + 0x80;
|
|
Packit |
4a16fb |
if (!--size)
|
|
Packit |
4a16fb |
return;
|
|
Packit |
4a16fb |
dst += dst_step;
|
|
Packit |
4a16fb |
src += src_step;
|
|
Packit |
4a16fb |
sum = (signed int *) ((char *)sum + sum_step);
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
static void generic_mix_select_callbacks(snd_pcm_direct_t *dmix)
|
|
Packit |
4a16fb |
{
|
|
Packit |
4a16fb |
if (snd_pcm_format_cpu_endian(dmix->shmptr->s.format)) {
|
|
Packit |
4a16fb |
dmix->u.dmix.mix_areas_16 = generic_mix_areas_16_native;
|
|
Packit |
4a16fb |
dmix->u.dmix.mix_areas_32 = generic_mix_areas_32_native;
|
|
Packit |
4a16fb |
dmix->u.dmix.remix_areas_16 = generic_remix_areas_16_native;
|
|
Packit |
4a16fb |
dmix->u.dmix.remix_areas_32 = generic_remix_areas_32_native;
|
|
Packit |
4a16fb |
} else {
|
|
Packit |
4a16fb |
dmix->u.dmix.mix_areas_16 = generic_mix_areas_16_swap;
|
|
Packit |
4a16fb |
dmix->u.dmix.mix_areas_32 = generic_mix_areas_32_swap;
|
|
Packit |
4a16fb |
dmix->u.dmix.remix_areas_16 = generic_remix_areas_16_swap;
|
|
Packit |
4a16fb |
dmix->u.dmix.remix_areas_32 = generic_remix_areas_32_swap;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
dmix->u.dmix.mix_areas_24 = generic_mix_areas_24;
|
|
Packit |
4a16fb |
dmix->u.dmix.mix_areas_u8 = generic_mix_areas_u8;
|
|
Packit |
4a16fb |
dmix->u.dmix.remix_areas_24 = generic_remix_areas_24;
|
|
Packit |
4a16fb |
dmix->u.dmix.remix_areas_u8 = generic_remix_areas_u8;
|
|
Packit |
4a16fb |
}
|
|
Packit |
4a16fb |
|
|
Packit |
4a16fb |
#endif
|