/* Extended Module Player * Copyright (C) 1996-2001 Claudio Matsuoka and Hipolito Carraro Jr. * * This file is part of the Extended Module Player and is distributed * under the terms of the GNU General Public License. See docs/COPYING * for more information. * * $Id: mix_all.c,v 1.7 2001/01/03 10:57:37 claudio Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "xmpi.h" #include "driver.h" #include "mixer.h" #include "synth.h" /* Mixers * * To increase performance eight mixers are defined, one for each * combination of the following parameters: interpolation, resolution * and number of channels. */ #define INTERPOLATE() do { \ if (itpt >> SMIX_SFT_FT) { \ cur_bk += itpt >> SMIX_SFT_FT; \ smp_x1 = in_bk[cur_bk]; \ smp_dt = in_bk[cur_bk + 1] - smp_x1; \ itpt &= SMIX_AND_FT; \ } \ smp_in = smp_x1 + ((itpt * smp_dt) >> SMIX_SFT_FT); \ } while (0) #define DONT_INTERPOLATE() do { \ smp_in = in_bk[itpt >> SMIX_SFT_FT]; \ } while (0) #define DO_FILTER() do { \ smp_in = (smp_in * vi->flt_B0 + fx1 * vi->flt_B1 + fx2 * vi->flt_B2) / FILTER_PRECISION; \ fx2 = fx1; fx1 = smp_in; \ } while (0) #define SAVE_FILTER() do { \ vi->flt_X1 = fx1; \ vi->flt_X2 = fx2; \ } while (0) #define MIX_STEREO() do { \ *(tmp_bk++) += smp_in * vr; \ *(tmp_bk++) += smp_in * vl; \ itpt += itpt_inc; \ } while (0) #define MIX_MONO() do { \ *(tmp_bk++) += smp_in * vl; \ itpt += itpt_inc; \ } while (0) #define MIX_LOOP(x) do { \ while (count--) { x } \ } while (0) #define VAR_NORM(x) \ register int smp_in; \ x *in_bk = vi->sptr; \ int cur_bk = vi->pos - 1; \ int itpt = vi->itpt + (1 << SMIX_SFT_FT) #define VAR_ITPT(x) \ VAR_NORM(x); \ int smp_x1 = 0, smp_dt = 0 #define VAR_FILT \ int fx1 = vi->flt_X1, fx2 = vi->flt_X2 #define SMIX_MIXER(f) void f(struct voice_info *vi, int* tmp_bk, \ int count, int vl, int vr, int itpt_inc) /* Handler for 8 bit samples, interpolated stereo output */ SMIX_MIXER(smix_st8itpt) { VAR_ITPT(int8); vl <<= 8; vr <<= 8; while (count--) { INTERPOLATE (); MIX_STEREO (); } } /* Handler for 16 bit samples, interpolated stereo output */ SMIX_MIXER(smix_st16itpt) { VAR_ITPT(int16); while (count--) { INTERPOLATE (); MIX_STEREO (); } } /* Handler for 8 bit samples, non-interpolated stereo output */ SMIX_MIXER(smix_st8norm) { VAR_NORM(int8); vl <<= 8; vr <<= 8; in_bk += cur_bk; while (count--) { DONT_INTERPOLATE (); MIX_STEREO (); } } /* Handler for 16 bit samples, non-interpolated stereo output */ SMIX_MIXER(smix_st16norm) { VAR_NORM(int16); in_bk += cur_bk; while (count--) { DONT_INTERPOLATE (); MIX_STEREO (); } } /* Handler for 8 bit samples, interpolated mono output */ SMIX_MIXER(smix_mn8itpt) { VAR_ITPT(int8); vl <<= 9; while (count--) { INTERPOLATE (); MIX_MONO (); } } /* Handler for 16 bit samples, interpolated mono output */ SMIX_MIXER(smix_mn16itpt) { VAR_ITPT(int16); vl <<= 1; while (count--) { INTERPOLATE (); MIX_MONO (); } } /* Handler for 8 bit samples, non-interpolated mono output */ SMIX_MIXER(smix_mn8norm) { VAR_NORM(int8); vl <<= 9; in_bk += cur_bk; while (count--) { DONT_INTERPOLATE (); MIX_MONO (); } } /* Handler for 16 bit samples, non-interpolated mono output */ SMIX_MIXER(smix_mn16norm) { VAR_NORM(int16); vl <<= 1; in_bk += cur_bk; while (count--) { DONT_INTERPOLATE (); MIX_MONO (); } } /* * Filtering mixers */ /* Handler for 8 bit samples, interpolated stereo output */ SMIX_MIXER(smix_st8itpt_flt) { VAR_ITPT(int8); VAR_FILT; vl <<= 8; vr <<= 8; while (count--) { INTERPOLATE (); DO_FILTER (); MIX_STEREO (); } SAVE_FILTER(); } /* Handler for 16 bit samples, interpolated stereo output */ SMIX_MIXER(smix_st16itpt_flt) { VAR_ITPT(int16); VAR_FILT; while (count--) { INTERPOLATE (); DO_FILTER (); MIX_STEREO (); } SAVE_FILTER(); } /* Handler for 8 bit samples, interpolated mono output */ SMIX_MIXER(smix_mn8itpt_flt) { VAR_ITPT(int8); VAR_FILT; vl <<= 9; while (count--) { INTERPOLATE (); DO_FILTER (); MIX_MONO (); } SAVE_FILTER(); } /* Handler for 16 bit samples, interpolated mono output */ SMIX_MIXER(smix_mn16itpt_flt) { VAR_ITPT(int16); VAR_FILT; vl <<= 1; while (count--) { INTERPOLATE (); DO_FILTER (); MIX_MONO (); } SAVE_FILTER(); } /* Handler for synthesized sounds */ SMIX_MIXER(smix_synth) { synth_mixer (tmp_bk, count, itpt_inc, vl, vr); }