summaryrefslogtreecommitdiff
path: root/audio/mixeng_template.h
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2005-10-30 18:58:22 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2005-10-30 18:58:22 +0000
commit1d14ffa97eacd3cb722271eaf6f093038396eac4 (patch)
tree1aae1f090262c3642cc672971890141050413d26 /audio/mixeng_template.h
parent3b0d4f61c917c4612b561d75b33a11f4da00738b (diff)
downloadqemu-1d14ffa97eacd3cb722271eaf6f093038396eac4.tar.gz
merged 15a_aqemu.patch audio patch (malc)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1584 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'audio/mixeng_template.h')
-rw-r--r--audio/mixeng_template.h136
1 files changed, 101 insertions, 35 deletions
diff --git a/audio/mixeng_template.h b/audio/mixeng_template.h
index f3b3f654fd..d726441e2e 100644
--- a/audio/mixeng_template.h
+++ b/audio/mixeng_template.h
@@ -1,8 +1,8 @@
/*
* QEMU Mixing engine
- *
- * Copyright (c) 2004 Vassili Karpov (malc)
- *
+ *
+ * Copyright (c) 2004-2005 Vassili Karpov (malc)
+ *
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
@@ -27,85 +27,151 @@
* dec++'ified by Dscho
*/
+#ifndef SIGNED
+#define HALF (IN_MAX >> 1)
+#endif
+
+#ifdef NOVOL
+#define VOL(a, b) a
+#else
+#ifdef FLOAT_MIXENG
+#define VOL(a, b) ((a) * (b))
+#else
+#define VOL(a, b) ((a) * (b)) >> 32
+#endif
+#endif
+
+#define ET glue (ENDIAN_CONVERSION, glue (_, IN_T))
+
+#ifdef FLOAT_MIXENG
+static real_t inline glue (conv_, ET) (IN_T v)
+{
+ IN_T nv = ENDIAN_CONVERT (v);
+
+#ifdef RECIPROCAL
+#ifdef SIGNED
+ return nv * (1.f / (real_t) (IN_MAX - IN_MIN));
+#else
+ return (nv - HALF) * (1.f / (real_t) IN_MAX);
+#endif
+#else /* !RECIPROCAL */
#ifdef SIGNED
-#define HALFT IN_MAX
-#define HALF IN_MAX
+ return nv / (real_t) (IN_MAX - IN_MIN);
#else
-#define HALFT ((IN_MAX)>>1)
-#define HALF HALFT
+ return (nv - HALF) / (real_t) IN_MAX;
#endif
+#endif
+}
-static int64_t inline glue(conv_,IN_T) (IN_T v)
+static IN_T inline glue (clip_, ET) (real_t v)
{
+ if (v >= 0.5) {
+ return IN_MAX;
+ }
+ else if (v < -0.5) {
+ return IN_MIN;
+ }
+
+#ifdef SIGNED
+ return ENDIAN_CONVERT ((IN_T) (v * (IN_MAX - IN_MIN)));
+#else
+ return ENDIAN_CONVERT ((IN_T) ((v * IN_MAX) + HALF));
+#endif
+}
+
+#else /* !FLOAT_MIXENG */
+
+static inline int64_t glue (conv_, ET) (IN_T v)
+{
+ IN_T nv = ENDIAN_CONVERT (v);
#ifdef SIGNED
- return (INT_MAX*(int64_t)v)/HALF;
+ return ((int64_t) nv) << (32 - SHIFT);
#else
- return (INT_MAX*((int64_t)v-HALFT))/HALF;
+ return ((int64_t) nv - HALF) << (32 - SHIFT);
#endif
}
-static IN_T inline glue(clip_,IN_T) (int64_t v)
+static inline IN_T glue (clip_, ET) (int64_t v)
{
- if (v >= INT_MAX)
+ if (v >= 0x7f000000) {
return IN_MAX;
- else if (v < -INT_MAX)
+ }
+ else if (v < -2147483648LL) {
return IN_MIN;
+ }
#ifdef SIGNED
- return (IN_T) (v*HALF/INT_MAX);
+ return ENDIAN_CONVERT ((IN_T) (v >> (32 - SHIFT)));
#else
- return (IN_T) (v+INT_MAX/2)*HALF/INT_MAX;
+ return ENDIAN_CONVERT ((IN_T) ((v >> (32 - SHIFT)) + HALF));
#endif
}
+#endif
-static void glue(glue(conv_,IN_T),_to_stereo) (void *dst, const void *src,
- int samples)
+static void glue (glue (conv_, ET), _to_stereo)
+ (st_sample_t *dst, const void *src, int samples, volume_t *vol)
{
- st_sample_t *out = (st_sample_t *) dst;
+ st_sample_t *out = dst;
IN_T *in = (IN_T *) src;
+#ifndef NOVOL
+ if (vol->mute) {
+ mixeng_clear (dst, samples);
+ return;
+ }
+#else
+ (void) vol;
+#endif
while (samples--) {
- out->l = glue(conv_,IN_T) (*in++);
- out->r = glue(conv_,IN_T) (*in++);
+ out->l = VOL (glue (conv_, ET) (*in++), vol->l);
+ out->r = VOL (glue (conv_, ET) (*in++), vol->r);
out += 1;
}
}
-static void glue(glue(conv_,IN_T),_to_mono) (void *dst, const void *src,
- int samples)
+static void glue (glue (conv_, ET), _to_mono)
+ (st_sample_t *dst, const void *src, int samples, volume_t *vol)
{
- st_sample_t *out = (st_sample_t *) dst;
+ st_sample_t *out = dst;
IN_T *in = (IN_T *) src;
+#ifndef NOVOL
+ if (vol->mute) {
+ mixeng_clear (dst, samples);
+ return;
+ }
+#else
+ (void) vol;
+#endif
while (samples--) {
- out->l = glue(conv_,IN_T) (in[0]);
+ out->l = VOL (glue (conv_, ET) (in[0]), vol->l);
out->r = out->l;
out += 1;
in += 1;
}
}
-static void glue(glue(clip_,IN_T),_from_stereo) (void *dst, const void *src,
- int samples)
+static void glue (glue (clip_, ET), _from_stereo)
+ (void *dst, const st_sample_t *src, int samples)
{
- st_sample_t *in = (st_sample_t *) src;
+ const st_sample_t *in = src;
IN_T *out = (IN_T *) dst;
while (samples--) {
- *out++ = glue(clip_,IN_T) (in->l);
- *out++ = glue(clip_,IN_T) (in->r);
+ *out++ = glue (clip_, ET) (in->l);
+ *out++ = glue (clip_, ET) (in->r);
in += 1;
}
}
-static void glue(glue(clip_,IN_T),_from_mono) (void *dst, const void *src,
- int samples)
+static void glue (glue (clip_, ET), _from_mono)
+ (void *dst, const st_sample_t *src, int samples)
{
- st_sample_t *in = (st_sample_t *) src;
+ const st_sample_t *in = src;
IN_T *out = (IN_T *) dst;
while (samples--) {
- *out++ = glue(clip_,IN_T) (in->l + in->r);
+ *out++ = glue (clip_, ET) (in->l + in->r);
in += 1;
}
}
+#undef ET
#undef HALF
-#undef HALFT
-
+#undef VOL