2 * some code for sample mixing
4 * (C) irixxxx, 2019,2020 added filtering
6 * This work is licensed under the terms of MAME license.
7 * See COPYING file in the top-level directory.
11 #include "../pico_int.h"
13 #define MAXOUT (+32767)
14 #define MINOUT (-32768)
17 #define Limit16(val) \
18 val -= val >> 3; /* reduce level to avoid clipping */ \
19 if ((s16)val != val) val = (val < 0 ? MINOUT : MAXOUT)
21 int mix_32_to_16_level;
24 int alpha; // alpha for EMA low pass
25 int y[2]; // filter intermediates
28 // NB ">>" rounds to -infinity, "/" to 0. To compensate the effect possibly use
29 // "-(-y>>n)" (round to +infinity) instead of "y>>n" in places.
31 // NB uses fixpoint; samples mustn't have more than (32-QB) bits. Adding the
32 // outputs of the sound sources together yields a max. of 18 bits, restricting
33 // QB to a maximum of 14.
35 // NB alpha for DC filtering shouldn't be smaller than 1/(1<<QB) to avoid loss.
38 // exponential moving average combined DC filter and lowpass filter
39 // y0[n] = (x[n]-y0[n-1])*alpha+y0[n-1], y1[n] = (y0[n] - y1[n-1])*(1-1/8192)
40 static inline int filter_band(struct iir *fi2, int x)
42 // low pass. alpha is Q8 to avoid loss by 32 bit overflow.
43 // fi2->y[0] += ((x<<(QB-8)) - (fi2->y[0]>>8)) * fi2->alpha;
44 fi2->y[0] += (x - (fi2->y[0]>>QB)) * fi2->alpha;
45 // DC filter. for alpha=1-1/8192 cutoff ~1HZ, for 1-1/1024 ~7Hz
46 fi2->y[1] += (fi2->y[0] - fi2->y[1]) >> QB;
47 return (fi2->y[0] - fi2->y[1]) >> QB;
50 // exponential moving average filter for DC filtering
51 // y[n] = (x[n]-y[n-1])*(1-1/8192) (corner approx. 1Hz, gain 1)
52 static inline int filter_exp(struct iir *fi2, int x)
54 fi2->y[1] += ((x << QB) - fi2->y[1]) >> QB;
55 return x - (fi2->y[1] >> QB);
58 // unfiltered (for testing)
59 static inline int filter_null(struct iir *fi2, int x)
64 #define filter filter_band
66 #define mix_32_to_16_stereo_core(dest, src, count, lv, fl) { \
68 struct iir lf = lfi2, rf = rfi2; \
70 for (; count > 0; count--) \
83 lfi2 = lf, rfi2 = rf; \
86 void mix_32_to_16_stereo_lvl(s16 *dest, s32 *src, int count)
88 mix_32_to_16_stereo_core(dest, src, count, mix_32_to_16_level, filter);
91 void mix_32_to_16_stereo(s16 *dest, s32 *src, int count)
93 mix_32_to_16_stereo_core(dest, src, count, 0, filter);
96 void mix_32_to_16_mono(s16 *dest, s32 *src, int count)
101 for (; count > 0; count--)
113 void mix_16h_to_32(s32 *dest_buf, s16 *mp3_buf, int count)
117 *dest_buf++ += (*mp3_buf++ * 5) >> 3;
121 void mix_16h_to_32_s1(s32 *dest_buf, s16 *mp3_buf, int count)
126 *dest_buf++ += (*mp3_buf++ * 5) >> 3;
127 *dest_buf++ += (*mp3_buf++ * 5) >> 3;
132 void mix_16h_to_32_s2(s32 *dest_buf, s16 *mp3_buf, int count)
137 *dest_buf++ += (*mp3_buf++ * 5) >> 3;
138 *dest_buf++ += (*mp3_buf++ * 5) >> 3;
143 // mixes cdda audio @44.1 KHz into dest_buf, resampling with nearest neighbour
144 void mix_16h_to_32_resample_stereo(s32 *dest_buf, s16 *cdda_buf, int count, int fac16)
148 int pos = 2 * (pos16>>16);
149 *dest_buf++ += (cdda_buf[pos ] * 5) >> 3;
150 *dest_buf++ += (cdda_buf[pos+1] * 5) >> 3;
155 // mixes cdda audio @44.1 KHz into dest_buf, resampling with nearest neighbour
156 void mix_16h_to_32_resample_mono(s32 *dest_buf, s16 *cdda_buf, int count, int fac16)
160 int pos = 2 * (pos16>>16);
161 *dest_buf += (cdda_buf[pos ] * 5) >> 4;
162 *dest_buf++ += (cdda_buf[pos+1] * 5) >> 4;
167 void mix_reset(int alpha_q16)
169 memset(&lfi2, 0, sizeof(lfi2));
170 memset(&rfi2, 0, sizeof(rfi2));
171 lfi2.alpha = rfi2.alpha = (0x10000-alpha_q16) >> 4; // filter alpha, Q12