1 #include <stdlib.h>
2 #include <math.h>
3 #include <string.h>
4
5 typedef struct {
6
7 int n_channels;
8
9 /* ... */
10
11 } my_data_struct;
12
13 /* par is an ascii string containing parameters given on the 'filter=' line
14 * in the configuration file
15 */
init_library(int bits_per_sample,int n_channels,int sample_rate,char * par)16 void * init_library(int bits_per_sample, int n_channels, int sample_rate, char *par)
17 {
18 void *pnt;
19
20 /* init library */
21
22 /* you might allocate some datastructure here or so and then
23 * return a point to it which will be then given for each call
24 * to do_filter as the first parameter
25 */
26
27 pnt = malloc(sizeof(my_data_struct));
28 if (!pnt)
29 exit(1);
30
31 memset(pnt, 0x00, sizeof(my_data_struct));
32
33 ((my_data_struct *)pnt) -> n_channels = n_channels;
34
35 return pnt;
36 }
37
do_filter(void * lib_data,void * sample_data,int n_samples)38 void do_filter(void *lib_data, void *sample_data, int n_samples)
39 {
40 my_data_struct *mds = (my_data_struct *)lib_data;
41 short *pnt = (short *)sample_data;
42 int channel;
43
44 /* do the filtering */
45 /* warning: sample_data is n_samples * n_channels in size! */
46
47 /* code taken from http://musicdsp.org/archive.php?classid=3#28 */
48 /* - Three one-poles combined in parallel
49 * - Output stays within input limits
50 * - 18 dB/oct (approx) frequency response rolloff
51 * - Quite fast, 2x3 parallel multiplications/sample, no internal buffers
52 * - Time-scalable, allowing use with different samplerates
53 * - Impulse and edge responses have continuous differential
54 * - Requires high internal numerical precision
55 */
56
57 /* Parameters */
58 /* Number of samples from start of edge to halfway to new value */
59 const double scale = 100;
60 /* 0 < Smoothness < 1. High is better, but may cause precision problems */
61 const double smoothness = 0.999;
62
63 /* Precalc variables */
64 double a = 1.0-(2.4/scale); /* Could also be set directly */
65 double b = smoothness; /* -"- */
66 double acoef = a;
67 double bcoef = a*b;
68 double ccoef = a*b*b;
69 double mastergain = 1.0 / (-1.0/(log(a)+2.0*log(b))+2.0/
70 (log(a)+log(b))-1.0/log(a));
71 double again = mastergain;
72 double bgain = mastergain * (log(a*b*b)*(log(a)-log(a*b)) /
73 ((log(a*b*b)-log(a*b))*log(a*b))
74 - log(a)/log(a*b));
75 double cgain = mastergain * (-(log(a)-log(a*b)) /
76 (log(a*b*b)-log(a*b)));
77
78 /* Runtime variables */
79 long streamofs;
80 double areg = 0;
81 double breg = 0;
82 double creg = 0;
83
84 /* Main loop */
85 for(channel = 0; channel < mds -> n_channels; channel++)
86 {
87 for (streamofs = 0; streamofs < n_samples; streamofs++)
88 {
89 long temp;
90
91 /* Update filters */
92 areg = acoef * areg + pnt[(streamofs * mds -> n_channels) + channel];
93 breg = bcoef * breg + pnt[(streamofs * mds -> n_channels) + channel];
94 creg = ccoef * creg + pnt[(streamofs * mds -> n_channels) + channel];
95
96 /* Combine filters in parallel */
97 temp = again * areg
98 + bgain * breg
99 + cgain * creg;
100
101 /* Check clipping */
102 if (temp > 32767)
103 {
104 temp = 32767;
105 }
106 else if (temp < -32768)
107 {
108 temp = -32768;
109 }
110
111 /* Store new value */
112 pnt[(streamofs * mds -> n_channels) + channel] = temp;
113 }
114 }
115 }
116