• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2019 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  * Author: Simon Ser <simon.ser@intel.com>
24  */
25 
26 #include "config.h"
27 
28 #include <stdlib.h>
29 
30 #include "igt_core.h"
31 #include "igt_audio.h"
32 
33 #define SAMPLING_RATE 44100
34 #define CHANNELS 1
35 #define BUFFER_LEN 2048
36 /** PHASESHIFT_LEN: how many samples will be truncated from the signal */
37 #define PHASESHIFT_LEN 8
38 
39 static const int test_freqs[] = { 300, 700, 5000 };
40 
41 static const size_t test_freqs_len = sizeof(test_freqs) / sizeof(test_freqs[0]);
42 
43 #define TEST_EXTRA_FREQ 500
44 
test_signal_detect_untampered(struct audio_signal * signal)45 static void test_signal_detect_untampered(struct audio_signal *signal)
46 {
47 	double buf[BUFFER_LEN];
48 	bool ok;
49 
50 	audio_signal_fill(signal, buf, BUFFER_LEN / CHANNELS);
51 	ok = audio_signal_detect(signal, SAMPLING_RATE, 0, buf, BUFFER_LEN);
52 	igt_assert(ok);
53 }
54 
test_signal_detect_silence(struct audio_signal * signal)55 static void test_signal_detect_silence(struct audio_signal *signal)
56 {
57 	double buf[BUFFER_LEN] = {0};
58 	bool ok;
59 
60 	ok = audio_signal_detect(signal, SAMPLING_RATE, 0, buf, BUFFER_LEN);
61 
62 	igt_assert(!ok);
63 }
64 
test_signal_detect_noise(struct audio_signal * signal)65 static void test_signal_detect_noise(struct audio_signal *signal)
66 {
67 	double buf[BUFFER_LEN];
68 	bool ok;
69 	size_t i;
70 	long r;
71 
72 	/* Generate random samples between -1 and 1 */
73 	srand(42);
74 	for (i = 0; i < BUFFER_LEN; i++) {
75 		r = random();
76 		buf[i] = (double) r / RAND_MAX * 2 - 1;
77 	}
78 
79 	ok = audio_signal_detect(signal, SAMPLING_RATE, 0, buf, BUFFER_LEN);
80 
81 	igt_assert(!ok);
82 }
83 
test_signal_detect_with_missing_freq(struct audio_signal * signal)84 static void test_signal_detect_with_missing_freq(struct audio_signal *signal)
85 {
86 	double buf[BUFFER_LEN];
87 	struct audio_signal *missing;
88 	bool ok;
89 	size_t i;
90 
91 	/* Generate a signal with all the expected frequencies but the first
92 	 * one */
93 	missing = audio_signal_init(CHANNELS, SAMPLING_RATE);
94 	for (i = 1; i < test_freqs_len; i++) {
95 		audio_signal_add_frequency(missing, test_freqs[i], 0);
96 	}
97 	audio_signal_synthesize(missing);
98 
99 	audio_signal_fill(missing, buf, BUFFER_LEN / CHANNELS);
100 	ok = audio_signal_detect(signal, SAMPLING_RATE, 0, buf, BUFFER_LEN);
101 	igt_assert(!ok);
102 }
103 
test_signal_detect_with_unexpected_freq(struct audio_signal * signal)104 static void test_signal_detect_with_unexpected_freq(struct audio_signal *signal)
105 {
106 	double buf[BUFFER_LEN];
107 	struct audio_signal *extra;
108 	bool ok;
109 	size_t i;
110 
111 	/* Add an extra, unexpected frequency */
112 	extra = audio_signal_init(CHANNELS, SAMPLING_RATE);
113 	for (i = 0; i < test_freqs_len; i++) {
114 		audio_signal_add_frequency(extra, test_freqs[i], 0);
115 	}
116 	audio_signal_add_frequency(extra, TEST_EXTRA_FREQ, 0);
117 	audio_signal_synthesize(extra);
118 
119 	audio_signal_fill(extra, buf, BUFFER_LEN / CHANNELS);
120 	ok = audio_signal_detect(signal, SAMPLING_RATE, 0, buf, BUFFER_LEN);
121 	igt_assert(!ok);
122 }
123 
test_signal_detect_held_sample(struct audio_signal * signal)124 static void test_signal_detect_held_sample(struct audio_signal *signal)
125 {
126 	double *buf;
127 	bool ok;
128 	size_t i;
129 	double value;
130 
131 	buf = malloc(BUFFER_LEN * sizeof(double));
132 	audio_signal_fill(signal, buf, BUFFER_LEN / CHANNELS);
133 
134 	/* Repeat a sample in the middle of the signal */
135 	value = buf[BUFFER_LEN / 3];
136 	for (i = 0; i < 5; i++)
137 		buf[BUFFER_LEN / 3 + i] = value;
138 
139 	ok = audio_signal_detect(signal, SAMPLING_RATE, 0, buf, BUFFER_LEN);
140 
141 	free(buf);
142 
143 	igt_assert_f(!ok, "Expected audio signal not to be detected\n");
144 }
145 
test_signal_detect_phaseshift(struct audio_signal * signal)146 static void test_signal_detect_phaseshift(struct audio_signal *signal)
147 {
148 	double *buf;
149 	bool ok;
150 
151 	buf = malloc((BUFFER_LEN + PHASESHIFT_LEN) * sizeof(double));
152 	audio_signal_fill(signal, buf, (BUFFER_LEN + PHASESHIFT_LEN) / CHANNELS);
153 
154 	/* Perform a phaseshift (this isn't related to sirens).
155 	 *
156 	 * The idea is to remove a part of the signal in the middle of the
157 	 * buffer:
158 	 *
159 	 *   BUFFER_LEN/3   PHASESHIFT_LEN            2*BUFFER_LEN/3
160 	 * [--------------|################|---------------------------------]
161 	 *
162 	 *                           |
163 	 *                           V
164 	 *
165 	 * [--------------|---------------------------------]
166 	 */
167 	memmove(&buf[BUFFER_LEN / 3], &buf[BUFFER_LEN / 3 + PHASESHIFT_LEN],
168 		(2 * BUFFER_LEN / 3) * sizeof(double));
169 
170 	ok = audio_signal_detect(signal, SAMPLING_RATE, 0, buf, BUFFER_LEN);
171 
172 	free(buf);
173 
174 	igt_assert(!ok);
175 }
176 
177 igt_main
178 {
179 	struct audio_signal *signal = NULL;
180 	int ret;
181 	size_t i;
182 
183 	igt_subtest_group {
184 		igt_fixture {
185 			signal = audio_signal_init(CHANNELS, SAMPLING_RATE);
186 
187 			for (i = 0; i < test_freqs_len; i++) {
188 				ret = audio_signal_add_frequency(signal,
189 								 test_freqs[i],
190 								 0);
191 				igt_assert(ret == 0);
192 			}
193 
194 			audio_signal_synthesize(signal);
195 		}
196 
197 		igt_subtest("signal-detect-untampered")
198 			test_signal_detect_untampered(signal);
199 
200 		igt_subtest("signal-detect-silence")
201 			test_signal_detect_silence(signal);
202 
203 		igt_subtest("signal-detect-noise")
204 			test_signal_detect_noise(signal);
205 
206 		igt_subtest("signal-detect-with-missing-freq")
207 			test_signal_detect_with_missing_freq(signal);
208 
209 		igt_subtest("signal-detect-with-unexpected-freq")
210 			test_signal_detect_with_unexpected_freq(signal);
211 
212 		igt_subtest("signal-detect-held-sample")
213 			test_signal_detect_held_sample(signal);
214 
215 		igt_subtest("signal-detect-phaseshift")
216 			test_signal_detect_phaseshift(signal);
217 
218 		igt_fixture {
219 			audio_signal_fini(signal);
220 		}
221 	}
222 }
223