From 378dfb98cbb4fbafc2be55312a1e4e25631ba636 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sun, 26 Apr 2009 03:39:39 +0200 Subject: initial commit --- .gitignore | 2 + dbmeasure.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 .gitignore create mode 100644 dbmeasure.c 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 +#include +#include + +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; +} -- cgit