Store filters in an array of lists
[openal-soft.git] / OpenAL32 / Include / alFilter.h
blobe28b7b2b58fb28a2157d57fd8cd021a038710ab2
1 #ifndef _AL_FILTER_H_
2 #define _AL_FILTER_H_
4 #include "alMain.h"
6 #include "math_defs.h"
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
12 #define LOWPASSFREQREF (5000.0f)
13 #define HIGHPASSFREQREF (250.0f)
16 /* Filters implementation is based on the "Cookbook formulae for audio
17 * EQ biquad filter coefficients" by Robert Bristow-Johnson
18 * http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
20 /* Implementation note: For the shelf filters, the specified gain is for the
21 * reference frequency, which is the centerpoint of the transition band. This
22 * better matches EFX filter design. To set the gain for the shelf itself, use
23 * the square root of the desired linear gain (or halve the dB gain).
26 typedef enum ALfilterType {
27 /** EFX-style low-pass filter, specifying a gain and reference frequency. */
28 ALfilterType_HighShelf,
29 /** EFX-style high-pass filter, specifying a gain and reference frequency. */
30 ALfilterType_LowShelf,
31 /** Peaking filter, specifying a gain and reference frequency. */
32 ALfilterType_Peaking,
34 /** Low-pass cut-off filter, specifying a cut-off frequency. */
35 ALfilterType_LowPass,
36 /** High-pass cut-off filter, specifying a cut-off frequency. */
37 ALfilterType_HighPass,
38 /** Band-pass filter, specifying a center frequency. */
39 ALfilterType_BandPass,
40 } ALfilterType;
42 typedef struct ALfilterState {
43 ALfloat x[2]; /* History of two last input samples */
44 ALfloat y[2]; /* History of two last output samples */
45 ALfloat b0, b1, b2; /* Transfer function coefficients "b" */
46 ALfloat a1, a2; /* Transfer function coefficients "a" (a0 is pre-applied) */
47 } ALfilterState;
48 /* Currently only a C-based filter process method is implemented. */
49 #define ALfilterState_process ALfilterState_processC
51 /**
52 * Calculates the rcpQ (i.e. 1/Q) coefficient for shelving filters, using the
53 * reference gain and shelf slope parameter.
54 * \param gain 0 < gain
55 * \param slope 0 < slope <= 1
57 inline ALfloat calc_rcpQ_from_slope(ALfloat gain, ALfloat slope)
59 return sqrtf((gain + 1.0f/gain)*(1.0f/slope - 1.0f) + 2.0f);
61 /**
62 * Calculates the rcpQ (i.e. 1/Q) coefficient for filters, using the normalized
63 * reference frequency and bandwidth.
64 * \param f0norm 0 < f0norm < 0.5.
65 * \param bandwidth 0 < bandwidth
67 inline ALfloat calc_rcpQ_from_bandwidth(ALfloat f0norm, ALfloat bandwidth)
69 ALfloat w0 = F_TAU * f0norm;
70 return 2.0f*sinhf(logf(2.0f)/2.0f*bandwidth*w0/sinf(w0));
73 inline void ALfilterState_clear(ALfilterState *filter)
75 filter->x[0] = 0.0f;
76 filter->x[1] = 0.0f;
77 filter->y[0] = 0.0f;
78 filter->y[1] = 0.0f;
81 /**
82 * Sets up the filter state for the specified filter type and its parameters.
84 * \param filter The filter object to prepare.
85 * \param type The type of filter for the object to apply.
86 * \param gain The gain for the reference frequency response. Only used by the
87 * Shelf and Peaking filter types.
88 * \param f0norm The normalized reference frequency (ref_freq / sample_rate).
89 * This is the center point for the Shelf, Peaking, and BandPass
90 * filter types, or the cutoff frequency for the LowPass and
91 * HighPass filter types.
92 * \param rcpQ The reciprocal of the Q coefficient for the filter's transition
93 * band. Can be generated from calc_rcpQ_from_slope or
94 * calc_rcpQ_from_bandwidth depending on the available data.
96 void ALfilterState_setParams(ALfilterState *filter, ALfilterType type, ALfloat gain, ALfloat f0norm, ALfloat rcpQ);
98 inline void ALfilterState_copyParams(ALfilterState *restrict dst, const ALfilterState *restrict src)
100 dst->b0 = src->b0;
101 dst->b1 = src->b1;
102 dst->b2 = src->b2;
103 dst->a1 = src->a1;
104 dst->a2 = src->a2;
107 void ALfilterState_processC(ALfilterState *filter, ALfloat *restrict dst, const ALfloat *restrict src, ALsizei numsamples);
109 inline void ALfilterState_processPassthru(ALfilterState *filter, const ALfloat *restrict src, ALsizei numsamples)
111 if(numsamples >= 2)
113 filter->x[1] = src[numsamples-2];
114 filter->x[0] = src[numsamples-1];
115 filter->y[1] = src[numsamples-2];
116 filter->y[0] = src[numsamples-1];
118 else if(numsamples == 1)
120 filter->x[1] = filter->x[0];
121 filter->x[0] = src[0];
122 filter->y[1] = filter->y[0];
123 filter->y[0] = src[0];
128 struct ALfilter;
130 typedef struct ALfilterVtable {
131 void (*const setParami)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALint val);
132 void (*const setParamiv)(struct ALfilter *filter, ALCcontext *context, ALenum param, const ALint *vals);
133 void (*const setParamf)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val);
134 void (*const setParamfv)(struct ALfilter *filter, ALCcontext *context, ALenum param, const ALfloat *vals);
136 void (*const getParami)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALint *val);
137 void (*const getParamiv)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALint *vals);
138 void (*const getParamf)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val);
139 void (*const getParamfv)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals);
140 } ALfilterVtable;
142 #define DEFINE_ALFILTER_VTABLE(T) \
143 const struct ALfilterVtable T##_vtable = { \
144 T##_setParami, T##_setParamiv, \
145 T##_setParamf, T##_setParamfv, \
146 T##_getParami, T##_getParamiv, \
147 T##_getParamf, T##_getParamfv, \
150 typedef struct ALfilter {
151 // Filter type (AL_FILTER_NULL, ...)
152 ALenum type;
154 ALfloat Gain;
155 ALfloat GainHF;
156 ALfloat HFReference;
157 ALfloat GainLF;
158 ALfloat LFReference;
160 const struct ALfilterVtable *vtbl;
162 /* Self ID */
163 ALuint id;
164 } ALfilter;
166 void ReleaseALFilters(ALCdevice *device);
168 #ifdef __cplusplus
170 #endif
172 #endif