00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef SIGNED
00031 #define HALF (IN_MAX >> 1)
00032 #endif
00033
00034 #ifdef CONFIG_MIXEMU
00035 #ifdef FLOAT_MIXENG
00036 #define VOL(a, b) ((a) * (b))
00037 #else
00038 #define VOL(a, b) ((a) * (b)) >> 32
00039 #endif
00040 #else
00041 #define VOL(a, b) a
00042 #endif
00043
00044 #define ET glue (ENDIAN_CONVERSION, glue (_, IN_T))
00045
00046 #ifdef FLOAT_MIXENG
00047 static mixeng_real inline glue (conv_, ET) (IN_T v)
00048 {
00049 IN_T nv = ENDIAN_CONVERT (v);
00050
00051 #ifdef RECIPROCAL
00052 #ifdef SIGNED
00053 return nv * (1.f / (mixeng_real) (IN_MAX - IN_MIN));
00054 #else
00055 return (nv - HALF) * (1.f / (mixeng_real) IN_MAX);
00056 #endif
00057 #else
00058 #ifdef SIGNED
00059 return nv / (mixeng_real) (IN_MAX - IN_MIN);
00060 #else
00061 return (nv - HALF) / (mixeng_real) IN_MAX;
00062 #endif
00063 #endif
00064 }
00065
00066 static IN_T inline glue (clip_, ET) (mixeng_real v)
00067 {
00068 if (v >= 0.5) {
00069 return IN_MAX;
00070 }
00071 else if (v < -0.5) {
00072 return IN_MIN;
00073 }
00074
00075 #ifdef SIGNED
00076 return ENDIAN_CONVERT ((IN_T) (v * (IN_MAX - IN_MIN)));
00077 #else
00078 return ENDIAN_CONVERT ((IN_T) ((v * IN_MAX) + HALF));
00079 #endif
00080 }
00081
00082 #else
00083
00084 static inline int64_t glue (conv_, ET) (IN_T v)
00085 {
00086 IN_T nv = ENDIAN_CONVERT (v);
00087 #ifdef SIGNED
00088 return ((int64_t) nv) << (32 - SHIFT);
00089 #else
00090 return ((int64_t) nv - HALF) << (32 - SHIFT);
00091 #endif
00092 }
00093
00094 static inline IN_T glue (clip_, ET) (int64_t v)
00095 {
00096 if (v >= 0x7f000000) {
00097 return IN_MAX;
00098 }
00099 else if (v < -2147483648LL) {
00100 return IN_MIN;
00101 }
00102
00103 #ifdef SIGNED
00104 return ENDIAN_CONVERT ((IN_T) (v >> (32 - SHIFT)));
00105 #else
00106 return ENDIAN_CONVERT ((IN_T) ((v >> (32 - SHIFT)) + HALF));
00107 #endif
00108 }
00109 #endif
00110
00111 static void glue (glue (conv_, ET), _to_stereo)
00112 (struct st_sample *dst, const void *src, int samples, struct mixeng_volume *vol)
00113 {
00114 struct st_sample *out = dst;
00115 IN_T *in = (IN_T *) src;
00116 #ifdef CONFIG_MIXEMU
00117 if (vol->mute) {
00118 mixeng_clear (dst, samples);
00119 return;
00120 }
00121 #else
00122 (void) vol;
00123 #endif
00124 while (samples--) {
00125 out->l = VOL (glue (conv_, ET) (*in++), vol->l);
00126 out->r = VOL (glue (conv_, ET) (*in++), vol->r);
00127 out += 1;
00128 }
00129 }
00130
00131 static void glue (glue (conv_, ET), _to_mono)
00132 (struct st_sample *dst, const void *src, int samples, struct mixeng_volume *vol)
00133 {
00134 struct st_sample *out = dst;
00135 IN_T *in = (IN_T *) src;
00136 #ifdef CONFIG_MIXEMU
00137 if (vol->mute) {
00138 mixeng_clear (dst, samples);
00139 return;
00140 }
00141 #else
00142 (void) vol;
00143 #endif
00144 while (samples--) {
00145 out->l = VOL (glue (conv_, ET) (in[0]), vol->l);
00146 out->r = out->l;
00147 out += 1;
00148 in += 1;
00149 }
00150 }
00151
00152 static void glue (glue (clip_, ET), _from_stereo)
00153 (void *dst, const struct st_sample *src, int samples)
00154 {
00155 const struct st_sample *in = src;
00156 IN_T *out = (IN_T *) dst;
00157 while (samples--) {
00158 *out++ = glue (clip_, ET) (in->l);
00159 *out++ = glue (clip_, ET) (in->r);
00160 in += 1;
00161 }
00162 }
00163
00164 static void glue (glue (clip_, ET), _from_mono)
00165 (void *dst, const struct st_sample *src, int samples)
00166 {
00167 const struct st_sample *in = src;
00168 IN_T *out = (IN_T *) dst;
00169 while (samples--) {
00170 *out++ = glue (clip_, ET) (in->l + in->r);
00171 in += 1;
00172 }
00173 }
00174
00175 #undef ET
00176 #undef HALF
00177 #undef VOL