1 #include <unistd.h>
2 #include <stdio.h>
3 #include <limits.h>
4 #include <getopt.h>
5 #include <stdbool.h>
6 #include "version.h"
7 
8 /*
9 filter parameter:
10 
11 filtertype	=	Butterworth
12 passtype	=	Bandpass
13 ripple	=
14 order	=	5
15 samplerate	=	8000
16 corner1	=	200
17 corner2	=	3400
18 adzero	=
19 logmin	=
20 */
21 
22 /* Digital filter designed by mkfilter/mkshape/gencode   A.J. Fisher
23    Command line: /www/usr/fisher/helpers/mkfilter -Bu -Bp -o 5 -a 2.5000000000e-02 4.2500000000e-01 -l */
24 
25 #define NZEROS 10
26 #define NPOLES 10
27 #define GAIN   2.823549227e+00
28 
29 float xv[NZEROS+1], yv[NPOLES+1];
30 
filter(float sample)31 float filter(float sample) {
32     xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4]; xv[4] = xv[5]; xv[5] = xv[6]; xv[6] = xv[7]; xv[7] = xv[8]; xv[8] = xv[9]; xv[9] = xv[10];
33     xv[10] = sample / GAIN;
34     yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4]; yv[4] = yv[5]; yv[5] = yv[6]; yv[6] = yv[7]; yv[7] = yv[8]; yv[8] = yv[9]; yv[9] = yv[10];
35     yv[10] =   (xv[10] - xv[0]) + 5 * (xv[2] - xv[8]) + 10 * (xv[6] - xv[4])
36                  + (  0.1254306222 * yv[0]) + (  0.1285714097 * yv[1])
37                  + ( -0.8106454980 * yv[2]) + ( -0.7664515771 * yv[3])
38                  + (  2.1846187758 * yv[4]) + (  1.8106678608 * yv[5])
39                  + ( -3.1465011600 * yv[6]) + ( -2.0391991609 * yv[7])
40                  + (  2.4873968618 * yv[8]) + (  1.0249072542 * yv[9]);
41     return yv[10];
42 }
43 
44 #define BUF_SIZE 32
45 short short_buf[BUF_SIZE];
46 float float_buf[BUF_SIZE];
47 int r = 0;
48 bool use_float = false;
49 
print_usage()50 void print_usage() {
51     fprintf(stderr,
52         "digitalvoice_filter version %s\n\n"
53         "Usage: digitalvoice_filter [options]\n\n"
54         "Available options:\n"
55         " -h, --help      show this message\n"
56         " -f, --float     use 32-bit float in and out (without this flag: 16-bit signed integer)\n"
57         " -v, --version   print version and exit\n",
58         VERSION
59     );
60 }
61 
62 
main(int argc,char ** argv)63 int main(int argc, char** argv) {
64     int c;
65     static struct option long_options[] = {
66         {"float", no_argument, NULL, 'f'},
67         {"version", no_argument, NULL, 'v'},
68         {"help", no_argument, NULL, 'h'},
69         { NULL, 0, NULL, 0 }
70     };
71     while ((c = getopt_long(argc, argv, "hfv", long_options, NULL)) != -1) {
72         switch (c) {
73             case 'f':
74                 fprintf(stderr, "digitalvoice_filter: switching to floating point operation\n");
75                 use_float = true;
76                 break;
77             case 'v':
78                 print_version();
79                 return 0;
80             case 'h':
81                 print_usage();
82                 return 0;
83         }
84     }
85 
86     int i;
87     if (use_float) {
88         while ((r = fread(float_buf, 4, BUF_SIZE, stdin)) > 0) {
89             for (i = 0; i < r; i++) {
90                 float_buf[i] = filter(float_buf[i]);
91             }
92             fwrite(float_buf, 4, r, stdout);
93             fflush(stdout);
94         }
95     } else {
96         while ((r = fread(short_buf, 2, BUF_SIZE, stdin)) > 0) {
97             for (i = 0; i < r; i++) {
98                 short_buf[i] = (short) (filter((float)short_buf[i] / SHRT_MAX) * SHRT_MAX);
99             }
100             fwrite(short_buf, 2, r, stdout);
101             fflush(stdout);
102         }
103     }
104 
105     return 0;
106 }
107