summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2009-04-27 00:53:36 +0200
committerLennart Poettering <lennart@poettering.net>2009-04-27 00:53:36 +0200
commiteda0fbdaaa8b04dc10909485f9a794bee99b2ffb (patch)
tree520092131d39f38b74115649cad21367be276d2d
parent8b6b56c20342aea92ff6b389d2174fc9ebf9c21e (diff)
Finish the code
-rw-r--r--dbmeasure.c114
1 files changed, 100 insertions, 14 deletions
diff --git a/dbmeasure.c b/dbmeasure.c
index f9140c8..2c40e9d 100644
--- a/dbmeasure.c
+++ b/dbmeasure.c
@@ -108,27 +108,50 @@ static double compute_level(const float *buffer, float *sum, unsigned n_samples,
for (i = 0; i < n_samples; i++) {
sum[i] += buffer[i];
- if (sum[i] > max)
- max = sum[i];
+ if (fabs(sum[i]) > max)
+ max = fabs(sum[i]);
}
return max / (double) iteration;
}
+static int prompt(const char *t) {
+ char r[64];
+ fputs(t, stderr);
+
+ if (!fgets(r, sizeof(r), stdin))
+ return 0;
+
+ return 1;
+}
+
+static double linear_to_dB(double f) {
+ return 20.0 * log10(f);
+}
+
int main(int argc, char *argv[]) {
int ret = 1;
- float *signal = NULL, *silence = NULL, *buffer = NULL, *sum = NULL;
+ float *signal = NULL, *silence = NULL, *buffer = NULL, *sum = NULL, *current = NULL;
snd_pcm_t *input = NULL, *output = NULL;
unsigned rate = 44100;
unsigned rindex = 0, windex = 0;
- double frequency = 440.0, amplitude = 0.5;
+ double frequency = 440.0, amplitude = 0.5, noise_level_dB = -80.0, initial_level_max = 0.97, initial_level_min = 0.8, reference_level;
unsigned iteration = 0;
int icount, ocount;
struct pollfd *pollfd;
int e;
+ unsigned needed_iterations = 0;
+ int skip = 1;
+ FILE *log;
+ int level_count = 0;
+
+ if (argc < 3) {
+ fprintf(stderr, "Need to specify device and output log file.\n");
+ goto finish;
+ }
- if (argc < 2) {
- fprintf(stderr, "Need to specify device.\n");
+ if (!(log = fopen(argv[2], "w"))) {
+ fprintf(stderr, "Failed to open log file %s: %s\n", argv[2], strerror(errno));
goto finish;
}
@@ -180,6 +203,12 @@ int main(int argc, char *argv[]) {
goto finish;
}
+ current = silence;
+
+ prompt("Please set your control to the highest volume possible and press return.\n");
+
+ fprintf(stderr, "Measuring noise level.\n");
+
for (;;) {
snd_pcm_sframes_t n;
unsigned short irevents, orevents;
@@ -202,9 +231,9 @@ int main(int argc, char *argv[]) {
}
if (orevents) {
- if ((n = snd_pcm_writei(output, signal + windex, rate - windex)) < 0) {
+ if ((n = snd_pcm_writei(output, current + windex, rate - windex)) < 0) {
- if (snd_pcm_recover(output, n, 0) < 0) {
+ if (snd_pcm_recover(output, n, 1) < 0) {
fprintf(stderr, "Cannot write samples: %s\n", snd_strerror(n));
goto finish;
} else
@@ -220,7 +249,7 @@ int main(int argc, char *argv[]) {
if (irevents) {
if ((n = snd_pcm_readi(input, buffer + rindex, rate - rindex)) < 0) {
- if (snd_pcm_recover(input, n, 0) < 0) {
+ if (snd_pcm_recover(input, n, 1) < 0) {
fprintf(stderr, "Cannot read samples: %s\n", snd_strerror(n));
goto finish;
}
@@ -235,13 +264,67 @@ int main(int argc, char *argv[]) {
rindex += n;
if (rindex == rate) {
- double level;
-
rindex = 0;
- iteration++;
- level = compute_level(buffer, sum, rate, iteration);
- fprintf(stderr, "Iteration %u, level is %g.\n", iteration, level);
+ if (skip)
+ skip = 0;
+ else {
+ double level;
+
+ iteration++;
+ level = compute_level(buffer, sum, rate, iteration);
+ fprintf(stderr, "Iteration %u, level is %g (%g dB).\n", iteration, level, linear_to_dB(level));
+
+ if (needed_iterations == 0) {
+ if (linear_to_dB(level) < noise_level_dB) {
+ fprintf(stderr, "%u iterations necessary to push noise level below %g dB\n", iteration, noise_level_dB);
+
+ needed_iterations = iteration;
+ current = signal;
+ windex = 0;
+ skip = 1;
+ iteration = 0;
+ memset(sum, 0, rate * sizeof(float));
+
+ fprintf(stderr, "Generating signal.\n");
+ }
+ } else {
+
+ if (iteration >= needed_iterations) {
+
+ if (level_count <= 0) {
+
+ if (level < initial_level_min ||
+ level > initial_level_max) {
+ fprintf(stderr,
+ "Volume level measured (%g) was too high or too low.\n"
+ "Please adjust mixer so that initial level is between %g and %g.\n"
+ "Test run canceled.\n", level, initial_level_min, initial_level_max);
+ goto finish;
+ }
+
+ reference_level = level;
+ }
+
+ fprintf(log, "%i\t%g\t%g\t%g\t%g\n",
+ level_count,
+ level, linear_to_dB(level),
+ level/reference_level, linear_to_dB(level/reference_level));
+
+ fflush(log);
+
+ level_count++;
+
+ windex = 0;
+ skip = 1;
+ iteration = 0;
+ memset(sum, 0, rate * sizeof(float));
+
+ if (!(prompt("Please reduce volume by one step and press return. Press C-D when finished.\n")))
+ break;
+ }
+ }
+ }
}
}
}
@@ -256,6 +339,9 @@ finish:
if (output)
snd_pcm_close(output);
+ if (log)
+ fclose(log);
+
free(signal);
free(silence);
free(buffer);