summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2009-04-26 22:42:19 +0200
committerLennart Poettering <lennart@poettering.net>2009-04-26 22:42:19 +0200
commit8b6b56c20342aea92ff6b389d2174fc9ebf9c21e (patch)
tree14ec70cb78f311b5281d3184ffcb3dfa270ef9fd
parent6c821955aa29a2158b059d4ce80c726450cb06dc (diff)
Implement basic measurement logic
-rw-r--r--dbmeasure.c135
1 files changed, 111 insertions, 24 deletions
diff --git a/dbmeasure.c b/dbmeasure.c
index c6d2c1d..f9140c8 100644
--- a/dbmeasure.c
+++ b/dbmeasure.c
@@ -30,10 +30,12 @@ static snd_pcm_t *open_device(const char *name, snd_pcm_stream_t stream, unsigne
snd_pcm_t *d;
int r;
snd_pcm_hw_params_t *hw;
+ snd_pcm_uframes_t t;
+ snd_output_t *output = NULL;
snd_pcm_hw_params_alloca(&hw);
- if ((r = snd_pcm_open(&d, name, stream, 0)) < 0) {
+ if ((r = snd_pcm_open(&d, name, stream, SND_PCM_NONBLOCK)) < 0) {
fprintf(stderr, "Cannot open audio device %s: %s\n", name, snd_strerror(r));
goto finish;
}
@@ -44,36 +46,58 @@ static snd_pcm_t *open_device(const char *name, snd_pcm_stream_t stream, unsigne
}
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));
+ 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));
+ 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));
+ 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));
+ if ((r = snd_pcm_hw_params_set_channels(d, hw, 1)) < 0) {
+ fprintf(stderr, "Cannot set channel count: %s\n", snd_strerror(r));
+ goto finish;
+ }
+
+ t = rate;
+ if ((r = snd_pcm_hw_params_set_buffer_size_near(d, hw, &t)) < 0) {
+ fprintf(stderr, "Cannot set buffer size: %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));
+ fprintf(stderr, "Cannot set parameters: %s\n", snd_strerror(r));
+ goto finish;
+ }
+
+ if ((r = snd_output_stdio_attach(&output, stderr, 0)) < 0) {
+ fprintf(stderr, "Cannot attach to stderr: %s\n", snd_strerror(r));
+ goto finish;
+ }
+
+ if ((r = snd_pcm_dump(d, output)) < 0) {
+ fprintf(stderr, "Cannot dump status: %s\n", snd_strerror(r));
goto finish;
}
+ snd_output_close(output);
+
return d;
finish:
if (d)
snd_pcm_close(d);
+ if (output)
+ snd_output_close(output);
+
+
return NULL;
}
@@ -93,13 +117,15 @@ static double compute_level(const float *buffer, float *sum, unsigned n_samples,
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;
+ unsigned rindex = 0, windex = 0;
double frequency = 440.0, amplitude = 0.5;
- unsigned iteration;
+ unsigned iteration = 0;
+ int icount, ocount;
+ struct pollfd *pollfd;
+ int e;
if (argc < 2) {
fprintf(stderr, "Need to specify device.\n");
@@ -132,30 +158,91 @@ int main(int argc, char *argv[]) {
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));
+ if ((icount = snd_pcm_poll_descriptors_count(input)) <= 0 ||
+ (ocount = snd_pcm_poll_descriptors_count(output)) <= 0) {
+ fprintf(stderr, "Failed to determine number of pollfd descriptors.\n");
+ goto finish;
+ }
+
+ if (!(pollfd = calloc(icount + ocount, sizeof(struct pollfd)))) {
+ fprintf(stderr, "Failed to allocate pollfd array.\n");
+ goto finish;
+ }
+
+ if ((e = snd_pcm_prepare(input)) < 0 ||
+ (e = snd_pcm_prepare(output)) < 0) {
+ fprintf(stderr, "snd_pcm_prepare() failed: %s\n", snd_strerror(e));
+ goto finish;
+ }
+
+ if ((e = snd_pcm_start(input)) < 0) {
+ fprintf(stderr, "snd_pcm_start() failed: %s\n", snd_strerror(e));
+ goto finish;
+ }
+
+ for (;;) {
+ snd_pcm_sframes_t n;
+ unsigned short irevents, orevents;
+
+ if (snd_pcm_poll_descriptors(input, pollfd, icount) != icount ||
+ snd_pcm_poll_descriptors(output, pollfd+icount, ocount) != ocount) {
+ fprintf(stderr, "ALSA changed its mind about number of file descriptors.");
goto finish;
}
- skip_input += n;
- if (skip_input == rate)
- skip_input = 0;
+ if (poll(pollfd, icount+ocount, -1) < 0) {
+ fprintf(stderr, "poll() failed: %s\n", strerror(errno));
+ goto finish;
+ }
- if ((n = snd_pcm_readi(output, buffer + skip_output, rate - skip_output)) < 0) {
- fprintf(stderr, "Cannot read samples: %s\n", snd_strerror(n));
+ if ((e = snd_pcm_poll_descriptors_revents(input, pollfd, icount, &irevents)) < 0 ||
+ (e = snd_pcm_poll_descriptors_revents(output, pollfd+icount, ocount, &orevents)) < 0) {
+ fprintf(stderr, "Cannot get revents: %s\n", snd_strerror(e));
goto finish;
}
- skip_output += n;
- if (skip_output == rate) {
- double level;
+ if (orevents) {
+ if ((n = snd_pcm_writei(output, signal + windex, rate - windex)) < 0) {
+
+ if (snd_pcm_recover(output, n, 0) < 0) {
+ fprintf(stderr, "Cannot write samples: %s\n", snd_strerror(n));
+ goto finish;
+ } else
+ continue;
+ }
+
+ windex += n;
+ if (windex == rate)
+ windex = 0;
+ }
+
+
+ if (irevents) {
+ if ((n = snd_pcm_readi(input, buffer + rindex, rate - rindex)) < 0) {
+
+ if (snd_pcm_recover(input, n, 0) < 0) {
+ fprintf(stderr, "Cannot read samples: %s\n", snd_strerror(n));
+ goto finish;
+ }
+
+ if ((e = snd_pcm_start(input)) < 0) {
+ fprintf(stderr, "snd_pcm_start() failed: %s\n", snd_strerror(e));
+ goto finish;
+ }
+
+ continue;
+ }
- skip_output = 0;
+ rindex += n;
+ if (rindex == rate) {
+ double level;
- level = compute_level(buffer, sum, rate, iteration);
+ rindex = 0;
- fprintf(stderr, "Iteration %u, level is %g.\n", iteration, level);
+ iteration++;
+ level = compute_level(buffer, sum, rate, iteration);
+ fprintf(stderr, "Iteration %u, level is %g.\n", iteration, level);
+ }
}
}