Add some more restrict keywords
[openal-soft.git] / OpenAL32 / Include / alFilter.h
blob5d5c213614159294375b0aac300fa884ef21ad9b
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 a1, a2; /* Transfer function coefficients "a" (a0 is pre-applied) */
46 ALfloat b0, b1, b2; /* Transfer function coefficients "b" */
48 void (*process)(struct ALfilterState *self, ALfloat *restrict dst, const ALfloat *restrict src, ALuint numsamples);
49 } ALfilterState;
50 #define ALfilterState_process(a, ...) ((a)->process((a), __VA_ARGS__))
52 /* Calculates the rcpQ (i.e. 1/Q) coefficient for shelving filters, using the
53 * reference gain and shelf slope parameter.
54 * 0 < gain
55 * 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 /* Calculates the rcpQ (i.e. 1/Q) coefficient for filters, using the frequency
62 * multiple (i.e. ref_freq / sampling_freq) and bandwidth.
63 * 0 < freq_mult < 0.5.
65 inline ALfloat calc_rcpQ_from_bandwidth(ALfloat freq_mult, ALfloat bandwidth)
67 ALfloat w0 = F_TAU * freq_mult;
68 return 2.0f*sinhf(logf(2.0f)/2.0f*bandwidth*w0/sinf(w0));
71 inline void ALfilterState_clear(ALfilterState *filter)
73 filter->x[0] = 0.0f;
74 filter->x[1] = 0.0f;
75 filter->y[0] = 0.0f;
76 filter->y[1] = 0.0f;
79 void ALfilterState_setParams(ALfilterState *filter, ALfilterType type, ALfloat gain, ALfloat freq_mult, ALfloat rcpQ);
81 inline ALfloat ALfilterState_processSingle(ALfilterState *filter, ALfloat sample)
83 ALfloat outsmp;
85 outsmp = filter->b0 * sample +
86 filter->b1 * filter->x[0] +
87 filter->b2 * filter->x[1] -
88 filter->a1 * filter->y[0] -
89 filter->a2 * filter->y[1];
90 filter->x[1] = filter->x[0];
91 filter->x[0] = sample;
92 filter->y[1] = filter->y[0];
93 filter->y[0] = outsmp;
95 return outsmp;
98 void ALfilterState_processC(ALfilterState *filter, ALfloat *restrict dst, const ALfloat *restrict src, ALuint numsamples);
100 inline void ALfilterState_processPassthru(ALfilterState *filter, const ALfloat *src, ALuint numsamples)
102 if(numsamples >= 2)
104 filter->x[1] = src[numsamples-2];
105 filter->x[0] = src[numsamples-1];
106 filter->y[1] = src[numsamples-2];
107 filter->y[0] = src[numsamples-1];
109 else if(numsamples == 1)
111 filter->x[1] = filter->x[0];
112 filter->x[0] = src[0];
113 filter->y[1] = filter->y[0];
114 filter->y[0] = src[0];
119 typedef struct ALfilter {
120 // Filter type (AL_FILTER_NULL, ...)
121 ALenum type;
123 ALfloat Gain;
124 ALfloat GainHF;
125 ALfloat HFReference;
126 ALfloat GainLF;
127 ALfloat LFReference;
129 void (*SetParami)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALint val);
130 void (*SetParamiv)(struct ALfilter *filter, ALCcontext *context, ALenum param, const ALint *vals);
131 void (*SetParamf)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val);
132 void (*SetParamfv)(struct ALfilter *filter, ALCcontext *context, ALenum param, const ALfloat *vals);
134 void (*GetParami)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALint *val);
135 void (*GetParamiv)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALint *vals);
136 void (*GetParamf)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val);
137 void (*GetParamfv)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals);
139 /* Self ID */
140 ALuint id;
141 } ALfilter;
143 #define ALfilter_SetParami(x, c, p, v) ((x)->SetParami((x),(c),(p),(v)))
144 #define ALfilter_SetParamiv(x, c, p, v) ((x)->SetParamiv((x),(c),(p),(v)))
145 #define ALfilter_SetParamf(x, c, p, v) ((x)->SetParamf((x),(c),(p),(v)))
146 #define ALfilter_SetParamfv(x, c, p, v) ((x)->SetParamfv((x),(c),(p),(v)))
148 #define ALfilter_GetParami(x, c, p, v) ((x)->GetParami((x),(c),(p),(v)))
149 #define ALfilter_GetParamiv(x, c, p, v) ((x)->GetParamiv((x),(c),(p),(v)))
150 #define ALfilter_GetParamf(x, c, p, v) ((x)->GetParamf((x),(c),(p),(v)))
151 #define ALfilter_GetParamfv(x, c, p, v) ((x)->GetParamfv((x),(c),(p),(v)))
153 inline void LockFiltersRead(ALCdevice *device)
154 { LockUIntMapRead(&device->FilterMap); }
155 inline void UnlockFiltersRead(ALCdevice *device)
156 { UnlockUIntMapRead(&device->FilterMap); }
157 inline void LockFiltersWrite(ALCdevice *device)
158 { LockUIntMapWrite(&device->FilterMap); }
159 inline void UnlockFiltersWrite(ALCdevice *device)
160 { UnlockUIntMapWrite(&device->FilterMap); }
162 inline struct ALfilter *LookupFilter(ALCdevice *device, ALuint id)
163 { return (struct ALfilter*)LookupUIntMapKeyNoLock(&device->FilterMap, id); }
164 inline struct ALfilter *RemoveFilter(ALCdevice *device, ALuint id)
165 { return (struct ALfilter*)RemoveUIntMapKeyNoLock(&device->FilterMap, id); }
167 ALvoid ReleaseALFilters(ALCdevice *device);
169 #ifdef __cplusplus
171 #endif
173 #endif