1 /*
2  * Copyright © 2017 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  * Authors:
24  *  Paul Kocialkowski <paul.kocialkowski@linux.intel.com>
25  */
26 
27 #include "config.h"
28 
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <gsl/gsl_fft_real.h>
32 #include <math.h>
33 #include <unistd.h>
34 
35 #include "igt_audio.h"
36 #include "igt_core.h"
37 
38 #define FREQS_MAX 64
39 #define CHANNELS_MAX 8
40 #define SYNTHESIZE_AMPLITUDE 0.9
41 #define SYNTHESIZE_ACCURACY 0.2
42 /** MIN_FREQ: minimum frequency that audio_signal can generate.
43  *
44  * To make sure the audio signal doesn't contain noise, #audio_signal_detect
45  * checks that low frequencies have a power lower than #NOISE_THRESHOLD.
46  * However if too-low frequencies are generated, noise detection can fail.
47  *
48  * This value should be at least 100Hz plus one bin. Best is not to change this
49  * value.
50  */
51 #define MIN_FREQ 200 /* Hz */
52 #define NOISE_THRESHOLD 0.0005
53 
54 /**
55  * SECTION:igt_audio
56  * @short_description: Library for audio-related tests
57  * @title: Audio
58  * @include: igt_audio.h
59  *
60  * This library contains helpers for audio-related tests. More specifically,
61  * it allows generating additions of sine signals as well as detecting them.
62  */
63 
64 struct audio_signal_freq {
65 	int freq;
66 	int channel;
67 
68 	double *period;
69 	size_t period_len;
70 	int offset;
71 };
72 
73 struct audio_signal {
74 	int channels;
75 	int sampling_rate;
76 
77 	struct audio_signal_freq freqs[FREQS_MAX];
78 	size_t freqs_count;
79 };
80 
81 /**
82  * audio_signal_init:
83  * @channels: The number of channels to use for the signal
84  * @sampling_rate: The sampling rate to use for the signal
85  *
86  * Allocate and initialize an audio signal structure with the given parameters.
87  *
88  * Returns: A newly-allocated audio signal structure
89  */
audio_signal_init(int channels,int sampling_rate)90 struct audio_signal *audio_signal_init(int channels, int sampling_rate)
91 {
92 	struct audio_signal *signal;
93 
94 	igt_assert(channels > 0);
95 	igt_assert(channels <= CHANNELS_MAX);
96 
97 	signal = calloc(1, sizeof(struct audio_signal));
98 	signal->sampling_rate = sampling_rate;
99 	signal->channels = channels;
100 	return signal;
101 }
102 
103 /**
104  * audio_signal_add_frequency:
105  * @signal: The target signal structure
106  * @frequency: The frequency to add to the signal
107  * @channel: The channel to add this frequency to, or -1 to add it to all
108  * channels
109  *
110  * Add a frequency to the signal.
111  *
112  * Returns: An integer equal to zero for success and negative for failure
113  */
audio_signal_add_frequency(struct audio_signal * signal,int frequency,int channel)114 int audio_signal_add_frequency(struct audio_signal *signal, int frequency,
115 				int channel)
116 {
117 	size_t index = signal->freqs_count;
118 	struct audio_signal_freq *freq;
119 
120 	igt_assert(index < FREQS_MAX);
121 	igt_assert(channel < signal->channels);
122 	igt_assert(frequency >= MIN_FREQ);
123 
124 	/* Stay within the Nyquist–Shannon sampling theorem. */
125 	if (frequency > signal->sampling_rate / 2) {
126 		igt_debug("Skipping frequency %d: too high for a %d Hz "
127 			  "sampling rate\n", frequency, signal->sampling_rate);
128 		return -1;
129 	}
130 
131 	/* Clip the frequency to an integer multiple of the sampling rate.
132 	 * This to be able to store a full period of it and use that for
133 	 * signal generation, instead of recurrent calls to sin().
134 	 */
135 	frequency = signal->sampling_rate / (signal->sampling_rate / frequency);
136 
137 	igt_debug("Adding test frequency %d to channel %d\n",
138 		  frequency, channel);
139 
140 	freq = &signal->freqs[index];
141 	memset(freq, 0, sizeof(*freq));
142 	freq->freq = frequency;
143 	freq->channel = channel;
144 
145 	signal->freqs_count++;
146 
147 	return 0;
148 }
149 
150 /**
151  * audio_signal_synthesize:
152  * @signal: The target signal structure
153  *
154  * Synthesize the data tables for the audio signal, that can later be used
155  * to fill audio buffers. The resources allocated by this function must be
156  * freed with a call to audio_signal_clean when the signal is no longer used.
157  */
audio_signal_synthesize(struct audio_signal * signal)158 void audio_signal_synthesize(struct audio_signal *signal)
159 {
160 	double *period;
161 	double value;
162 	size_t period_len;
163 	int freq;
164 	int i, j;
165 
166 	for (i = 0; i < signal->freqs_count; i++) {
167 		freq = signal->freqs[i].freq;
168 		period_len = signal->sampling_rate / freq;
169 
170 		period = calloc(period_len, sizeof(double));
171 
172 		for (j = 0; j < period_len; j++) {
173 			value = 2.0 * M_PI * freq / signal->sampling_rate * j;
174 			value = sin(value) * SYNTHESIZE_AMPLITUDE;
175 
176 			period[j] = value;
177 		}
178 
179 		signal->freqs[i].period = period;
180 		signal->freqs[i].period_len = period_len;
181 	}
182 }
183 
184 /**
185  * audio_signal_fini:
186  *
187  * Release the signal.
188  */
audio_signal_fini(struct audio_signal * signal)189 void audio_signal_fini(struct audio_signal *signal)
190 {
191 	audio_signal_reset(signal);
192 	free(signal);
193 }
194 
195 /**
196  * audio_signal_reset:
197  * @signal: The target signal structure
198  *
199  * Free the resources allocated by audio_signal_synthesize and remove
200  * the previously-added frequencies.
201  */
audio_signal_reset(struct audio_signal * signal)202 void audio_signal_reset(struct audio_signal *signal)
203 {
204 	size_t i;
205 
206 	for (i = 0; i < signal->freqs_count; i++) {
207 		free(signal->freqs[i].period);
208 	}
209 
210 	signal->freqs_count = 0;
211 }
212 
audio_signal_count_freqs(struct audio_signal * signal,int channel)213 static size_t audio_signal_count_freqs(struct audio_signal *signal, int channel)
214 {
215 	size_t n, i;
216 	struct audio_signal_freq *freq;
217 
218 	n = 0;
219 	for (i = 0; i < signal->freqs_count; i++) {
220 		freq = &signal->freqs[i];
221 		if (freq->channel < 0 || freq->channel == channel)
222 			n++;
223 	}
224 
225 	return n;
226 }
227 
228 /** audio_sanity_check:
229  *
230  * Make sure our generated signal is not messed up. In particular, make sure
231  * the maximum reaches a reasonable value but doesn't exceed our
232  * SYNTHESIZE_AMPLITUDE limit. Same for the minimum.
233  *
234  * We want the signal to be powerful enough to be able to hear something. We
235  * want the signal not to reach 1.0 so that we're sure it won't get capped by
236  * the audio card or the receiver.
237  */
audio_sanity_check(double * samples,size_t samples_len)238 static void audio_sanity_check(double *samples, size_t samples_len)
239 {
240 	size_t i;
241 	double min = 0, max = 0;
242 
243 	for (i = 0; i < samples_len; i++) {
244 		if (samples[i] < min)
245 			min = samples[i];
246 		if (samples[i] > max)
247 			max = samples[i];
248 	}
249 
250 	igt_assert(-SYNTHESIZE_AMPLITUDE <= min);
251 	igt_assert(min <= -SYNTHESIZE_AMPLITUDE + SYNTHESIZE_ACCURACY);
252 	igt_assert(SYNTHESIZE_AMPLITUDE - SYNTHESIZE_ACCURACY <= max);
253 	igt_assert(max <= SYNTHESIZE_AMPLITUDE);
254 }
255 
256 /**
257  * audio_signal_fill:
258  * @signal: The target signal structure
259  * @buffer: The target buffer to fill
260  * @samples: The number of samples to fill
261  *
262  * Fill the requested number of samples to the target buffer with the audio
263  * signal data (in interleaved double format), at the requested sampling rate
264  * and number of channels.
265  *
266  * Each sample is normalized (ie. between 0 and 1).
267  */
audio_signal_fill(struct audio_signal * signal,double * buffer,size_t samples)268 void audio_signal_fill(struct audio_signal *signal, double *buffer,
269 		       size_t samples)
270 {
271 	double *dst, *src;
272 	struct audio_signal_freq *freq;
273 	int total;
274 	int count;
275 	int i, j, k;
276 	size_t freqs_per_channel[CHANNELS_MAX];
277 
278 	memset(buffer, 0, sizeof(double) * signal->channels * samples);
279 
280 	for (i = 0; i < signal->channels; i++) {
281 		freqs_per_channel[i] = audio_signal_count_freqs(signal, i);
282 		igt_assert(freqs_per_channel[i] > 0);
283 	}
284 
285 	for (i = 0; i < signal->freqs_count; i++) {
286 		freq = &signal->freqs[i];
287 		total = 0;
288 
289 		igt_assert(freq->period);
290 
291 		while (total < samples) {
292 			src = freq->period + freq->offset;
293 			dst = buffer + total * signal->channels;
294 
295 			count = freq->period_len - freq->offset;
296 			if (count > samples - total)
297 				count = samples - total;
298 
299 			freq->offset += count;
300 			freq->offset %= freq->period_len;
301 
302 			for (j = 0; j < count; j++) {
303 				for (k = 0; k < signal->channels; k++) {
304 					if (freq->channel >= 0 &&
305 					    freq->channel != k)
306 						continue;
307 					dst[j * signal->channels + k] +=
308 						src[j] / freqs_per_channel[k];
309 				}
310 			}
311 
312 			total += count;
313 		}
314 	}
315 
316 	audio_sanity_check(buffer, signal->channels * samples);
317 }
318 
319 /* See https://en.wikipedia.org/wiki/Window_function#Hann_and_Hamming_windows */
hann_window(double v,size_t i,size_t N)320 static double hann_window(double v, size_t i, size_t N)
321 {
322 	return v * 0.5 * (1 - cos(2.0 * M_PI * (double) i / (double) N));
323 }
324 
325 /**
326  * Checks that frequencies specified in signal, and only those, are included
327  * in the input data.
328  *
329  * sampling_rate is given in Hz. samples_len is the number of elements in
330  * samples.
331  */
audio_signal_detect(struct audio_signal * signal,int sampling_rate,int channel,const double * samples,size_t samples_len)332 bool audio_signal_detect(struct audio_signal *signal, int sampling_rate,
333 			 int channel, const double *samples, size_t samples_len)
334 {
335 	double *data;
336 	size_t data_len = samples_len;
337 	size_t bin_power_len = data_len / 2 + 1;
338 	double bin_power[bin_power_len];
339 	bool detected[FREQS_MAX];
340 	int ret, freq_accuracy, freq, local_max_freq;
341 	double max, local_max, threshold;
342 	size_t i, j;
343 	bool above, success;
344 
345 	/* gsl will mutate the array in-place, so make a copy */
346 	data = malloc(samples_len * sizeof(double));
347 	memcpy(data, samples, samples_len * sizeof(double));
348 
349 	/* Apply a Hann window to the input signal, to reduce frequency leaks
350 	 * due to the endpoints of the signal being discontinuous.
351 	 *
352 	 * For more info:
353 	 * - https://download.ni.com/evaluation/pxi/Understanding%20FFTs%20and%20Windowing.pdf
354 	 * - https://en.wikipedia.org/wiki/Window_function
355 	 */
356 	for (i = 0; i < data_len; i++)
357 		data[i] = hann_window(data[i], i, data_len);
358 
359 	/* Allowed error in Hz due to FFT step */
360 	freq_accuracy = sampling_rate / data_len;
361 	igt_debug("Allowed freq. error: %d Hz\n", freq_accuracy);
362 
363 	ret = gsl_fft_real_radix2_transform(data, 1, data_len);
364 	if (ret != 0) {
365 		free(data);
366 		igt_assert(0);
367 	}
368 
369 	/* Compute the power received by every bin of the FFT.
370 	 *
371 	 * For i < data_len / 2, the real part of the i-th term is stored at
372 	 * data[i] and its imaginary part is stored at data[data_len - i].
373 	 * i = 0 and i = data_len / 2 are special cases, they are purely real
374 	 * so their imaginary part isn't stored.
375 	 *
376 	 * The power is encoded as the magnitude of the complex number and the
377 	 * phase is encoded as its angle.
378 	 */
379 	bin_power[0] = data[0];
380 	for (i = 1; i < bin_power_len - 1; i++) {
381 		bin_power[i] = hypot(data[i], data[data_len - i]);
382 	}
383 	bin_power[bin_power_len - 1] = data[data_len / 2];
384 
385 	/* Normalize the power */
386 	for (i = 0; i < bin_power_len; i++)
387 		bin_power[i] = 2 * bin_power[i] / data_len;
388 
389 	/* Detect noise with a threshold on the power of low frequencies */
390 	for (i = 0; i < bin_power_len; i++) {
391 		freq = sampling_rate * i / data_len;
392 		if (freq > MIN_FREQ - 100)
393 			break;
394 		if (bin_power[i] > NOISE_THRESHOLD) {
395 			igt_debug("Noise level too high: freq=%d power=%f\n",
396 				  freq, bin_power[i]);
397 			return false;
398 		}
399 	}
400 
401 	/* Record the maximum power received as a way to normalize all the
402 	 * others. */
403 	max = NAN;
404 	for (i = 0; i < bin_power_len; i++) {
405 		if (isnan(max) || bin_power[i] > max)
406 			max = bin_power[i];
407 	}
408 
409 	for (i = 0; i < signal->freqs_count; i++)
410 		detected[i] = false;
411 
412 	/* Do a linear search through the FFT bins' power to find the the local
413 	 * maximums that exceed half of the absolute maximum that we previously
414 	 * calculated.
415 	 *
416 	 * Since the frequencies might not be perfectly aligned with the bins of
417 	 * the FFT, we need to find the local maximum across some consecutive
418 	 * bins. Once the power returns under the power threshold, we compare
419 	 * the frequency of the bin that received the maximum power to the
420 	 * expected frequencies. If found, we mark this frequency as such,
421 	 * otherwise we warn that an unexpected frequency was found.
422 	 */
423 	threshold = max / 2;
424 	success = true;
425 	above = false;
426 	local_max = 0;
427 	local_max_freq = -1;
428 	for (i = 0; i < bin_power_len; i++) {
429 		freq = sampling_rate * i / data_len;
430 
431 		if (bin_power[i] > threshold)
432 			above = true;
433 
434 		if (!above) {
435 			continue;
436 		}
437 
438 		/* If we were above the threshold and we're not anymore, it's
439 		 * time to decide whether the peak frequency is correct or
440 		 * invalid. */
441 		if (bin_power[i] < threshold) {
442 			for (j = 0; j < signal->freqs_count; j++) {
443 				if (signal->freqs[j].channel >= 0 &&
444 				    signal->freqs[j].channel != channel)
445 					continue;
446 
447 				if (signal->freqs[j].freq >
448 				    local_max_freq - freq_accuracy &&
449 				    signal->freqs[j].freq <
450 				    local_max_freq + freq_accuracy) {
451 					detected[j] = true;
452 					igt_debug("Frequency %d detected\n",
453 						  local_max_freq);
454 					break;
455 				}
456 			}
457 
458 			/* We haven't generated this frequency, but we detected
459 			 * it. */
460 			if (j == signal->freqs_count) {
461 				igt_debug("Detected additional frequency: %d\n",
462 					  local_max_freq);
463 				success = false;
464 			}
465 
466 			above = false;
467 			local_max = 0;
468 			local_max_freq = -1;
469 		}
470 
471 		if (bin_power[i] > local_max) {
472 			local_max = bin_power[i];
473 			local_max_freq = freq;
474 		}
475 	}
476 
477 	/* Check that all frequencies we generated have been detected. */
478 	for (i = 0; i < signal->freqs_count; i++) {
479 		if (signal->freqs[i].channel >= 0 &&
480 		    signal->freqs[i].channel != channel)
481 			continue;
482 
483 		if (!detected[i]) {
484 			igt_debug("Missing frequency: %d\n",
485 				  signal->freqs[i].freq);
486 			success = false;
487 		}
488 	}
489 
490 	free(data);
491 
492 	return success;
493 }
494 
495 /**
496  * audio_extract_channel_s32_le: extracts a single channel from a multi-channel
497  * S32_LE input buffer.
498  *
499  * If dst_cap is zero, no copy is performed. This can be used to compute the
500  * minimum required capacity.
501  *
502  * Returns: the number of samples extracted.
503  */
audio_extract_channel_s32_le(double * dst,size_t dst_cap,int32_t * src,size_t src_len,int n_channels,int channel)504 size_t audio_extract_channel_s32_le(double *dst, size_t dst_cap,
505 				    int32_t *src, size_t src_len,
506 				    int n_channels, int channel)
507 {
508 	size_t dst_len, i;
509 
510 	igt_assert(channel < n_channels);
511 	igt_assert(src_len % n_channels == 0);
512 	dst_len = src_len / n_channels;
513 	if (dst_cap == 0)
514 		return dst_len;
515 
516 	igt_assert(dst_len <= dst_cap);
517 	for (i = 0; i < dst_len; i++)
518 		dst[i] = (double) src[i * n_channels + channel] / INT32_MAX;
519 
520 	return dst_len;
521 }
522 
audio_convert_to_s16_le(int16_t * dst,double * src,size_t len)523 static void audio_convert_to_s16_le(int16_t *dst, double *src, size_t len)
524 {
525 	size_t i;
526 
527 	for (i = 0; i < len; ++i)
528 		dst[i] = INT16_MAX * src[i];
529 }
530 
audio_convert_to_s24_le(int32_t * dst,double * src,size_t len)531 static void audio_convert_to_s24_le(int32_t *dst, double *src, size_t len)
532 {
533 	size_t i;
534 
535 	for (i = 0; i < len; ++i)
536 		dst[i] = 0x7FFFFF * src[i];
537 }
538 
audio_convert_to_s32_le(int32_t * dst,double * src,size_t len)539 static void audio_convert_to_s32_le(int32_t *dst, double *src, size_t len)
540 {
541 	size_t i;
542 
543 	for (i = 0; i < len; ++i)
544 		dst[i] = INT32_MAX * src[i];
545 }
546 
audio_convert_to(void * dst,double * src,size_t len,snd_pcm_format_t format)547 void audio_convert_to(void *dst, double *src, size_t len,
548 		      snd_pcm_format_t format)
549 {
550 	switch (format) {
551 	case SND_PCM_FORMAT_S16_LE:
552 		audio_convert_to_s16_le(dst, src, len);
553 		break;
554 	case SND_PCM_FORMAT_S24_LE:
555 		audio_convert_to_s24_le(dst, src, len);
556 		break;
557 	case SND_PCM_FORMAT_S32_LE:
558 		audio_convert_to_s32_le(dst, src, len);
559 		break;
560 	default:
561 		assert(false); /* unreachable */
562 	}
563 }
564 
565 #define RIFF_TAG "RIFF"
566 #define WAVE_TAG "WAVE"
567 #define FMT_TAG "fmt "
568 #define DATA_TAG "data"
569 
570 static void
append_to_buffer(char * dst,size_t * i,const void * src,size_t src_size)571 append_to_buffer(char *dst, size_t *i, const void *src, size_t src_size)
572 {
573 	memcpy(&dst[*i], src, src_size);
574 	*i += src_size;
575 }
576 
577 /**
578  * audio_create_wav_file_s32_le:
579  * @qualifier: the basename of the file (the test name will be prepended, and
580  * the file extension will be appended)
581  * @sample_rate: the sample rate in Hz
582  * @channels: the number of channels
583  * @path: if non-NULL, will be set to a pointer to the new file path (the
584  * caller is responsible for free-ing it)
585  *
586  * Creates a new WAV file.
587  *
588  * After calling this function, the caller is expected to write S32_LE PCM data
589  * to the returned file descriptor.
590  *
591  * See http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html for
592  * a WAV file format specification.
593  *
594  * Returns: a file descriptor to the newly created file, or -1 on error.
595  */
audio_create_wav_file_s32_le(const char * qualifier,uint32_t sample_rate,uint16_t channels,char ** path)596 int audio_create_wav_file_s32_le(const char *qualifier, uint32_t sample_rate,
597 				 uint16_t channels, char **path)
598 {
599 	char _path[PATH_MAX];
600 	const char *test_name, *subtest_name;
601 	int fd;
602 	char header[44];
603 	size_t i = 0;
604 	uint32_t file_size, chunk_size, byte_rate;
605 	uint16_t format, block_align, bits_per_sample;
606 
607 	test_name = igt_test_name();
608 	subtest_name = igt_subtest_name();
609 
610 	igt_assert(igt_frame_dump_path);
611 	snprintf(_path, sizeof(_path), "%s/audio-%s-%s-%s.wav",
612 		 igt_frame_dump_path, test_name, subtest_name, qualifier);
613 
614 	if (path)
615 		*path = strdup(_path);
616 
617 	igt_debug("Dumping %s audio to %s\n", qualifier, _path);
618 	fd = open(_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
619 	if (fd < 0) {
620 		igt_warn("open failed: %s\n", strerror(errno));
621 		return -1;
622 	}
623 
624 	/* File header */
625 	file_size = UINT32_MAX; /* unknown file size */
626 	append_to_buffer(header, &i, RIFF_TAG, strlen(RIFF_TAG));
627 	append_to_buffer(header, &i, &file_size, sizeof(file_size));
628 	append_to_buffer(header, &i, WAVE_TAG, strlen(WAVE_TAG));
629 
630 	/* Format chunk */
631 	chunk_size = 16;
632 	format = 1; /* PCM */
633 	bits_per_sample = 32; /* S32_LE */
634 	byte_rate = sample_rate * channels * bits_per_sample / 8;
635 	block_align = channels * bits_per_sample / 8;
636 	append_to_buffer(header, &i, FMT_TAG, strlen(FMT_TAG));
637 	append_to_buffer(header, &i, &chunk_size, sizeof(chunk_size));
638 	append_to_buffer(header, &i, &format, sizeof(format));
639 	append_to_buffer(header, &i, &channels, sizeof(channels));
640 	append_to_buffer(header, &i, &sample_rate, sizeof(sample_rate));
641 	append_to_buffer(header, &i, &byte_rate, sizeof(byte_rate));
642 	append_to_buffer(header, &i, &block_align, sizeof(block_align));
643 	append_to_buffer(header, &i, &bits_per_sample, sizeof(bits_per_sample));
644 
645 	/* Data chunk */
646 	chunk_size = UINT32_MAX; /* unknown chunk size */
647 	append_to_buffer(header, &i, DATA_TAG, strlen(DATA_TAG));
648 	append_to_buffer(header, &i, &chunk_size, sizeof(chunk_size));
649 
650 	igt_assert(i == sizeof(header));
651 
652 	if (write(fd, header, sizeof(header)) != sizeof(header)) {
653 		igt_warn("write failed: %s'n", strerror(errno));
654 		close(fd);
655 		return -1;
656 	}
657 
658 	return fd;
659 }
660