source: roaraudio/roarclients/roarvumeter.c @ 3517:1a3218a3fc5b

Last change on this file since 3517:1a3218a3fc5b was 3517:1a3218a3fc5b, checked in by phi, 14 years ago

updated license headers, FSF moved office

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