source: roaraudio/roarclients/roarvumeter.c @ 3025:e0985044be84

Last change on this file since 3025:e0985044be84 was 3025:e0985044be84, checked in by phi, 15 years ago

wrote a bad working beat detection

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