1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
3 Copyright (C) 2008 Nedko Arnaudov <nedko@arnaudov.name>
4 The DSP code is based on ladspa:1970 by Fons Adriaensen
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 /* if NDEBUG is defined, assert checks are disabled */
32 static float exp2ap(float x
)
38 // return ldexp(1 + x * (0.66 + 0.34 * x), i);
39 return ldexp(1 + x
* (0.6930 + x
* (0.2416 + x
* (0.0517 + x
* 0.0137))), i
);
52 struct param_sect
* sect_ptr
)
55 sect_ptr
->b
= sect_ptr
->g
= 1.0f
;
56 sect_ptr
->a
= sect_ptr
->s1
= sect_ptr
->s2
= sect_ptr
->z1
= sect_ptr
->z2
= 0.0f
;
62 struct param_sect
* sect_ptr
,
69 float s1
, s2
, d1
, d2
, a
, da
, x
, y
;
81 if (f
< 0.5f
* sect_ptr
->f
) f
= 0.5f
* sect_ptr
->f
;
82 else if (f
> 2.0f
* sect_ptr
->f
) f
= 2.0f
* sect_ptr
->f
;
84 sect_ptr
->s1
= -cosf(6.283185f
* f
);
85 d1
= (sect_ptr
->s1
- s1
) / k
;
91 if (g
< 0.5f
* sect_ptr
->g
) g
= 0.5f
* sect_ptr
->g
;
92 else if (g
> 2.0f
* sect_ptr
->g
) g
= 2.0f
* sect_ptr
->g
;
94 sect_ptr
->a
= 0.5f
* (g
- 1.0f
);
95 da
= (sect_ptr
->a
- a
) / k
;
101 if (b
< 0.5f
* sect_ptr
->b
) b
= 0.5f
* sect_ptr
->b
;
102 else if (b
> 2.0f
* sect_ptr
->b
) b
= 2.0f
* sect_ptr
->b
;
109 b
*= 7 * f
/ sqrtf(g
);
110 sect_ptr
->s2
= (1 - b
) / (1 + b
);
111 d2
= (sect_ptr
->s2
- s2
) / k
;
120 y
= x
- s2
* sect_ptr
->z2
;
121 *sig
++ -= a
* (sect_ptr
->z2
+ s2
* y
- x
);
122 y
-= s1
* sect_ptr
->z1
;
123 sect_ptr
->z2
= sect_ptr
->z1
+ s1
* y
;
124 sect_ptr
->z1
= y
+ 1e-10f
;
132 const float * global_parameters
[GLOBAL_PARAMETERS_COUNT
];
134 unsigned int bands_count
;
135 const float ** band_parameters
; /* [band_index * BAND_PARAMETERS_COUNT + parameter_index] */
139 struct param_sect
* sect
; /* [band_index] */
145 unsigned int bands_count
,
146 filter_handle
* handle_ptr
)
148 struct filter
* filter_ptr
;
151 assert(bands_count
> 0);
153 filter_ptr
= calloc(1, sizeof(struct filter
));
154 if (filter_ptr
== NULL
)
159 filter_ptr
->band_parameters
= calloc(bands_count
, sizeof(float *) * BAND_PARAMETERS_COUNT
);
160 if (filter_ptr
->band_parameters
== NULL
)
165 filter_ptr
->sect
= malloc(sizeof(struct param_sect
) * bands_count
);
166 if (filter_ptr
->sect
== NULL
)
168 goto free_band_params
;
171 filter_ptr
->sample_rate
= sample_rate
;
172 filter_ptr
->bands_count
= bands_count
;
173 filter_ptr
->fade
= 0;
174 filter_ptr
->gain
= 1.0;
176 for (j
= 0; j
< bands_count
; j
++)
178 param_sect_init(filter_ptr
->sect
+ j
);
181 *handle_ptr
= (filter_handle
)filter_ptr
;
186 free(filter_ptr
->band_parameters
);
195 #define filter_ptr ((struct filter *)handle)
199 filter_handle handle
)
201 free(filter_ptr
->sect
);
202 free(filter_ptr
->band_parameters
);
207 filter_connect_global_parameter(
208 filter_handle handle
,
209 unsigned int global_parameter
,
210 const float * value_ptr
)
212 assert(global_parameter
>= 0);
213 assert(global_parameter
< GLOBAL_PARAMETERS_COUNT
);
215 filter_ptr
->global_parameters
[global_parameter
] = value_ptr
;
219 filter_connect_band_parameter(
220 filter_handle handle
,
221 unsigned int band_index
,
222 unsigned int band_parameter
,
223 const float * value_ptr
)
225 assert(band_index
>= 0);
226 assert(band_index
< filter_ptr
->bands_count
);
227 assert(band_parameter
>= 0);
228 assert(band_parameter
< BAND_PARAMETERS_COUNT
);
230 filter_ptr
->band_parameters
[band_index
* BAND_PARAMETERS_COUNT
+ band_parameter
] = value_ptr
;
235 filter_handle handle
,
236 const float * input_buffer
,
237 float * output_buffer
,
238 unsigned long samples_count
)
245 float sfreq
[filter_ptr
->bands_count
];
246 float sband
[filter_ptr
->bands_count
];
247 float sgain
[filter_ptr
->bands_count
];
250 bands_count
= filter_ptr
->bands_count
;
252 fgain
= exp2ap(0.1661 * *filter_ptr
->global_parameters
[GLOBAL_PARAMETER_GAIN
]);
254 for (j
= 0; j
< bands_count
; j
++)
256 t
= *filter_ptr
->band_parameters
[BAND_PARAMETERS_COUNT
* j
+ BAND_PARAMETER_FREQUENCY
] / filter_ptr
->sample_rate
;
267 sband
[j
] = *filter_ptr
->band_parameters
[BAND_PARAMETERS_COUNT
* j
+ BAND_PARAMETER_BANDWIDTH
];
269 if (*filter_ptr
->band_parameters
[BAND_PARAMETERS_COUNT
* j
+ BAND_PARAMETER_ACTIVE
] > 0.0)
271 sgain
[j
] = exp2ap(0.1661 * *filter_ptr
->band_parameters
[BAND_PARAMETERS_COUNT
* j
+ BAND_PARAMETER_GAIN
]);
279 while (samples_count
)
281 k
= (samples_count
> 48) ? 32 : samples_count
;
284 g
= filter_ptr
->gain
;
290 else if (t
< 0.80 * g
)
295 filter_ptr
->gain
= t
;
297 for (i
= 0; i
< k
; i
++)
300 sig
[i
] = g
* input_buffer
[i
];
303 for (j
= 0; j
< bands_count
; j
++)
305 param_sect_proc(filter_ptr
->sect
+ j
, k
, sig
, sfreq
[j
], sband
[j
], sgain
[j
]);
308 j
= filter_ptr
->fade
;
312 if (*filter_ptr
->global_parameters
[GLOBAL_PARAMETER_ACTIVE
] > 0.0)
335 filter_ptr
->fade
= j
;
339 memcpy(output_buffer
, p
, k
* sizeof(float));
343 d
= (j
/ 16.0 - g
) / k
;
344 for (i
= 0; i
< k
; i
++)
347 output_buffer
[i
] = g
* sig
[i
] + (1 - g
) * input_buffer
[i
];