* [PATCH i-g-t v2 0/3] Audio tests support for HDMI, with audio and ALSA helpers
@ 2017-08-21 15:27 Paul Kocialkowski
2017-08-21 15:27 ` [PATCH i-g-t v2 1/3] lib: Add audio library with dedicated helpers Paul Kocialkowski
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Paul Kocialkowski @ 2017-08-21 15:27 UTC (permalink / raw)
To: intel-gfx
Changes since v1:
* Introduced explicit --enable-audio configure option
* Added dependencies to README
* Removed trailing whitespaces
* Fixed alignment in sqrt call
* Fixed ALSA overrun/underrun error handling and recovery
* Fixed ALSA open/close sequence for more robust behavior
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH i-g-t v2 1/3] lib: Add audio library with dedicated helpers
2017-08-21 15:27 [PATCH i-g-t v2 0/3] Audio tests support for HDMI, with audio and ALSA helpers Paul Kocialkowski
@ 2017-08-21 15:27 ` Paul Kocialkowski
2017-08-21 15:27 ` [PATCH i-g-t v2 2/3] lib: Add ALSA " Paul Kocialkowski
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Paul Kocialkowski @ 2017-08-21 15:27 UTC (permalink / raw)
To: intel-gfx
This introduces an audio library, with dedicated helpers for both
generating signals and detecting peak frequencies in a signal.
This library paves the way for testing audio going through display
connectors, such as HDMI.
Signed-off-by: Paul Kocialkowski <paul.kocialkowski@linux.intel.com>
---
.../intel-gpu-tools/intel-gpu-tools-docs.xml | 1 +
lib/Makefile.am | 2 +
lib/igt.h | 1 +
lib/igt_audio.c | 326 +++++++++++++++++++++
lib/igt_audio.h | 47 +++
5 files changed, 377 insertions(+)
create mode 100644 lib/igt_audio.c
create mode 100644 lib/igt_audio.h
diff --git a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
index f88afd2a..c77159cf 100644
--- a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
+++ b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
@@ -16,6 +16,7 @@
<chapter>
<title>API Reference</title>
<xi:include href="xml/drmtest.xml"/>
+ <xi:include href="xml/igt_audio.xml"/>
<xi:include href="xml/igt_aux.xml"/>
<xi:include href="xml/igt_chamelium.xml"/>
<xi:include href="xml/igt_core.xml"/>
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 9c932d6f..5ea08314 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -33,6 +33,8 @@ if HAVE_GSL
lib_source_list += \
igt_frame.c \
igt_frame.h \
+ igt_audio.c \
+ igt_audio.h \
$(NULL)
endif
diff --git a/lib/igt.h b/lib/igt.h
index d16a4991..a75d2db7 100644
--- a/lib/igt.h
+++ b/lib/igt.h
@@ -35,6 +35,7 @@
#include "igt_dummyload.h"
#include "igt_fb.h"
#include "igt_frame.h"
+#include "igt_audio.h"
#include "igt_gt.h"
#include "igt_kms.h"
#include "igt_pm.h"
diff --git a/lib/igt_audio.c b/lib/igt_audio.c
new file mode 100644
index 00000000..6b35529a
--- /dev/null
+++ b/lib/igt_audio.c
@@ -0,0 +1,326 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Paul Kocialkowski <paul.kocialkowski@linux.intel.com>
+ */
+
+#include "config.h"
+
+#include <math.h>
+#include <gsl/gsl_fft_real.h>
+
+#include "igt.h"
+
+#define FREQS_MAX 8
+
+/**
+ * SECTION:igt_audio
+ * @short_description: Library for audio-related tests
+ * @title: Audio
+ * @include: igt_audio.h
+ *
+ * This library contains helpers for audio-related tests. More specifically,
+ * it allows generating additions of sine signals as well as detecting them.
+ */
+
+struct audio_signal_freq {
+ int freq;
+
+ short *period;
+ int frames;
+ int offset;
+};
+
+struct audio_signal {
+ int channels;
+ int sampling_rate;
+
+ struct audio_signal_freq freqs[FREQS_MAX];
+ int freqs_count;
+};
+
+/**
+ * audio_signal_init:
+ * @channels: The number of channels to use for the signal
+ * @sampling_rate: The sampling rate to use for the signal
+ *
+ * Allocate and initialize an audio signal structure with the given parameters.
+ *
+ * Returns: A newly-allocated audio signal structure
+ */
+struct audio_signal *audio_signal_init(int channels, int sampling_rate)
+{
+ struct audio_signal *signal;
+
+ signal = malloc(sizeof(struct audio_signal));
+ memset(signal, 0, sizeof(struct audio_signal));
+
+ signal->sampling_rate = sampling_rate;
+ signal->channels = channels;
+
+ return signal;
+}
+
+/**
+ * audio_signal_add_frequency:
+ * @signal: The target signal structure
+ * @frequency: The frequency to add to the signal
+ *
+ * Add a frequency to the signal.
+ *
+ * Returns: An integer equal to zero for success and negative for failure
+ */
+int audio_signal_add_frequency(struct audio_signal *signal, int frequency)
+{
+ int index = signal->freqs_count;
+
+ if (index == FREQS_MAX)
+ return -1;
+
+ /* Stay within the Nyquist–Shannon sampling theorem. */
+ if (frequency > signal->sampling_rate / 2)
+ return -1;
+
+ /* Clip the frequency to an integer multiple of the sampling rate.
+ * This to be able to store a full period of it and use that for
+ * signal generation, instead of recurrent calls to sin().
+ */
+ frequency = signal->sampling_rate / (signal->sampling_rate / frequency);
+
+ igt_debug("Adding test frequency %d\n", frequency);
+
+ signal->freqs[index].freq = frequency;
+ signal->freqs[index].frames = 0;
+ signal->freqs[index].offset = 0;
+ signal->freqs_count++;
+
+ return 0;
+}
+
+/**
+ * audio_signal_synthesize:
+ * @signal: The target signal structure
+ *
+ * Synthesize the data tables for the audio signal, that can later be used
+ * to fill audio buffers. The resources allocated by this function must be
+ * freed with a call to audio_signal_clean when the signal is no longer used.
+ */
+void audio_signal_synthesize(struct audio_signal *signal)
+{
+ short *period;
+ double value;
+ int frames;
+ int freq;
+ int i, j;
+
+ if (signal->freqs_count == 0)
+ return;
+
+ for (i = 0; i < signal->freqs_count; i++) {
+ freq = signal->freqs[i].freq;
+ frames = signal->sampling_rate / freq;
+
+ period = calloc(1, frames * sizeof(short));
+
+ for (j = 0; j < frames; j++) {
+ value = 2.0 * M_PI * freq / signal->sampling_rate * j;
+ value = sin(value) * SHRT_MAX / signal->freqs_count;
+
+ period[j] = (short) value;
+ }
+
+ signal->freqs[i].period = period;
+ signal->freqs[i].frames = frames;
+ }
+}
+
+/**
+ * audio_signal_synthesize:
+ * @signal: The target signal structure
+ *
+ * Free the resources allocated by audio_signal_synthesize and remove
+ * the previously-added frequencies.
+ */
+void audio_signal_clean(struct audio_signal *signal)
+{
+ int i;
+
+ for (i = 0; i < signal->freqs_count; i++) {
+ if (signal->freqs[i].period)
+ free(signal->freqs[i].period);
+
+ memset(&signal->freqs[i], 0, sizeof(struct audio_signal_freq));
+ }
+
+ signal->freqs_count = 0;
+}
+
+/**
+ * audio_signal_fill:
+ * @signal: The target signal structure
+ * @buffer: The target buffer to fill
+ * @frames: The number of frames to fill
+ *
+ * Fill the requested number of frames to the target buffer with the audio
+ * signal data (in interleaved S16_LE format), at the requested sampling rate
+ * and number of channels.
+ */
+void audio_signal_fill(struct audio_signal *signal, short *buffer, int frames)
+{
+ short *destination;
+ short *source;
+ int total;
+ int freq_frames;
+ int freq_offset;
+ int count;
+ int i, j, k;
+
+ memset(buffer, 0, sizeof(short) * signal->channels * frames);
+
+ for (i = 0; i < signal->freqs_count; i++) {
+ total = 0;
+
+ while (total < frames) {
+ freq_frames = signal->freqs[i].frames;
+ freq_offset = signal->freqs[i].offset;
+
+ source = signal->freqs[i].period + freq_offset;
+ destination = buffer + total * signal->channels;
+
+ count = freq_frames - freq_offset;
+ if (count > (frames - total))
+ count = frames - total;
+
+ freq_offset += count;
+ freq_offset %= freq_frames;
+
+ signal->freqs[i].offset = freq_offset;
+
+ for (j = 0; j < count; j++) {
+ for (k = 0; k < signal->channels; k++) {
+ destination[j * signal->channels + k] += source[j];
+ }
+ }
+
+ total += count;
+ }
+ }
+}
+
+/**
+ * audio_signal_detect:
+ * @signal: The target signal structure
+ * @channels: The input data's number of channels
+ * @sampling_rate: The input data's sampling rate
+ * @buffer: The input data's buffer
+ * @frames: The input data's number of frames
+ *
+ * Detect that the frequencies specified in @signal, and only those, are
+ * present in the input data. The input data's format is required to be S16_LE.
+ *
+ * Returns: A boolean indicating whether the detection was successful
+ */
+bool audio_signal_detect(struct audio_signal *signal, int channels,
+ int sampling_rate, short *buffer, int frames)
+{
+ double data[frames];
+ int amplitude[frames / 2];
+ bool detected[signal->freqs_count];
+ int threshold;
+ bool above;
+ int error;
+ int freq;
+ int max;
+ int c, i, j;
+
+ /* Allowed error in Hz due to FFT step. */
+ error = sampling_rate / frames;
+
+ for (c = 0; c < channels; c++) {
+ for (i = 0; i < frames; i++)
+ data[i] = (double) buffer[i * channels + c];
+
+ gsl_fft_real_radix2_transform(data, 1, frames);
+
+ max = 0;
+
+ for (i = 0; i < frames / 2; i++) {
+ amplitude[i] = sqrt(data[i] * data[i] +
+ data[frames - i] *
+ data[frames - i]);
+ if (amplitude[i] > max)
+ max = amplitude[i];
+ }
+
+ for (i = 0; i < signal->freqs_count; i++)
+ detected[i] = false;
+
+ threshold = max / 2;
+ above = false;
+ max = 0;
+
+ for (i = 0; i < frames / 2; i++) {
+ if (amplitude[i] > threshold)
+ above = true;
+
+ if (above) {
+ if (amplitude[i] < threshold) {
+ above = false;
+ max = 0;
+
+ for (j = 0; j < signal->freqs_count; j++) {
+ if (signal->freqs[j].freq >
+ freq - error &&
+ signal->freqs[j].freq <
+ freq + error) {
+ detected[j] = true;
+ break;
+ }
+ }
+
+ /* Detected frequency was not generated. */
+ if (j == signal->freqs_count) {
+ igt_debug("Detected additional frequency: %d\n",
+ freq);
+ return false;
+ }
+ }
+
+ if (amplitude[i] > max) {
+ max = amplitude[i];
+ freq = sampling_rate * i / frames;
+ }
+ }
+ }
+
+ for (i = 0; i < signal->freqs_count; i++) {
+ if (!detected[i]) {
+ igt_debug("Missing frequency: %d\n",
+ signal->freqs[i].freq);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
diff --git a/lib/igt_audio.h b/lib/igt_audio.h
new file mode 100644
index 00000000..507e7ab9
--- /dev/null
+++ b/lib/igt_audio.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Paul Kocialkowski <paul.kocialkowski@linux.intel.com>
+ */
+
+#ifndef IGT_AUDIO_H
+#define IGT_AUDIO_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "igt.h"
+#include <stdbool.h>
+
+struct audio_signal;
+
+struct audio_signal *audio_signal_init(int channels, int sampling_rate);
+int audio_signal_add_frequency(struct audio_signal *signal, int frequency);
+void audio_signal_synthesize(struct audio_signal *signal);
+void audio_signal_clean(struct audio_signal *signal);
+void audio_signal_fill(struct audio_signal *signal, short *buffer, int frames);
+bool audio_signal_detect(struct audio_signal *signal, int channels,
+ int sampling_rate, short *buffer, int frames);
+
+#endif
--
2.14.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH i-g-t v2 2/3] lib: Add ALSA library with dedicated helpers
2017-08-21 15:27 [PATCH i-g-t v2 0/3] Audio tests support for HDMI, with audio and ALSA helpers Paul Kocialkowski
2017-08-21 15:27 ` [PATCH i-g-t v2 1/3] lib: Add audio library with dedicated helpers Paul Kocialkowski
@ 2017-08-21 15:27 ` Paul Kocialkowski
2017-08-21 15:27 ` [PATCH i-g-t v2 3/3] tests: Introduce audio tests, starting with HDMI signal integrity Paul Kocialkowski
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Paul Kocialkowski @ 2017-08-21 15:27 UTC (permalink / raw)
To: intel-gfx
This introduces an ALSA library, with dedicated helpers for handling
playback and capture. It handles ALSA device identification and
configuration as well as a run loop with callback mechanisms for feeding
output data and handling input data.
This library paves the way for testing audio going through display
connectors, such as HDMI.
Signed-off-by: Paul Kocialkowski <paul.kocialkowski@linux.intel.com>
---
configure.ac | 3 +
.../intel-gpu-tools/intel-gpu-tools-docs.xml | 1 +
lib/Makefile.am | 7 +
lib/igt.h | 1 +
lib/igt_alsa.c | 637 +++++++++++++++++++++
lib/igt_alsa.h | 60 ++
6 files changed, 709 insertions(+)
create mode 100644 lib/igt_alsa.c
create mode 100644 lib/igt_alsa.h
diff --git a/configure.ac b/configure.ac
index 50aa86b5..e66273a4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -219,6 +219,9 @@ if test "x$enable_chamelium" = xyes; then
AC_DEFINE(HAVE_CHAMELIUM, 1, [Enable Chamelium support])
fi
+PKG_CHECK_MODULES(ALSA, [alsa], [alsa=yes], [alsa=no])
+AM_CONDITIONAL(HAVE_ALSA, [test "x$alsa" = xyes])
+
# -----------------------------------------------------------------------------
# Configuration options
# -----------------------------------------------------------------------------
diff --git a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
index c77159cf..0c34e4a5 100644
--- a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
+++ b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
@@ -16,6 +16,7 @@
<chapter>
<title>API Reference</title>
<xi:include href="xml/drmtest.xml"/>
+ <xi:include href="xml/igt_alsa.xml"/>
<xi:include href="xml/igt_audio.xml"/>
<xi:include href="xml/igt_aux.xml"/>
<xi:include href="xml/igt_chamelium.xml"/>
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 5ea08314..3ff14f66 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -38,6 +38,13 @@ lib_source_list += \
$(NULL)
endif
+if HAVE_ALSA
+lib_source_list += \
+ igt_alsa.c \
+ igt_alsa.h \
+ $(NULL)
+endif
+
AM_CPPFLAGS = -I$(top_srcdir)
AM_CFLAGS = \
$(CWARNFLAGS) \
diff --git a/lib/igt.h b/lib/igt.h
index a75d2db7..ebf92349 100644
--- a/lib/igt.h
+++ b/lib/igt.h
@@ -35,6 +35,7 @@
#include "igt_dummyload.h"
#include "igt_fb.h"
#include "igt_frame.h"
+#include "igt_alsa.h"
#include "igt_audio.h"
#include "igt_gt.h"
#include "igt_kms.h"
diff --git a/lib/igt_alsa.c b/lib/igt_alsa.c
new file mode 100644
index 00000000..b5574c76
--- /dev/null
+++ b/lib/igt_alsa.c
@@ -0,0 +1,637 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Paul Kocialkowski <paul.kocialkowski@linux.intel.com>
+ */
+
+#include "config.h"
+
+#include <alsa/asoundlib.h>
+
+#include "igt.h"
+
+#define HANDLES_MAX 8
+
+/**
+ * SECTION:igt_alsa
+ * @short_description: Library with ALSA helpers
+ * @title: ALSA
+ * @include: igt_alsa.h
+ *
+ * This library contains helpers for ALSA playback and capture.
+ */
+
+struct alsa {
+ snd_pcm_t *output_handles[HANDLES_MAX];
+ int output_handles_count;
+ int output_sampling_rate;
+ int output_channels;
+
+ int (*output_callback)(void *data, short *buffer, int samples);
+ void *output_callback_data;
+ int output_samples_trigger;
+
+ snd_pcm_t *input_handle;
+ int input_sampling_rate;
+ int input_channels;
+
+ int (*input_callback)(void *data, short *buffer, int samples);
+ void *input_callback_data;
+ int input_samples_trigger;
+};
+
+static void alsa_error_handler(const char *file, int line, const char *function,
+ int err, const char *fmt, ...)
+{
+ if (err)
+ igt_debug("[ALSA] %s: %s\n", function, snd_strerror(err));
+}
+
+/**
+ * alsa_init:
+ * Allocate and initialize an alsa structure and configure the error handler.
+ *
+ * Returns: A newly-allocated alsa structure
+ */
+struct alsa *alsa_init(void)
+{
+ struct alsa *alsa;
+
+ alsa = malloc(sizeof(struct alsa));
+ memset(alsa, 0, sizeof(struct alsa));
+
+ /* Redirect errors to igt_debug instead of stderr. */
+ snd_lib_error_set_handler(alsa_error_handler);
+
+ return alsa;
+}
+
+static char *alsa_resolve_indentifier(const char *device_name, int skip)
+{
+ snd_ctl_card_info_t *card_info;
+ snd_pcm_info_t *pcm_info;
+ snd_ctl_t *handle = NULL;
+ const char *pcm_name;
+ char *identifier = NULL;
+ char name[32];
+ int card = -1;
+ int dev;
+ int ret;
+
+ snd_ctl_card_info_alloca(&card_info);
+ snd_pcm_info_alloca(&pcm_info);
+
+ /* First try to open the device as-is. */
+ if (!skip) {
+ ret = snd_ctl_open(&handle, device_name, 0);
+ if (!ret) {
+ identifier = strdup(device_name);
+ goto resolved;
+ }
+ }
+
+ do {
+ ret = snd_card_next(&card);
+ if (ret < 0 || card < 0)
+ break;
+
+ snprintf(name, sizeof(name), "hw:%d", card);
+
+ ret = snd_ctl_open(&handle, name, 0);
+ if (ret < 0)
+ continue;
+
+ ret = snd_ctl_card_info(handle, card_info);
+ if (ret < 0) {
+ snd_ctl_close(handle);
+ handle = NULL;
+ continue;
+ }
+
+ dev = -1;
+
+ do {
+ ret = snd_ctl_pcm_next_device(handle, &dev);
+ if (ret < 0 || dev < 0)
+ break;
+
+ snd_pcm_info_set_device(pcm_info, dev);
+ snd_pcm_info_set_subdevice(pcm_info, 0);
+
+ ret = snd_ctl_pcm_info(handle, pcm_info);
+ if (ret < 0)
+ continue;
+
+ pcm_name = snd_pcm_info_get_name(pcm_info);
+ if (!pcm_name)
+ continue;
+
+ ret = strncmp(device_name, pcm_name,
+ strlen(device_name));
+
+ if (ret == 0) {
+ if (skip > 0) {
+ skip--;
+ continue;
+ }
+
+ snprintf(name, sizeof(name), "hw:%d,%d", card,
+ dev);
+
+ identifier = strdup(name);
+ goto resolved;
+ }
+ } while (dev >= 0);
+
+ snd_ctl_close(handle);
+ handle = NULL;
+ } while (card >= 0);
+
+resolved:
+ if (handle)
+ snd_ctl_close(handle);
+
+ return identifier;
+}
+
+/**
+ * alsa_open_output:
+ * @alsa: The target alsa structure
+ * @device_name: The name prefix of the output device(s) to open
+ *
+ * Open ALSA output devices whose name prefixes match the provided name prefix.
+ *
+ * Returns: An integer equal to zero for success and negative for failure
+ */
+int alsa_open_output(struct alsa *alsa, const char *device_name)
+{
+ snd_pcm_t *handle;
+ char *identifier;
+ int skip;
+ int index;
+ int ret;
+
+ skip = alsa->output_handles_count;
+ index = alsa->output_handles_count;
+
+ while (index < HANDLES_MAX) {
+ identifier = alsa_resolve_indentifier(device_name, skip++);
+ if (!identifier)
+ break;
+
+ ret = snd_pcm_open(&handle, identifier, SND_PCM_STREAM_PLAYBACK,
+ SND_PCM_NONBLOCK);
+ if (ret < 0) {
+ free(identifier);
+ continue;
+ }
+
+ igt_debug("Opened output %s\n", identifier);
+
+ alsa->output_handles[index++] = handle;
+ free(identifier);
+ }
+
+ if (index == 0)
+ return -1;
+
+ alsa->output_handles_count = index;
+
+ return 0;
+}
+
+/**
+ * alsa_open_input:
+ * @alsa: The target alsa structure
+ * @device_name: The name of the input device to open
+ *
+ * Open the ALSA input device whose name matches the provided name prefix.
+ *
+ * Returns: An integer equal to zero for success and negative for failure
+ */
+int alsa_open_input(struct alsa *alsa, const char *device_name)
+{
+ snd_pcm_t *handle;
+ char *identifier;
+ int ret;
+
+ identifier = alsa_resolve_indentifier(device_name, 0);
+
+ ret = snd_pcm_open(&handle, device_name, SND_PCM_STREAM_CAPTURE,
+ SND_PCM_NONBLOCK);
+ if (ret < 0)
+ goto complete;
+
+ igt_debug("Opened input %s\n", identifier);
+
+ alsa->input_handle = handle;
+
+ ret = 0;
+
+complete:
+ free(identifier);
+
+ return ret;
+}
+
+/**
+ * alsa_close_output:
+ * @alsa: The target alsa structure
+ *
+ * Close all the open ALSA outputs.
+ */
+void alsa_close_output(struct alsa *alsa)
+{
+ snd_pcm_t *handle;
+ int i;
+
+ for (i = 0; i < alsa->output_handles_count; i++) {
+ handle = alsa->output_handles[i];
+ if (!handle)
+ continue;
+
+ snd_pcm_close(handle);
+ alsa->output_handles[i] = NULL;
+ }
+
+ alsa->output_handles_count = 0;
+
+ alsa->output_callback = NULL;
+}
+
+/**
+ * alsa_close_output:
+ * @alsa: The target alsa structure
+ *
+ * Close the open ALSA input.
+ */
+void alsa_close_input(struct alsa *alsa)
+{
+ snd_pcm_t *handle = alsa->input_handle;
+ if (!handle)
+ return;
+
+ snd_pcm_close(handle);
+ alsa->input_handle = NULL;
+
+ alsa->input_callback = NULL;
+}
+
+static bool alsa_test_configuration(snd_pcm_t *handle, int channels,
+ int sampling_rate)
+{
+ snd_pcm_hw_params_t *params;
+ int ret;
+
+ snd_pcm_hw_params_alloca(¶ms);
+
+ ret = snd_pcm_hw_params_any(handle, params);
+ if (ret < 0)
+ return false;
+
+ ret = snd_pcm_hw_params_test_rate(handle, params, sampling_rate, 0);
+ if (ret < 0)
+ return false;
+
+ ret = snd_pcm_hw_params_test_channels(handle, params, channels);
+ if (ret < 0)
+ return false;
+
+ return true;
+}
+
+/**
+ * alsa_test_output_configuration:
+ * @alsa: The target alsa structure
+ * @channels: The number of channels to test
+ * @sampling_rate: The sampling rate to test
+ *
+ * Test the output configuration specified by @channels and @sampling_rate
+ * for the output devices.
+ *
+ * Returns: A boolean indicating whether the test succeeded
+ */
+bool alsa_test_output_configuration(struct alsa *alsa, int channels,
+ int sampling_rate)
+{
+ snd_pcm_t *handle;
+ bool ret;
+ int i;
+
+ for (i = 0; i < alsa->output_handles_count; i++) {
+ handle = alsa->output_handles[i];
+
+ ret = alsa_test_configuration(handle, channels, sampling_rate);
+ if (!ret)
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * alsa_test_input_configuration:
+ * @alsa: The target alsa structure
+ * @channels: The number of channels to test
+ * @sampling_rate: The sampling rate to test
+ *
+ * Test the input configuration specified by @channels and @sampling_rate
+ * for the input device.
+ *
+ * Returns: A boolean indicating whether the test succeeded
+ */
+bool alsa_test_input_configuration(struct alsa *alsa, int channels,
+ int sampling_rate)
+{
+ return alsa_test_configuration(alsa->input_handle, channels,
+ sampling_rate);
+}
+
+/**
+ * alsa_configure_output:
+ * @alsa: The target alsa structure
+ * @channels: The number of channels to test
+ * @sampling_rate: The sampling rate to test
+ *
+ * Configure the output devices with the configuration specified by @channels
+ * and @sampling_rate.
+ */
+void alsa_configure_output(struct alsa *alsa, int channels,
+ int sampling_rate)
+{
+ snd_pcm_t *handle;
+ int ret;
+ int i;
+
+ for (i = 0; i < alsa->output_handles_count; i++) {
+ handle = alsa->output_handles[i];
+
+ ret = snd_pcm_set_params(handle, SND_PCM_FORMAT_S16_LE,
+ SND_PCM_ACCESS_RW_INTERLEAVED,
+ channels, sampling_rate, 0, 0);
+ igt_assert(ret >= 0);
+ }
+
+ alsa->output_channels = channels;
+ alsa->output_sampling_rate = sampling_rate;
+}
+
+/**
+ * alsa_configure_input:
+ * @alsa: The target alsa structure
+ * @channels: The number of channels to test
+ * @sampling_rate: The sampling rate to test
+ *
+ * Configure the input device with the configuration specified by @channels
+ * and @sampling_rate.
+ */
+void alsa_configure_input(struct alsa *alsa, int channels,
+ int sampling_rate)
+{
+ snd_pcm_t *handle;
+ int ret;
+
+ handle = alsa->input_handle;
+
+ ret = snd_pcm_set_params(handle, SND_PCM_FORMAT_S16_LE,
+ SND_PCM_ACCESS_RW_INTERLEAVED, channels,
+ sampling_rate, 0, 0);
+ igt_assert(ret >= 0);
+
+ alsa->input_channels = channels;
+ alsa->input_sampling_rate = sampling_rate;
+
+}
+
+/**
+ * alsa_register_output_callback:
+ * @alsa: The target alsa structure
+ * @callback: The callback function to call to fill output data
+ * @callback_data: The data pointer to pass to the callback function
+ * @samples_trigger: The required number of samples to trigger the callback
+ *
+ * Register a callback function to be called to fill output data during a run.
+ * The callback is called when @samples_trigger samples are required.
+ *
+ * The callback should return an integer equal to zero for success and negative
+ * for failure.
+ */
+void alsa_register_output_callback(struct alsa *alsa,
+ int (*callback)(void *data, short *buffer, int samples),
+ void *callback_data, int samples_trigger)
+{
+ alsa->output_callback = callback;
+ alsa->output_callback_data = callback_data;
+ alsa->output_samples_trigger = samples_trigger;
+}
+
+/**
+ * alsa_register_input_callback:
+ * @alsa: The target alsa structure
+ * @callback: The callback function to call when input data is available
+ * @callback_data: The data pointer to pass to the callback function
+ * @samples_trigger: The required number of samples to trigger the callback
+ *
+ * Register a callback function to be called when input data is available during
+ * a run. The callback is called when @samples_trigger samples are available.
+ *
+ * The callback should return an integer equal to zero for success, negative for
+ * failure and positive to indicate that the run should stop.
+ */
+void alsa_register_input_callback(struct alsa *alsa,
+ int (*callback)(void *data, short *buffer, int samples),
+ void *callback_data, int samples_trigger)
+{
+ alsa->input_callback = callback;
+ alsa->input_callback_data = callback_data;
+ alsa->input_samples_trigger = samples_trigger;
+}
+
+/**
+ * alsa_run:
+ * @alsa: The target alsa structure
+ * @duration_ms: The maximum duration of the run in milliseconds
+ *
+ * Run ALSA playback and capture on the input and output devices for at
+ * most @duration_ms milliseconds, calling the registered callbacks when needed.
+ *
+ * Returns: An integer equal to zero for success, positive for a stop caused
+ * by the input callback and negative for failure
+ */
+int alsa_run(struct alsa *alsa, int duration_ms)
+{
+ snd_pcm_t *handle;
+ short *output_buffer = NULL;
+ short *input_buffer = NULL;
+ int output_limit;
+ int output_total = 0;
+ int output_counts[alsa->output_handles_count];
+ bool output_ready = false;
+ int output_channels;
+ int output_trigger;
+ int input_limit;
+ int input_total = 0;
+ int input_count = 0;
+ int input_channels;
+ int input_trigger;
+ bool reached;
+ int index;
+ int count;
+ int avail;
+ int i;
+ int ret;
+
+ output_limit = alsa->output_sampling_rate * duration_ms / 1000;
+ output_channels = alsa->output_channels;
+ output_trigger = alsa->output_samples_trigger;
+ output_buffer = malloc(sizeof(short) * output_channels *
+ output_trigger);
+
+ if (alsa->input_callback) {
+ input_limit = alsa->input_sampling_rate * duration_ms / 1000;
+ input_trigger = alsa->input_samples_trigger;
+ input_channels = alsa->input_channels;
+ input_buffer = malloc(sizeof(short) * input_channels *
+ input_trigger);
+ }
+
+ do {
+ reached = true;
+
+ if (output_total < output_limit) {
+ reached = false;
+
+ if (!output_ready) {
+ output_ready = true;
+
+ for (i = 0; i < alsa->output_handles_count; i++)
+ output_counts[i] = 0;
+
+ ret = alsa->output_callback(alsa->output_callback_data,
+ output_buffer,
+ output_trigger);
+ if (ret < 0)
+ goto complete;
+ }
+
+ for (i = 0; i < alsa->output_handles_count; i++) {
+ handle = alsa->output_handles[i];
+
+ ret = snd_pcm_avail(handle);
+ if (output_counts[i] < output_trigger &&
+ ret > 0) {
+ index = output_counts[i] *
+ output_channels;
+ count = output_trigger -
+ output_counts[i];
+ avail = snd_pcm_avail(handle);
+
+ count = avail < count ? avail : count;
+
+ ret = snd_pcm_writei(handle,
+ &output_buffer[index],
+ count);
+ if (ret < 0) {
+ ret = snd_pcm_recover(handle,
+ ret, 0);
+ if (ret < 0)
+ goto complete;
+ }
+
+ output_counts[i] += ret;
+ } else if (output_counts[i] < output_trigger &&
+ ret < 0) {
+ ret = snd_pcm_recover(handle, ret, 0);
+ if (ret < 0)
+ goto complete;
+ }
+ }
+
+ output_ready = false;
+
+ for (i = 0; i < alsa->output_handles_count; i++)
+ if (output_counts[i] < output_trigger)
+ output_ready = true;
+
+ if (!output_ready)
+ output_total += output_trigger;
+
+ }
+
+ if (alsa->input_callback && input_total < input_limit) {
+ reached = false;
+
+ if (input_count == input_trigger) {
+ input_count = 0;
+
+ ret = alsa->input_callback(alsa->input_callback_data,
+ input_buffer,
+ input_trigger);
+ if (ret != 0)
+ goto complete;
+ }
+
+ handle = alsa->input_handle;
+
+ ret = snd_pcm_avail(handle);
+ if (input_count < input_trigger &&
+ (ret > 0 || input_total == 0)) {
+ index = input_count * input_channels;
+ count = input_trigger - input_count;
+ avail = snd_pcm_avail(handle);
+
+ count = avail > 0 && avail < count ? avail :
+ count;
+
+ ret = snd_pcm_readi(handle,
+ &input_buffer[index],
+ count);
+ if (ret == -EAGAIN) {
+ ret = 0;
+ } else if (ret < 0) {
+ ret = snd_pcm_recover(handle, ret, 0);
+ if (ret < 0)
+ goto complete;
+ }
+
+ input_count += ret;
+ input_total += ret;
+ } else if (input_count < input_trigger && ret < 0) {
+ ret = snd_pcm_recover(handle, ret, 0);
+ if (ret < 0)
+ goto complete;
+ }
+ }
+ } while (!reached);
+
+ ret = 0;
+
+complete:
+ if (output_buffer)
+ free(output_buffer);
+
+ if (input_buffer)
+ free(input_buffer);
+
+ return ret;
+}
diff --git a/lib/igt_alsa.h b/lib/igt_alsa.h
new file mode 100644
index 00000000..f3949d26
--- /dev/null
+++ b/lib/igt_alsa.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Paul Kocialkowski <paul.kocialkowski@linux.intel.com>
+ */
+
+#ifndef IGT_ALSA_H
+#define IGT_ALSA_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "igt.h"
+#include <stdbool.h>
+
+struct alsa;
+
+struct alsa *alsa_init(void);
+int alsa_open_output(struct alsa *alsa, const char *device_name);
+int alsa_open_input(struct alsa *alsa, const char *device_name);
+void alsa_close_output(struct alsa *alsa);
+void alsa_close_input(struct alsa *alsa);
+bool alsa_test_output_configuration(struct alsa *alsa, int channels,
+ int sampling_rate);
+bool alsa_test_input_configuration(struct alsa *alsa, int channels,
+ int sampling_rate);
+void alsa_configure_output(struct alsa *alsa, int channels,
+ int sampling_rate);
+void alsa_configure_input(struct alsa *alsa, int channels,
+ int sampling_rate);
+void alsa_register_output_callback(struct alsa *alsa,
+ int (*callback)(void *data, short *buffer, int samples),
+ void *callback_data, int samples_trigger);
+void alsa_register_input_callback(struct alsa *alsa,
+ int (*callback)(void *data, short *buffer, int samples),
+ void *callback_data, int samples_trigger);
+int alsa_run(struct alsa *alsa, int duration_ms);
+
+#endif
--
2.14.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH i-g-t v2 3/3] tests: Introduce audio tests, starting with HDMI signal integrity
2017-08-21 15:27 [PATCH i-g-t v2 0/3] Audio tests support for HDMI, with audio and ALSA helpers Paul Kocialkowski
2017-08-21 15:27 ` [PATCH i-g-t v2 1/3] lib: Add audio library with dedicated helpers Paul Kocialkowski
2017-08-21 15:27 ` [PATCH i-g-t v2 2/3] lib: Add ALSA " Paul Kocialkowski
@ 2017-08-21 15:27 ` Paul Kocialkowski
2017-08-21 15:48 ` ✓ Fi.CI.BAT: success for Audio tests support for HDMI, with audio and ALSA helpers Patchwork
2017-08-21 17:58 ` [PATCH i-g-t v2 0/3] " Lyude Paul
4 siblings, 0 replies; 6+ messages in thread
From: Paul Kocialkowski @ 2017-08-21 15:27 UTC (permalink / raw)
To: intel-gfx
This introduces a new test for audio going through display connectors.
It currently contains a single subtest for HDMI signal integrity, but
other test cases will be added later on.
The test setup consists in using an HDMI-VGA bridge that separates the
audio out (via a 3.5 mm jack) and feeding this back to the DUT's line-in
where it can be recorded by ALSA with controls correctly configured.
The audio test makes use of the audio and ALSA igt libraries helpers.
Signed-off-by: Paul Kocialkowski <paul.kocialkowski@linux.intel.com>
---
README | 6 ++
configure.ac | 18 ++++++
tests/Makefile.am | 12 ++++
tests/audio.c | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 210 insertions(+)
create mode 100644 tests/audio.c
diff --git a/README b/README
index d1ea9529..c3ddf768 100644
--- a/README
+++ b/README
@@ -153,6 +153,12 @@ The following dependencies are required for building chamelium support
libglib2.0-dev
libgsl-dev
+The following dependencies are requires for building audio support
+(package names may vary):
+
+ libasound2-dev
+ libgsl-dev
+
Releases for maintainers
------------------------
diff --git a/configure.ac b/configure.ac
index e66273a4..41ec4d26 100644
--- a/configure.ac
+++ b/configure.ac
@@ -222,6 +222,23 @@ fi
PKG_CHECK_MODULES(ALSA, [alsa], [alsa=yes], [alsa=no])
AM_CONDITIONAL(HAVE_ALSA, [test "x$alsa" = xyes])
+# for audio
+AC_ARG_ENABLE(audio, AS_HELP_STRING([--enable-audio],
+ [Enable building of audio tests (default: no)]),
+ [if test x$enableval = xyes; then enable_audio=yes; fi],
+ [enable_audio=no])
+AM_CONDITIONAL(HAVE_AUDIO, [test "x$enable_audio" = xyes])
+if test "x$enable_audio" = xyes; then
+ if test x"$alsa" != xyes; then
+ AC_MSG_ERROR([Failed to find ALSA, required by audio.])
+ fi
+ if test x"$gsl" != xyes; then
+ AC_MSG_ERROR([Failed to find gsl, required by audio.])
+ fi
+
+ AC_DEFINE(HAVE_AUDIO, 1, [Enable Audio support])
+fi
+
# -----------------------------------------------------------------------------
# Configuration options
# -----------------------------------------------------------------------------
@@ -420,6 +437,7 @@ echo ""
echo " • Tests:"
echo " Build tests : ${BUILD_TESTS}"
echo " Chamelium tests : ${enable_chamelium}"
+echo " Audio tests : ${enable_audio}"
echo " Compile prime tests: ${NOUVEAU}"
echo " Print stack traces : ${with_libunwind}"
echo " Debug flags : ${DEBUG_CFLAGS}"
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f9d11e6c..471f3818 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -20,6 +20,15 @@ TESTS_progs += \
$(NULL)
endif
+if HAVE_ALSA
+if HAVE_GSL
+TESTS_progs += \
+ audio \
+ $(NULL)
+endif
+endif
+
+
if BUILD_TESTS
test-list.txt: Makefile.sources
@echo TESTLIST > $@
@@ -134,6 +143,9 @@ vc4_wait_seqno_LDADD = $(LDADD) $(DRM_VC4_LIBS)
chamelium_CFLAGS = $(AM_CFLAGS) $(XMLRPC_CFLAGS) $(LIBUDEV_CFLAGS)
chamelium_LDADD = $(LDADD) $(XMLRPC_LIBS) $(LIBUDEV_LIBS)
+audio_CFLAGS = $(AM_CFLAGS) $(ALSA_CFLAGS)
+audio_LDADD = $(LDADD) $(ALSA_LIBS)
+
amdgpu_amd_basic_CFLAGS = $(AM_CFLAGS) $(DRM_AMDGPU_CFLAGS)
amdgpu_amd_basic_LDADD = $(LDADD) $(DRM_AMDGPU_LIBS)
amdgpu_amd_cs_nop_CFLAGS = $(AM_CFLAGS) $(DRM_AMDGPU_CFLAGS)
diff --git a/tests/audio.c b/tests/audio.c
new file mode 100644
index 00000000..7fb91c97
--- /dev/null
+++ b/tests/audio.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Paul Kocialkowski <paul.kocialkowski@linux.intel.com>
+ */
+
+#include "config.h"
+#include "igt.h"
+
+#define PLAYBACK_CHANNELS 2
+#define PLAYBACK_FRAMES 1024
+
+#define CAPTURE_SAMPLE_RATE 48000
+#define CAPTURE_CHANNELS 2
+#define CAPTURE_DEVICE_NAME "default"
+#define CAPTURE_FRAMES 2048
+
+#define RUN_TIMEOUT 2000
+
+struct test_data {
+ struct alsa *alsa;
+ struct audio_signal *signal;
+
+ int streak;
+};
+
+static int sampling_rates[] = {
+ 32000,
+ 44100,
+ 48000,
+ 88200,
+ 96000,
+ 176400,
+ 192000,
+};
+
+static int sampling_rates_count = sizeof(sampling_rates) / sizeof(int);
+
+static int test_frequencies[] = {
+ 300,
+ 600,
+ 1200,
+ 80000,
+ 10000,
+};
+
+static int test_frequencies_count = sizeof(test_frequencies) / sizeof(int);
+
+static int output_callback(void *data, short *buffer, int frames)
+{
+ struct test_data *test_data = (struct test_data *) data;
+
+ audio_signal_fill(test_data->signal, buffer, frames);
+
+ return 0;
+}
+
+static int input_callback(void *data, short *buffer, int frames)
+{
+ struct test_data *test_data = (struct test_data *) data;
+ bool detect;
+
+ detect = audio_signal_detect(test_data->signal, CAPTURE_CHANNELS,
+ CAPTURE_SAMPLE_RATE, buffer, frames);
+ if (detect)
+ test_data->streak++;
+ else
+ test_data->streak = 0;
+
+ /* A streak of 3 gives confidence that the signal is good. */
+ if (test_data->streak == 3)
+ return 1;
+
+ return 0;
+}
+
+static void test_integrity(const char *device_name)
+{
+ struct test_data data;
+ int sampling_rate;
+ bool run = false;
+ bool test;
+ int i, j;
+ int ret;
+
+ data.alsa = alsa_init();
+ igt_assert(data.alsa);
+
+ ret = alsa_open_input(data.alsa, CAPTURE_DEVICE_NAME);
+ igt_assert(ret >= 0);
+
+ alsa_configure_input(data.alsa, CAPTURE_CHANNELS,
+ CAPTURE_SAMPLE_RATE);
+
+ alsa_register_input_callback(data.alsa, input_callback, &data,
+ CAPTURE_FRAMES);
+
+ for (i = 0; i < sampling_rates_count; i++) {
+ ret = alsa_open_output(data.alsa, device_name);
+ igt_assert(ret >= 0);
+
+ sampling_rate = sampling_rates[i];
+
+ test = alsa_test_output_configuration(data.alsa,
+ PLAYBACK_CHANNELS,
+ sampling_rate);
+ if (!test) {
+ alsa_close_output(data.alsa);
+ continue;
+ }
+
+ igt_debug("Testing with sampling rate %d\n", sampling_rate);
+
+ alsa_configure_output(data.alsa, PLAYBACK_CHANNELS,
+ sampling_rate);
+
+ data.signal = audio_signal_init(PLAYBACK_CHANNELS,
+ sampling_rate);
+ igt_assert(data.signal);
+
+ for (j = 0; j < test_frequencies_count; j++)
+ audio_signal_add_frequency(data.signal,
+ test_frequencies[j]);
+
+ audio_signal_synthesize(data.signal);
+
+ alsa_register_output_callback(data.alsa, output_callback,
+ &data, PLAYBACK_FRAMES);
+
+ data.streak = 0;
+
+ ret = alsa_run(data.alsa, RUN_TIMEOUT);
+ igt_assert(ret > 0);
+
+ audio_signal_clean(data.signal);
+ free(data.signal);
+
+ alsa_close_output(data.alsa);
+
+ run = true;
+ }
+
+ /* Make sure we tested at least one frequency */
+ igt_assert(run);
+
+ alsa_close_input(data.alsa);
+ free(data.alsa);
+}
+
+igt_main
+{
+ igt_subtest("hdmi-integrity")
+ test_integrity("HDMI");
+}
--
2.14.0
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 6+ messages in thread
* ✓ Fi.CI.BAT: success for Audio tests support for HDMI, with audio and ALSA helpers
2017-08-21 15:27 [PATCH i-g-t v2 0/3] Audio tests support for HDMI, with audio and ALSA helpers Paul Kocialkowski
` (2 preceding siblings ...)
2017-08-21 15:27 ` [PATCH i-g-t v2 3/3] tests: Introduce audio tests, starting with HDMI signal integrity Paul Kocialkowski
@ 2017-08-21 15:48 ` Patchwork
2017-08-21 17:58 ` [PATCH i-g-t v2 0/3] " Lyude Paul
4 siblings, 0 replies; 6+ messages in thread
From: Patchwork @ 2017-08-21 15:48 UTC (permalink / raw)
To: Paul Kocialkowski; +Cc: intel-gfx
== Series Details ==
Series: Audio tests support for HDMI, with audio and ALSA helpers
URL : https://patchwork.freedesktop.org/series/29096/
State : success
== Summary ==
IGT patchset tested on top of latest successful build
5a17ee2c8f9013f5db852d27564b837f9f2c5a9f tools/intel_vbt_decode: Fix decoding of child device structure
with latest DRM-Tip kernel build CI_DRM_2985
dbfb2f62576e drm-tip: 2017y-08m-21d-08h-13m-34s UTC integration manifest
Test gem_exec_flush:
Subgroup basic-batch-kernel-default-uc:
pass -> FAIL (fi-snb-2600) fdo#100007
Test kms_pipe_crc_basic:
Subgroup suspend-read-crc-pipe-b:
dmesg-warn -> PASS (fi-byt-j1900) fdo#101705 +1
fdo#100007 https://bugs.freedesktop.org/show_bug.cgi?id=100007
fdo#101705 https://bugs.freedesktop.org/show_bug.cgi?id=101705
fi-bdw-5557u total:279 pass:268 dwarn:0 dfail:0 fail:0 skip:11 time:458s
fi-bdw-gvtdvm total:279 pass:265 dwarn:0 dfail:0 fail:0 skip:14 time:441s
fi-blb-e6850 total:279 pass:224 dwarn:1 dfail:0 fail:0 skip:54 time:362s
fi-bsw-n3050 total:279 pass:243 dwarn:0 dfail:0 fail:0 skip:36 time:577s
fi-bwr-2160 total:279 pass:184 dwarn:0 dfail:0 fail:0 skip:95 time:251s
fi-bxt-j4205 total:279 pass:260 dwarn:0 dfail:0 fail:0 skip:19 time:527s
fi-byt-j1900 total:279 pass:255 dwarn:0 dfail:0 fail:0 skip:24 time:531s
fi-byt-n2820 total:279 pass:250 dwarn:1 dfail:0 fail:0 skip:28 time:519s
fi-elk-e7500 total:279 pass:230 dwarn:0 dfail:0 fail:0 skip:49 time:440s
fi-glk-2a total:279 pass:260 dwarn:0 dfail:0 fail:0 skip:19 time:611s
fi-hsw-4770 total:279 pass:263 dwarn:0 dfail:0 fail:0 skip:16 time:451s
fi-hsw-4770r total:279 pass:263 dwarn:0 dfail:0 fail:0 skip:16 time:421s
fi-ilk-650 total:279 pass:229 dwarn:0 dfail:0 fail:0 skip:50 time:427s
fi-ivb-3520m total:279 pass:261 dwarn:0 dfail:0 fail:0 skip:18 time:512s
fi-ivb-3770 total:279 pass:261 dwarn:0 dfail:0 fail:0 skip:18 time:476s
fi-kbl-7260u total:279 pass:268 dwarn:1 dfail:0 fail:0 skip:10 time:499s
fi-kbl-7500u total:279 pass:261 dwarn:0 dfail:0 fail:0 skip:18 time:480s
fi-kbl-7560u total:279 pass:269 dwarn:0 dfail:0 fail:0 skip:10 time:597s
fi-kbl-r total:279 pass:261 dwarn:0 dfail:0 fail:0 skip:18 time:603s
fi-pnv-d510 total:279 pass:223 dwarn:1 dfail:0 fail:0 skip:55 time:528s
fi-skl-6260u total:279 pass:269 dwarn:0 dfail:0 fail:0 skip:10 time:472s
fi-skl-6700k total:279 pass:261 dwarn:0 dfail:0 fail:0 skip:18 time:484s
fi-skl-6770hq total:279 pass:269 dwarn:0 dfail:0 fail:0 skip:10 time:495s
fi-skl-gvtdvm total:279 pass:266 dwarn:0 dfail:0 fail:0 skip:13 time:454s
fi-skl-x1585l total:279 pass:268 dwarn:0 dfail:0 fail:0 skip:11 time:481s
fi-snb-2520m total:279 pass:251 dwarn:0 dfail:0 fail:0 skip:28 time:551s
fi-snb-2600 total:279 pass:249 dwarn:0 dfail:0 fail:1 skip:29 time:410s
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_78/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH i-g-t v2 0/3] Audio tests support for HDMI, with audio and ALSA helpers
2017-08-21 15:27 [PATCH i-g-t v2 0/3] Audio tests support for HDMI, with audio and ALSA helpers Paul Kocialkowski
` (3 preceding siblings ...)
2017-08-21 15:48 ` ✓ Fi.CI.BAT: success for Audio tests support for HDMI, with audio and ALSA helpers Patchwork
@ 2017-08-21 17:58 ` Lyude Paul
4 siblings, 0 replies; 6+ messages in thread
From: Lyude Paul @ 2017-08-21 17:58 UTC (permalink / raw)
To: Paul Kocialkowski, intel-gfx
R-B'd and pushed, thanks!
On Mon, 2017-08-21 at 18:27 +0300, Paul Kocialkowski wrote:
> Changes since v1:
> * Introduced explicit --enable-audio configure option
> * Added dependencies to README
> * Removed trailing whitespaces
> * Fixed alignment in sqrt call
> * Fixed ALSA overrun/underrun error handling and recovery
> * Fixed ALSA open/close sequence for more robust behavior
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2017-08-21 17:58 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-08-21 15:27 [PATCH i-g-t v2 0/3] Audio tests support for HDMI, with audio and ALSA helpers Paul Kocialkowski
2017-08-21 15:27 ` [PATCH i-g-t v2 1/3] lib: Add audio library with dedicated helpers Paul Kocialkowski
2017-08-21 15:27 ` [PATCH i-g-t v2 2/3] lib: Add ALSA " Paul Kocialkowski
2017-08-21 15:27 ` [PATCH i-g-t v2 3/3] tests: Introduce audio tests, starting with HDMI signal integrity Paul Kocialkowski
2017-08-21 15:48 ` ✓ Fi.CI.BAT: success for Audio tests support for HDMI, with audio and ALSA helpers Patchwork
2017-08-21 17:58 ` [PATCH i-g-t v2 0/3] " Lyude Paul
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox