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