source: roaraudio/roarclients/roarfilt.c @ 648:bf9e4790f8d3

Last change on this file since 648:bf9e4790f8d3 was 648:bf9e4790f8d3, checked in by phi, 16 years ago

use correct data type and everything is fine :)

File size: 4.4 KB
Line 
1//roarfilt.c:
2
3#include <roaraudio.h>
4#include <math.h>
5
6#define BUFSIZE 1024
7struct {
8 uint16_t a, b;
9 int16_t  old[ROAR_MAX_CHANNELS];
10} g_lowpass;
11
12void usage (void) {
13 printf("roarfilt [OPTIONS]...\n");
14
15 printf("\nOptions:\n\n");
16
17 printf("  --server SERVER    - Set server hostname\n"
18        "  --rate   RATE      - Set sample rate\n"
19        "  --bits   BITS      - Set bits per sample\n"
20        "  --chans  CHANNELS  - Set number of channels\n"
21        "  --help             - Show this help\n"
22        "\n"
23        "  --half             - half the volume\n"
24        "  --double           - double the volume\n"
25        "  --amp VAL          - Set amplification\n"
26        "  --mul VAL          - Set mul\n"
27        "  --div VAL          - Set div\n"
28        "  --lowpass freq     - lowpass filter\n"
29       );
30
31}
32
33void vol2 (void * data, int mul, int div, int len) {
34 int16_t * samples = (int16_t *) data;
35 int i;
36
37 len /= 2;
38
39 for (i = 0; i < len; i++)
40  samples[i] = ((int) samples[i] * mul) / div;
41}
42
43void vol1 (void * data, int mul, int div, int len) {
44 int8_t * samples = (int8_t *) data;
45 int i;
46
47 for (i = 0; i < len; i++)
48  samples[i] = ((int) samples[i] * mul) / div;
49}
50
51void logs2 (void * data, float scale, int len) {
52 int16_t * samples = (int16_t *) data;
53 int i;
54 float div = logf(scale);
55 float scalemul = scale - 1;
56 int neg;
57
58 len /= 2;
59
60 //printf("logs2(data=%p, scale=%f, len=%i): scalemul=%f, div=%f\n", data, scale, len, scalemul, div);
61
62 for (i = 0; i < len; i++) {
63  if ( (neg = (samples[i] < 0)) )
64   samples[i] = abs(samples[i]);
65
66
67  samples[i] = (neg ? 32768.0 : 32767.0)*logf(1 + (scalemul*(float)samples[i]/(neg ? 32768.0 : 32767.0))) / div;
68
69  if ( neg )
70   samples[i] *= -1;
71 }
72}
73
74void lowpass2 (void * data, int len, int channels) {
75 int16_t * samples = (int16_t *) data;
76 register int32_t s;
77 int i, c;
78
79 if ( channels > ROAR_MAX_CHANNELS )
80  return;
81
82 len /= 2 * channels;
83
84//  *      output[N] = input[N] * A + output[N-1] * B
85
86 for (i = 0; i < len; i++) {
87  for (c = 0; c < channels; c++) {
88   s = samples[i*channels + c] * g_lowpass.a + g_lowpass.old[c] * g_lowpass.b;
89
90   s /= 65536;
91
92   samples[i*channels + c] = s;
93   g_lowpass.old[       c] = s;
94  }
95 }
96}
97
98int main (int argc, char * argv[]) {
99 int    rate     = 44100;
100 int    bits     = 16;
101 int    channels = 2;
102 int    codec    = ROAR_CODEC_DEFAULT;
103 char * server   = NULL;
104 char * k;
105 int    fh;
106 int    i;
107 int    mul = 1, div = 1;
108 float  logscale = 0;
109 float  lp       = 0;
110 char buf[BUFSIZE];
111
112 memset(&g_lowpass, 0, sizeof(g_lowpass));
113
114 for (i = 1; i < argc; i++) {
115  k = argv[i];
116
117  if ( strcmp(k, "--server") == 0 ) {
118   server = argv[++i];
119  } else if ( strcmp(k, "--rate") == 0 ) {
120   rate = atoi(argv[++i]);
121  } else if ( strcmp(k, "--bits") == 0 ) {
122   bits = atoi(argv[++i]);
123  } else if ( strcmp(k, "--channels") == 0 || strcmp(k, "--chans") == 0 ) {
124   channels = atoi(argv[++i]);
125  } else if ( strcmp(k, "--half") == 0 ) {
126   div *= 2;
127  } else if ( strcmp(k, "--double") == 0 ) {
128   mul *= 2;
129  } else if ( strcmp(k, "--amp") == 0 ) {
130   mul *= atoi(argv[++i]);
131  } else if ( strcmp(k, "--mul") == 0 ) {
132   mul  = atoi(argv[++i]);
133  } else if ( strcmp(k, "--div") == 0 ) {
134   div  = atoi(argv[++i]);
135  } else if ( strcmp(k, "--log") == 0 ) {
136   logscale = atof(argv[++i]);
137  } else if ( strcmp(k, "--lowpass") == 0 ) {
138   lp = exp(-2 * M_PI * atof(argv[++i]) / rate) * 65536;
139   g_lowpass.b = lp;
140   g_lowpass.a = 65536 - lp;
141//   printf("lowpass: A=%i, B=%i\n", g_lowpass.a, g_lowpass.b);
142  } else if ( strcmp(k, "--help") == 0 ) {
143   usage();
144   return 0;
145  } else {
146   fprintf(stderr, "Error: unknown argument: %s\n", k);
147   usage();
148   return 1;
149  }
150 }
151
152 if ( (fh = roar_simple_filter(rate, channels, bits, codec, server, "roarifilt")) == -1 ) {
153  fprintf(stderr, "Error: can not start playback\n");
154  return 1;
155 }
156
157 if ( mul == div && logscale == 0 && lp == 0 ) {
158  fprintf(stderr, "Error: filter is useless!\n");
159  return 0;
160 }
161
162 if ( bits == 16 ) {
163  while((i = read(fh, buf, BUFSIZE))) {
164   if ( mul != div )
165    vol2((void*)buf, mul, div, i);
166   if ( logscale )
167    logs2((void*)buf, logscale, i);
168   if ( g_lowpass.a )
169    lowpass2((void*)buf, i, channels);
170   if (write(fh, buf, i) != i)
171    break;
172  }
173 } else if ( bits == 8 ) {
174  while((i = read(fh, buf, BUFSIZE))) {
175   vol1((void*)buf, mul, div, i);
176   if (write(fh, buf, i) != i)
177    break;
178  }
179 } else {
180  fprintf(stderr, "Error: %i bits per sample is not supported!\n", bits);
181  return 1;
182 }
183
184 roar_simple_close(fh);
185
186 return 0;
187}
188
189//ll
Note: See TracBrowser for help on using the repository browser.