source: roaraudio/roarclients/roarvumeter.c @ 3121:0ed0acfadd4f

Last change on this file since 3121:0ed0acfadd4f was 3091:9da1d1d068c8, checked in by phi, 14 years ago

updated help, added --pc and --chans

File size: 7.2 KB
Line 
1//roarvumeter.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008, 2009
5 *
6 *  This file is part of roarclients a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  RoarAudio is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
25#include <roaraudio.h>
26#include <libroardsp/libroardsp.h>
27
28#ifdef ROAR_HAVE_LIBM
29
30#include <math.h>
31
32#define BUFSIZE 1024
33
34#define LOWPASS_ORDER  6
35
36#define MODE_NONE  0x00
37#define MODE_PC    0x01
38#define MODE_DB    0x02
39#define MODE_BEAT  0x04
40
41void usage (void) {
42 printf("roarvumeter [OPTIONS]...\n");
43
44 printf("\nOptions:\n\n");
45
46 printf("  --server  SERVER   - Set server hostname\n"
47        "  --rate    RATE     - Set sample rate\n"
48        "  --bits    BITS     - Set bits per sample\n"
49        "  --chans   CHANNELS - Set number of channels\n"
50        "  --samples SAMPLES  - Set number of input samples per block\n"
51        "  --pc               - Use percent scale\n"
52        "  --db               - Use dB scale\n"
53        "  --beat             - Enable beat detection\n"
54        "  --lowpass FREQ     - Use lowpass to filter input (-%idB/dec)\n"
55        "  --help             - Show this help\n",
56        LOWPASS_ORDER * 20
57       );
58
59}
60
61int vumeter16bit2ch (struct roar_vio_calls * vio, int samples, int16_t * buf, int mode, struct roardsp_filterchain * fc) {
62 struct roar_stream    beat_stream[1];
63 struct roardsp_filter beat_lp[1];
64 float                 beat_lpfreq = 1;
65 int i;
66 int samples_half = samples/2;
67 int64_t suml, sumr;
68 double  rmsl, rmsr;
69 int run_filters    = roardsp_fchain_num(fc);
70 int beat_detection = mode & MODE_BEAT;
71 char * beat[2]     = {"     ", "Beat!"};
72 char * dbeat       = beat[0];
73 int have_beat;
74 int16_t beat_val, beat_old;
75
76 if ( beat_detection ) {
77  mode -= MODE_BEAT;
78
79  roar_stream_new(beat_stream, 10, 1, 16, ROAR_CODEC_PCM);
80  roardsp_filter_init(beat_lp, beat_stream, ROARDSP_FILTER_LOWP);
81  roardsp_filter_ctl(beat_lp, ROARDSP_FCTL_FREQ, &beat_lpfreq);
82 }
83
84 printf("\e[s");
85 fflush(stdout);
86
87 while (roar_vio_read(vio, buf, samples * 2) > 0) {
88  suml = sumr = 0;
89
90  if ( run_filters ) {
91   roardsp_fchain_calc(fc, buf, samples * 2);
92  }
93
94  for (i = 0; i < samples; i += 2) {
95   suml += (int64_t) buf[i  ] * (int64_t) buf[i  ];
96   sumr += (int64_t) buf[i+1] * (int64_t) buf[i+1];
97  }
98
99  rmsl = sqrt((double)suml/(double)samples_half);
100  rmsr = sqrt((double)sumr/(double)samples_half);
101
102  if ( beat_detection ) {
103   beat_old = beat_val = (rmsl + rmsr) / 2;
104   roardsp_filter_calc(beat_lp, &beat_val, 2);
105   if ( (float)beat_old > (float)beat_val*1.1f ) {
106    dbeat = beat[1];
107    have_beat = 1;
108   } else {
109    dbeat = beat[0];
110    have_beat = 0;
111   }
112  }
113
114  switch (mode) {
115   case MODE_NONE: // beat only
116     if ( have_beat )
117      printf("%s\n", dbeat);
118    break;
119   case MODE_PC:
120     printf("L: %3i%% R: %3i%% %s          \e[u", (int)(rmsl/327.68), (int)(rmsr/327.68), dbeat);
121    break;
122   case MODE_DB:
123     printf("L: %6.2fdB R: %6.2fdB %s          \e[u", 20*log10(rmsl/32768.), 20*log10(rmsr/32768.), dbeat);
124    break;
125  }
126
127  fflush(stdout);
128 }
129
130 roardsp_filter_uninit(beat_lp);
131
132 return 0;
133}
134
135int vumeter (struct roar_vio_calls * vio, int samples, int bits, int channels, int mode, struct roardsp_filterchain * fc) {
136 void * buf = malloc((samples*bits*channels)/8);
137
138 if ( !buf )
139  return -1;
140
141 if ( bits == 16 ) {
142  if ( channels == 2 ) {
143   vumeter16bit2ch(vio, samples, (int16_t *) buf, mode, fc);
144   free(buf);
145   return 0;
146  } else {
147   free(buf);
148   return -1;
149  }
150 } else {
151  free(buf);
152  return -1;
153 }
154}
155
156int main (int argc, char * argv[]) {
157 struct roar_connection       con;
158 struct roar_stream           s;
159 struct roardsp_filterchain   fchain;
160 struct roardsp_filter      * filter;
161 float  lowpass_freq = 0;
162 int    rate     = ROAR_RATE_DEFAULT;
163 int    bits     = 16;
164 int    channels = 2;
165 int    codec    = ROAR_CODEC_DEFAULT;
166 int    samples  = -1;
167 char * server   = NULL;
168 char * k;
169 struct roar_vio_calls stream, re;
170 int    i;
171 int    mode = 0;
172
173 for (i = 1; i < argc; i++) {
174  k = argv[i];
175
176  if ( strcmp(k, "--server") == 0 ) {
177   server = argv[++i];
178  } else if ( strcmp(k, "--rate") == 0 ) {
179   rate = atoi(argv[++i]);
180  } else if ( strcmp(k, "--bits") == 0 ) {
181   bits = atoi(argv[++i]);
182  } else if ( strcmp(k, "--channels") == 0 || strcmp(k, "--chans") == 0) {
183   channels = atoi(argv[++i]);
184  } else if ( strcmp(k, "--samples") == 0 ) {
185   samples = atoi(argv[++i]);
186  } else if ( strcmp(k, "--db") == 0 ) {
187   mode |= MODE_PC;
188   mode -= MODE_PC;
189   mode |= MODE_DB;
190  } else if ( strcmp(k, "--pc") == 0 ) {
191   mode |= MODE_DB;
192   mode -= MODE_DB;
193   mode |= MODE_PC;
194  } else if ( strcmp(k, "--beat") == 0 ) {
195   mode |= MODE_BEAT;
196  } else if ( strcmp(k, "--lowpass") == 0 ) {
197   lowpass_freq = atof(argv[++i]);
198  } else if ( strcmp(k, "--help") == 0 ) {
199   usage();
200   return 0;
201  } else {
202   fprintf(stderr, "Error: unknown argument: %s\n", k);
203   usage();
204   return 1;
205  }
206 }
207
208 if ( !mode )
209  mode = MODE_PC;
210
211 if ( samples == -1 )
212  samples = rate/10;
213
214 if ( roar_simple_connect(&con, server, "roarvumeter") == -1 ) {
215  fprintf(stderr, "Error: can not connect to server!\n");
216  return 1;
217 }
218
219 if ( roar_vio_simple_new_stream_obj(&stream, &con, &s, rate, channels, bits, codec, ROAR_DIR_MONITOR) == -1) {
220  fprintf(stderr, "Error: can not start monetoring\n");
221  return 1;
222 }
223
224 if ( roar_vio_open_re(&re, &stream) == -1 ) {
225  roar_vio_close(&stream);
226  fprintf(stderr, "Error: can not open RE VIO layer\n");
227  return 1;
228 }
229
230 if ( roardsp_fchain_init(&fchain) == -1 ) {
231  roar_vio_close(&re);
232  fprintf(stderr, "Error: can not init filterchain\n");
233  return 1;
234 }
235
236 if ( lowpass_freq > 1 ) {
237  for (i = 0; i < LOWPASS_ORDER; i++) {
238   if ( roardsp_filter_new(&filter, &s, ROARDSP_FILTER_LOWP) == -1 ) {
239    fprintf(stderr, "Error: can not open lowpass\n");
240    roar_vio_close(&re);
241    roardsp_fchain_uninit(&fchain);
242    return 1;
243   }
244
245   if ( roardsp_filter_ctl(filter, ROARDSP_FCTL_FREQ, &lowpass_freq) == -1 ) {
246    fprintf(stderr, "Error: can not set filter frequency\n");
247    roar_vio_close(&re);
248    roardsp_fchain_uninit(&fchain);
249    return 1;
250   }
251
252   if ( roardsp_fchain_add(&fchain, filter) == -1 ) {
253    fprintf(stderr, "Error: can not set filter frequency\n");
254    roar_vio_close(&re);
255    roardsp_fchain_uninit(&fchain);
256    return 1;
257   }
258  }
259 }
260
261 vumeter(&re, samples*channels, bits, channels, mode, &fchain);
262
263 printf("\n"); // if the reach this then roard has quited and we should print a newline
264
265 roar_vio_close(&re);
266
267 roar_disconnect(&con);
268
269 roardsp_fchain_uninit(&fchain);
270
271 return 0;
272}
273
274#else
275int main (void) {
276 fprintf(stderr, "Error: No Math library support compiled in.\n");
277 return 1;
278}
279#endif
280
281//ll
Note: See TracBrowser for help on using the repository browser.