From: Simon Ser <simon.ser@intel.com>
To: igt-dev@lists.freedesktop.org
Cc: martin.peres@intel.com
Subject: [igt-dev] [PATCH i-g-t 4/5] lib/igt_audio: detect noise and pops
Date: Wed, 29 May 2019 16:32:49 +0300 [thread overview]
Message-ID: <20190529133250.27817-5-simon.ser@intel.com> (raw)
In-Reply-To: <20190529133250.27817-1-simon.ser@intel.com>
First, normalize the bin power by dividing it by the number of input samples.
We need to multiply by 2 since we get half as many bins as input samples.
Second, check that low frequencies are under a given threshold. If there is a
pop or some noise, the low frequencies will be affected.
Signed-off-by: Simon Ser <simon.ser@intel.com>
---
lib/igt_audio.c | 44 +++++++++++++++++++++++++++++++++++++++-----
1 file changed, 39 insertions(+), 5 deletions(-)
diff --git a/lib/igt_audio.c b/lib/igt_audio.c
index 08c0fb6af0db..423615427a4d 100644
--- a/lib/igt_audio.c
+++ b/lib/igt_audio.c
@@ -39,6 +39,8 @@
#define CHANNELS_MAX 8
#define SYNTHESIZE_AMPLITUDE 0.9
#define SYNTHESIZE_ACCURACY 0.2
+#define MIN_FREQ 200 /* Hz */
+#define NOISE_THRESHOLD 0.0005
/**
* SECTION:igt_audio
@@ -108,6 +110,7 @@ int audio_signal_add_frequency(struct audio_signal *signal, int frequency,
igt_assert(index < FREQS_MAX);
igt_assert(channel < signal->channels);
+ igt_assert(frequency >= MIN_FREQ);
/* Stay within the Nyquist–Shannon sampling theorem. */
if (frequency > signal->sampling_rate / 2) {
@@ -304,6 +307,12 @@ void audio_signal_fill(struct audio_signal *signal, double *buffer,
audio_sanity_check(buffer, signal->channels * samples);
}
+/* See https://en.wikipedia.org/wiki/Window_function#Hann_and_Hamming_windows */
+static double hann_window(double v, size_t i, size_t N)
+{
+ return v * 0.5 * (1 - cos(2.0 * M_PI * (double) i / (double) N));
+}
+
/**
* Checks that frequencies specified in signal, and only those, are included
* in the input data.
@@ -328,6 +337,11 @@ bool audio_signal_detect(struct audio_signal *signal, int sampling_rate,
data = malloc(samples_len * sizeof(double));
memcpy(data, samples, samples_len * sizeof(double));
+ /* Apply a Hann window to the input signal, to reduce frequency leaks
+ * due to the endpoints of the signal being discontinuous. */
+ for (i = 0; i < data_len; i++)
+ data[i] = hann_window(data[i], i, data_len);
+
/* Allowed error in Hz due to FFT step */
freq_accuracy = sampling_rate / data_len;
igt_debug("Allowed freq. error: %d Hz\n", freq_accuracy);
@@ -338,8 +352,7 @@ bool audio_signal_detect(struct audio_signal *signal, int sampling_rate,
igt_assert(0);
}
- /* Compute the power received by every bin of the FFT, and record the
- * maximum power received as a way to normalize all the others.
+ /* Compute the power received by every bin of the FFT.
*
* For i < data_len / 2, the real part of the i-th term is stored at
* data[i] and its imaginary part is stored at data[data_len - i].
@@ -349,15 +362,36 @@ bool audio_signal_detect(struct audio_signal *signal, int sampling_rate,
* The power is encoded as the magnitude of the complex number and the
* phase is encoded as its angle.
*/
- max = 0;
bin_power[0] = data[0];
for (i = 1; i < bin_power_len - 1; i++) {
bin_power[i] = hypot(data[i], data[data_len - i]);
- if (bin_power[i] > max)
- max = bin_power[i];
}
bin_power[bin_power_len - 1] = data[data_len / 2];
+ /* Normalize the power */
+ for (i = 0; i < bin_power_len; i++)
+ bin_power[i] = 2 * bin_power[i] / data_len;
+
+ /* Detect noise with a threshold on the power of low frequencies */
+ for (i = 0; i < bin_power_len; i++) {
+ freq = sampling_rate * i / data_len;
+ if (freq > MIN_FREQ - 100)
+ break;
+ if (bin_power[i] > NOISE_THRESHOLD) {
+ igt_debug("Noise level too high: freq=%d power=%f\n",
+ freq, bin_power[i]);
+ return false;
+ }
+ }
+
+ /* Record the maximum power received as a way to normalize all the
+ * others. */
+ max = NAN;
+ for (i = 0; i < bin_power_len; i++) {
+ if (isnan(max) || bin_power[i] > max)
+ max = bin_power[i];
+ }
+
for (i = 0; i < signal->freqs_count; i++)
detected[i] = false;
--
2.21.0
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
next prev parent reply other threads:[~2019-05-29 13:32 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-29 13:32 [igt-dev] [PATCH i-g-t 0/5] Add igt_audio self-tests and check for noise/pops Simon Ser
2019-05-29 13:32 ` [igt-dev] [PATCH i-g-t 1/5] lib/igt_audio: add basic audio_signal_detect tests Simon Ser
2019-06-03 13:43 ` Martin Peres
2019-06-04 8:00 ` Ser, Simon
2019-05-29 13:32 ` [igt-dev] [PATCH i-g-t 2/5] lib/tests/igt_audio: add test with missing frequency Simon Ser
2019-06-03 13:46 ` Martin Peres
2019-05-29 13:32 ` [igt-dev] [PATCH i-g-t 3/5] lib/tests/igt_audio: add test with an extra frequency Simon Ser
2019-06-03 13:49 ` Martin Peres
2019-05-29 13:32 ` Simon Ser [this message]
2019-06-03 14:11 ` [igt-dev] [PATCH i-g-t 4/5] lib/igt_audio: detect noise and pops Martin Peres
2019-05-29 13:32 ` [igt-dev] [PATCH i-g-t 5/5] lib/tests/igt_audio: add a pop test Simon Ser
2019-06-03 14:14 ` Martin Peres
2019-05-29 14:44 ` [igt-dev] ✓ Fi.CI.BAT: success for Add igt_audio self-tests and check for noise/pops Patchwork
2019-05-29 22:22 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190529133250.27817-5-simon.ser@intel.com \
--to=simon.ser@intel.com \
--cc=igt-dev@lists.freedesktop.org \
--cc=martin.peres@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.