source: roaraudio/roarclients/roarfilt.c @ 646:a8915fb83769

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

added lowpass, but seems not to work at the moment

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