Revision 1d14ffa9 audio/mixeng_template.h
b/audio/mixeng_template.h | ||
---|---|---|
1 | 1 |
/* |
2 | 2 |
* QEMU Mixing engine |
3 |
*
|
|
4 |
* Copyright (c) 2004 Vassili Karpov (malc) |
|
5 |
*
|
|
3 |
* |
|
4 |
* Copyright (c) 2004-2005 Vassili Karpov (malc)
|
|
5 |
* |
|
6 | 6 |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | 7 |
* of this software and associated documentation files (the "Software"), to deal |
8 | 8 |
* in the Software without restriction, including without limitation the rights |
... | ... | |
27 | 27 |
* dec++'ified by Dscho |
28 | 28 |
*/ |
29 | 29 |
|
30 |
#ifndef SIGNED |
|
31 |
#define HALF (IN_MAX >> 1) |
|
32 |
#endif |
|
33 |
|
|
34 |
#ifdef NOVOL |
|
35 |
#define VOL(a, b) a |
|
36 |
#else |
|
37 |
#ifdef FLOAT_MIXENG |
|
38 |
#define VOL(a, b) ((a) * (b)) |
|
39 |
#else |
|
40 |
#define VOL(a, b) ((a) * (b)) >> 32 |
|
41 |
#endif |
|
42 |
#endif |
|
43 |
|
|
44 |
#define ET glue (ENDIAN_CONVERSION, glue (_, IN_T)) |
|
45 |
|
|
46 |
#ifdef FLOAT_MIXENG |
|
47 |
static real_t inline glue (conv_, ET) (IN_T v) |
|
48 |
{ |
|
49 |
IN_T nv = ENDIAN_CONVERT (v); |
|
50 |
|
|
51 |
#ifdef RECIPROCAL |
|
52 |
#ifdef SIGNED |
|
53 |
return nv * (1.f / (real_t) (IN_MAX - IN_MIN)); |
|
54 |
#else |
|
55 |
return (nv - HALF) * (1.f / (real_t) IN_MAX); |
|
56 |
#endif |
|
57 |
#else /* !RECIPROCAL */ |
|
30 | 58 |
#ifdef SIGNED |
31 |
#define HALFT IN_MAX |
|
32 |
#define HALF IN_MAX |
|
59 |
return nv / (real_t) (IN_MAX - IN_MIN); |
|
33 | 60 |
#else |
34 |
#define HALFT ((IN_MAX)>>1) |
|
35 |
#define HALF HALFT |
|
61 |
return (nv - HALF) / (real_t) IN_MAX; |
|
36 | 62 |
#endif |
63 |
#endif |
|
64 |
} |
|
37 | 65 |
|
38 |
static int64_t inline glue(conv_,IN_T) (IN_T v)
|
|
66 |
static IN_T inline glue (clip_, ET) (real_t v)
|
|
39 | 67 |
{ |
68 |
if (v >= 0.5) { |
|
69 |
return IN_MAX; |
|
70 |
} |
|
71 |
else if (v < -0.5) { |
|
72 |
return IN_MIN; |
|
73 |
} |
|
74 |
|
|
75 |
#ifdef SIGNED |
|
76 |
return ENDIAN_CONVERT ((IN_T) (v * (IN_MAX - IN_MIN))); |
|
77 |
#else |
|
78 |
return ENDIAN_CONVERT ((IN_T) ((v * IN_MAX) + HALF)); |
|
79 |
#endif |
|
80 |
} |
|
81 |
|
|
82 |
#else /* !FLOAT_MIXENG */ |
|
83 |
|
|
84 |
static inline int64_t glue (conv_, ET) (IN_T v) |
|
85 |
{ |
|
86 |
IN_T nv = ENDIAN_CONVERT (v); |
|
40 | 87 |
#ifdef SIGNED |
41 |
return (INT_MAX*(int64_t)v)/HALF;
|
|
88 |
return ((int64_t) nv) << (32 - SHIFT);
|
|
42 | 89 |
#else |
43 |
return (INT_MAX*((int64_t)v-HALFT))/HALF;
|
|
90 |
return ((int64_t) nv - HALF) << (32 - SHIFT);
|
|
44 | 91 |
#endif |
45 | 92 |
} |
46 | 93 |
|
47 |
static IN_T inline glue(clip_,IN_T) (int64_t v)
|
|
94 |
static inline IN_T glue (clip_, ET) (int64_t v)
|
|
48 | 95 |
{ |
49 |
if (v >= INT_MAX)
|
|
96 |
if (v >= 0x7f000000) {
|
|
50 | 97 |
return IN_MAX; |
51 |
else if (v < -INT_MAX) |
|
98 |
} |
|
99 |
else if (v < -2147483648LL) { |
|
52 | 100 |
return IN_MIN; |
101 |
} |
|
53 | 102 |
|
54 | 103 |
#ifdef SIGNED |
55 |
return (IN_T) (v*HALF/INT_MAX);
|
|
104 |
return ENDIAN_CONVERT ((IN_T) (v >> (32 - SHIFT)));
|
|
56 | 105 |
#else |
57 |
return (IN_T) (v+INT_MAX/2)*HALF/INT_MAX;
|
|
106 |
return ENDIAN_CONVERT ((IN_T) ((v >> (32 - SHIFT)) + HALF));
|
|
58 | 107 |
#endif |
59 | 108 |
} |
109 |
#endif |
|
60 | 110 |
|
61 |
static void glue(glue(conv_,IN_T),_to_stereo) (void *dst, const void *src,
|
|
62 |
int samples)
|
|
111 |
static void glue (glue (conv_, ET), _to_stereo)
|
|
112 |
(st_sample_t *dst, const void *src, int samples, volume_t *vol)
|
|
63 | 113 |
{ |
64 |
st_sample_t *out = (st_sample_t *) dst;
|
|
114 |
st_sample_t *out = dst; |
|
65 | 115 |
IN_T *in = (IN_T *) src; |
116 |
#ifndef NOVOL |
|
117 |
if (vol->mute) { |
|
118 |
mixeng_clear (dst, samples); |
|
119 |
return; |
|
120 |
} |
|
121 |
#else |
|
122 |
(void) vol; |
|
123 |
#endif |
|
66 | 124 |
while (samples--) { |
67 |
out->l = glue(conv_,IN_T) (*in++);
|
|
68 |
out->r = glue(conv_,IN_T) (*in++);
|
|
125 |
out->l = VOL (glue (conv_, ET) (*in++), vol->l);
|
|
126 |
out->r = VOL (glue (conv_, ET) (*in++), vol->r);
|
|
69 | 127 |
out += 1; |
70 | 128 |
} |
71 | 129 |
} |
72 | 130 |
|
73 |
static void glue(glue(conv_,IN_T),_to_mono) (void *dst, const void *src,
|
|
74 |
int samples)
|
|
131 |
static void glue (glue (conv_, ET), _to_mono)
|
|
132 |
(st_sample_t *dst, const void *src, int samples, volume_t *vol)
|
|
75 | 133 |
{ |
76 |
st_sample_t *out = (st_sample_t *) dst;
|
|
134 |
st_sample_t *out = dst; |
|
77 | 135 |
IN_T *in = (IN_T *) src; |
136 |
#ifndef NOVOL |
|
137 |
if (vol->mute) { |
|
138 |
mixeng_clear (dst, samples); |
|
139 |
return; |
|
140 |
} |
|
141 |
#else |
|
142 |
(void) vol; |
|
143 |
#endif |
|
78 | 144 |
while (samples--) { |
79 |
out->l = glue(conv_,IN_T) (in[0]);
|
|
145 |
out->l = VOL (glue (conv_, ET) (in[0]), vol->l);
|
|
80 | 146 |
out->r = out->l; |
81 | 147 |
out += 1; |
82 | 148 |
in += 1; |
83 | 149 |
} |
84 | 150 |
} |
85 | 151 |
|
86 |
static void glue(glue(clip_,IN_T),_from_stereo) (void *dst, const void *src,
|
|
87 |
int samples)
|
|
152 |
static void glue (glue (clip_, ET), _from_stereo)
|
|
153 |
(void *dst, const st_sample_t *src, int samples)
|
|
88 | 154 |
{ |
89 |
st_sample_t *in = (st_sample_t *) src;
|
|
155 |
const st_sample_t *in = src;
|
|
90 | 156 |
IN_T *out = (IN_T *) dst; |
91 | 157 |
while (samples--) { |
92 |
*out++ = glue(clip_,IN_T) (in->l);
|
|
93 |
*out++ = glue(clip_,IN_T) (in->r);
|
|
158 |
*out++ = glue (clip_, ET) (in->l);
|
|
159 |
*out++ = glue (clip_, ET) (in->r);
|
|
94 | 160 |
in += 1; |
95 | 161 |
} |
96 | 162 |
} |
97 | 163 |
|
98 |
static void glue(glue(clip_,IN_T),_from_mono) (void *dst, const void *src,
|
|
99 |
int samples)
|
|
164 |
static void glue (glue (clip_, ET), _from_mono)
|
|
165 |
(void *dst, const st_sample_t *src, int samples)
|
|
100 | 166 |
{ |
101 |
st_sample_t *in = (st_sample_t *) src;
|
|
167 |
const st_sample_t *in = src;
|
|
102 | 168 |
IN_T *out = (IN_T *) dst; |
103 | 169 |
while (samples--) { |
104 |
*out++ = glue(clip_,IN_T) (in->l + in->r);
|
|
170 |
*out++ = glue (clip_, ET) (in->l + in->r);
|
|
105 | 171 |
in += 1; |
106 | 172 |
} |
107 | 173 |
} |
108 | 174 |
|
175 |
#undef ET |
|
109 | 176 |
#undef HALF |
110 |
#undef HALFT |
|
111 |
|
|
177 |
#undef VOL |
Also available in: Unified diff