summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2009-04-26 03:39:39 +0200
committerLennart Poettering <lennart@poettering.net>2009-04-26 03:39:39 +0200
commit378dfb98cbb4fbafc2be55312a1e4e25631ba636 (patch)
tree759c8486ca5e11fc4749f63f168e336fe844674a
initial commit
-rw-r--r--.gitignore2
-rw-r--r--dbmeasure.c178
2 files changed, 180 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d0fba61
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+dbmeasure
+*.o
diff --git a/dbmeasure.c b/dbmeasure.c
new file mode 100644
index 0000000..c6d2c1d
--- /dev/null
+++ b/dbmeasure.c
@@ -0,0 +1,178 @@
+/*-*- Mode: C; c-file-style: "linux"; indent-tabs-mode: nil; c-basic-offset: 8 -*-*/
+
+#include <math.h>
+#include <stdlib.h>
+#include <asoundlib.h>
+
+static float *generate_signal(unsigned n_samples, double amplitude, double frequency) {
+ float *r;
+ unsigned i;
+
+ if (!(r = malloc(n_samples * sizeof(float))))
+ return NULL;
+
+ for (i = 0; i < n_samples; i++)
+ r[i] = amplitude * sin(((double) i*frequency*M_PI*2)/(double) n_samples);
+
+ return r;
+}
+
+static float *generate_silence(unsigned n_samples) {
+ float *r;
+
+ if (!(r = calloc(n_samples, sizeof(float))))
+ return NULL;
+
+ return r;
+}
+
+static snd_pcm_t *open_device(const char *name, snd_pcm_stream_t stream, unsigned rate) {
+ snd_pcm_t *d;
+ int r;
+ snd_pcm_hw_params_t *hw;
+
+ snd_pcm_hw_params_alloca(&hw);
+
+ if ((r = snd_pcm_open(&d, name, stream, 0)) < 0) {
+ fprintf(stderr, "Cannot open audio device %s: %s\n", name, snd_strerror(r));
+ goto finish;
+ }
+
+ if ((r = snd_pcm_hw_params_any(d, hw)) < 0) {
+ fprintf(stderr, "Cannot initialize hardware parameters: %s\n", snd_strerror(r));
+ goto finish;
+ }
+
+ if ((r = snd_pcm_hw_params_set_access(d, hw, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
+ fprintf(stderr, "Cannot set access type (%s)\n", snd_strerror(r));
+ goto finish;
+ }
+
+ if ((r = snd_pcm_hw_params_set_format(d, hw, SND_PCM_FORMAT_FLOAT_LE)) < 0) {
+ fprintf(stderr, "cannot set sample format (%s)\n", snd_strerror(r));
+ goto finish;
+ }
+
+ if ((r = snd_pcm_hw_params_set_rate(d, hw, rate, 0)) < 0) {
+ fprintf(stderr, "cannot set sample rate (%s)\n", snd_strerror(r));
+ goto finish;
+ }
+
+ if ((r = snd_pcm_hw_params_set_channels(d, hw, 2)) < 0) {
+ fprintf(stderr, "cannot set channel count (%s)\n", snd_strerror(r));
+ goto finish;
+ }
+
+ if ((r = snd_pcm_hw_params(d, hw)) < 0) {
+ fprintf(stderr, "cannot set parameters (%s)\n", snd_strerror(r));
+ goto finish;
+ }
+
+ return d;
+
+finish:
+ if (d)
+ snd_pcm_close(d);
+
+ return NULL;
+}
+
+static double compute_level(const float *buffer, float *sum, unsigned n_samples, unsigned iteration) {
+ unsigned i;
+ double max = 0.0;
+
+ for (i = 0; i < n_samples; i++) {
+ sum[i] += buffer[i];
+
+ if (sum[i] > max)
+ max = sum[i];
+ }
+
+ return max / (double) iteration;
+}
+
+int main(int argc, char *argv[]) {
+ int ret = 1;
+ snd_pcm_sframes_t n;
+ float *signal = NULL, *silence = NULL, *buffer = NULL, *sum = NULL;
+ snd_pcm_t *input = NULL, *output = NULL;
+ unsigned rate = 44100;
+ unsigned skip_input = 0, skip_output = 0;
+ double frequency = 440.0, amplitude = 0.5;
+ unsigned iteration;
+
+ if (argc < 2) {
+ fprintf(stderr, "Need to specify device.\n");
+ goto finish;
+ }
+
+ if (!(output = open_device(argv[1], SND_PCM_STREAM_PLAYBACK, rate)))
+ goto finish;
+
+ if (!(input = open_device(argv[1], SND_PCM_STREAM_CAPTURE, rate)))
+ goto finish;
+
+ if (!(silence = generate_silence(rate))) {
+ fprintf(stderr, "Failed to generate silence.\n");
+ goto finish;
+ }
+
+ if (!(signal = generate_signal(rate, amplitude, frequency))) {
+ fprintf(stderr, "Failed to generate signal.\n");
+ goto finish;
+ }
+
+ if (!(buffer = malloc(rate * sizeof(float)))) {
+ fprintf(stderr, "Failed to allocate buffer.\n");
+ goto finish;
+ }
+
+ if (!(sum = calloc(rate, sizeof(float)))) {
+ fprintf(stderr, "Failed to allocate sum buffer.\n");
+ goto finish;
+ }
+
+ for (iteration = 1;; iteration ++) {
+ if ((n = snd_pcm_writei(output, silence + skip_input, rate - skip_input)) < 0) {
+ fprintf(stderr, "Cannot write samples: %s\n", snd_strerror(n));
+ goto finish;
+ }
+
+ skip_input += n;
+ if (skip_input == rate)
+ skip_input = 0;
+
+ if ((n = snd_pcm_readi(output, buffer + skip_output, rate - skip_output)) < 0) {
+ fprintf(stderr, "Cannot read samples: %s\n", snd_strerror(n));
+ goto finish;
+ }
+
+ skip_output += n;
+ if (skip_output == rate) {
+ double level;
+
+ skip_output = 0;
+
+ level = compute_level(buffer, sum, rate, iteration);
+
+ fprintf(stderr, "Iteration %u, level is %g.\n", iteration, level);
+ }
+ }
+
+ ret = 0;
+
+finish:
+
+ if (input)
+ snd_pcm_close(input);
+
+ if (output)
+ snd_pcm_close(output);
+
+ free(signal);
+ free(silence);
+ free(buffer);
+ free(sum);
+
+ return ret;
+}