Skip to contentSkip to conversation

tests/kms_chamelium: add dp-audio test

PATCH Superseded Simon Ser 1 participant 6 messages Apr 11, 2019

Subsystems (2)

v3 of 7 Superseded Latest is v7 →

lore
Share & tools
lore

Simon Ser

author
#0 lore raw

v3 cover tests/kms_chamelium: add dp-audio test

The first patch hasn't changed since v2. I've added 3 more patches to implement more features in the audio test.

Simon Ser (4):
tests/kms_chamelium: add dp-audio test tests/kms_chamelium: capture audio data in real-time tests/kms_chamelium: test we receive a signal from both audio channels tests/kms_chamelium: test audio channels are not mixed up

 docs/audio.txt             |  45 ---
 docs/chamelium.txt         |  32 +-
 lib/igt.h                  |   1 +
 lib/igt_alsa.c             |  83 +++++-
 lib/igt_alsa.h             |   1 +
 lib/igt_audio.c            | 406 +++++++++++++++++--------
 lib/igt_audio.h            |  19 +-
 lib/igt_aux.c              |  31 ++
 lib/igt_aux.h              |   1 +
 lib/igt_chamelium.c        | 135 +++++++++
 lib/igt_chamelium.h        |  14 +
 lib/igt_chamelium_stream.c | 592 +++++++++++++++++++++++++++++++++++++
 lib/igt_chamelium_stream.h |  52 ++++
 lib/meson.build            |   5 +-
 meson.build                |  52 ++--
 meson_options.txt          |   6 -
 tests/audio.c              | 193 ------------
 tests/kms_chamelium.c      | 340 ++++++++++++++++++++-
 tests/meson.build          |   9 +-
 19 files changed, 1567 insertions(+), 450 deletions(-)
 delete mode 100644 docs/audio.txt
 create mode 100644 lib/igt_chamelium_stream.c
 create mode 100644 lib/igt_chamelium_stream.h
 delete mode 100644 tests/audio.c
Signature · 6 lines
2.21.0

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev
author
#1 lore raw

PATCH v3 1/4 tests/kms_chamelium: add dp-audio test

This new test ensures DisplayPort audio works by using the Chamelium.

It enables the DisplayPort output and sends an audio signal containing a set of frequencies we choose to all HDMI/DisplayPort audio devices. It starts recording audio on the Chamelium device and uses the stream server to retrieve captured audio pages. It then checks that the capture audio signal contains the frequencies we sent, and only those, by computing a FFT.

A new library has been added to libigt to communicate with the stream server. It implements a simple custom TCP protocol.

In case the test fails, a WAV file with the captured data is saved on disk.

Right now the test has a few limitations:

- Only the first channel is checked
- IGT only generates audio with a single sampling rate (48 KHz)
- Audio data is not captured in real-time

These limitations will be lifted in future patches.

PulseAudio must not run during the tests since ALSA is used directly. To ensure this, edit /etc/pulse/client.conf and add autospawn=no. Then run pulseaudio --kill.

This commit deletes the existing audio tests. They weren't run and required an exotic configuration (HDMI audio splitter, dummy HDMI sink and a line-in port on the DUT).

---
 docs/audio.txt             |  45 ---
 docs/chamelium.txt         |  32 +-
 lib/igt.h                  |   1 +
 lib/igt_alsa.c             |  42 ++-
 lib/igt_alsa.h             |   1 +
 lib/igt_audio.c            | 285 ++++++++++++------
 lib/igt_audio.h            |  12 +-
 lib/igt_aux.c              |  31 ++
 lib/igt_aux.h              |   1 +
 lib/igt_chamelium.c        | 101 +++++++
 lib/igt_chamelium.h        |  11 +
 lib/igt_chamelium_stream.c | 592 +++++++++++++++++++++++++++++++++++++
 lib/igt_chamelium_stream.h |  52 ++++
 lib/meson.build            |   5 +-
 meson.build                |  52 ++--
 meson_options.txt          |   6 -
 tests/audio.c              | 193 ------------
 tests/kms_chamelium.c      | 276 ++++++++++++++++-
 tests/meson.build          |   9 +-
 19 files changed, 1358 insertions(+), 389 deletions(-)
 delete mode 100644 docs/audio.txt
 create mode 100644 lib/igt_chamelium_stream.c
 create mode 100644 lib/igt_chamelium_stream.h
 delete mode 100644 tests/audio.c
docs/audio.txt deleted +0 -45
deleted file mode 100644
index 158ad5d1..00000000
@@ -1,45 +0,0 @@
-Audio Support in IGT
-====================
-
-This document provides information and instructions about audio support in IGT.
-
-Introduction
-------------
-
-The audio test is aimed at testing the audio features of display connectors,
-such as HDMI.
-
-Test setup
-----------
-
-The setup required for the audio test consists of using an HDMI-VGA adapter with
-an audio-out 3.5 mm jack to extract the audio from the HDMI interface.
-The audio-out jack is connected back to the device-under-test's line-in.
-
-Depending on the behavior of the adapter, it may be necessary to connect a
-ghost VGA dongle to it (in order to emulate a connected display) to enable the
-audio output. There are guides available detailing how to build these.
-
-When executed, the test will automatically send the test audio signal to all
-ALSA audio HDMI outputs and record from the standard ALSA capture device.
-
-Configuration
--------------
-
-In order to deploy the test, ALSA controls have to be configured to set the
-ALSA capture source to line-in. On Intel x86 systems, this can be achieved
-with the following calls to the amixer utility:
-# amixer sset Line 31 on
-# amixer sset "Input Source" Line
-
-It is then useful to store the ALSA state permanently with the alsactl utility:
-# alsactl store
-
-These settings can be restored with the alsactl utility:
-# alsactl restore
-
-It is desirable to ensure that the alsa-restore and alsa-state systemd services
-are enabled to do this job automatically, especially in the case of an
-automated testing system:
-# systemctl enable alsa-restore
-# systemctl enable alsa-state
docs/chamelium.txt +26 -6
index 0cabcdc6..316dd607 100644
@@ -139,6 +139,23 @@ $ make remote-install CHAMELEON_HOST=192.168.72.1
 
 The process requires the Chamelium to be connected to the Internet to succeed.
 
+Audio Capture
+-------------
+
+The Chamelium supports audio capture. IGT tests take advantage of the
+Chamelium streaming server to download audio samples from the Chamelium.
+
+IGT needs direct access to audio devices through ALSA, so PulseAudio needs to
+be stopped (otherwise audio tests will automatically get skipped). To make sure
+PulseAudio isn't running:
+
+- Edit /etc/pulse/client.conf and add autospawn=no
+- Run `pulseaudio --kill` (if it succeeds, it means PulseAudio was running)
+- Make sure a DE that automatically spawns PulseAudio isn't running
+
+In case a test fails, the raw captured audio files will be dumped in a WAV
+file.
+
 Contributing Changes to the Daemon
 ----------------------------------
 
@@ -146,10 +163,11 @@ Contributions to the Chamelium daemon, just like any contribution to ChromiumOS,
 are submitted and reviewed at: https://chromium-review.googlesource.com/
 
 The ChromiumOS project provides an extensive developer guide:
-https://www.chromium.org/chromium-os/developer-guide that assumes running within
-the ChromiumOS build system. Since this is likely not the case for contributing
-to the Chamelium daemon, only the part about uploading changes is relevant:
-https://www.chromium.org/chromium-os/developer-guide#TOC-Upload-your-changes-and-get-a-code-review
+https://chromium.googlesource.com/chromiumos/docs/+/master/developer_guide.md
+It that assumes running within the ChromiumOS build system. Since this is
+likely not the case for contributing to the Chamelium daemon, only the part
+about uploading changes is relevant:
+https://chromium.googlesource.com/chromiumos/docs/+/master/developer_guide.md#Upload-your-changes-and-get-a-code-review
 
 Most of the process is about using the Gerrit web interface for submitting and
 having the change reviewed and not forgetting the Change-Id, TEST= and BUG=
@@ -162,7 +180,7 @@ Support for the Chamelium platform in IGT is found in the following places:
 * lib/igt_chamelium.c: library with Chamelium-related helpers
 * tests/kms_chamelium.c: sub-tests using the Chamelium
 
-As of late August 2017, the following features are tested by IGT:
+As of early April 2019, the following features are tested by IGT:
 * Pixel-by-pixel frame integrity tests for DP and HDMI
 * Error-trend-based frame integrity tests for VGA
 * CRC-based frame integrity tests for DP and HDMI
@@ -173,6 +191,7 @@ As of late August 2017, the following features are tested by IGT:
   each interface or combined
 * EDID display identifier integrity check for all interfaces
 * EDID display identifier change during suspend for all interfaces
+* Audio Fourier-based tests for DP at 48KHz
 
 Future Developments
 -------------------
@@ -180,7 +199,8 @@ Future Developments
 With the current generation of the hardware platform, support for testing a
 number of additional display features could be included as future developments,
 including:
-* Audio capture from HDMI and DP
+* Audio capture from HDMI, with multiple channels and with other playback
+  sampling rates
 * High-bandwidth Digital Content Protection (HDCP) streaming to the display
 * Remote control forwarding (CEC) sent from the display
 * YUV colorspace for HDMI, instead of RGB
lib/igt.h +1 -0
index 6654a659..5852d557 100644
@@ -43,6 +43,7 @@
 #include "igt_stats.h"
 #ifdef HAVE_CHAMELIUM
 #include "igt_chamelium.h"
+#include "igt_chamelium_stream.h"
 #endif
 #include "instdone.h"
 #include "intel_batchbuffer.h"
lib/igt_alsa.c +38 -4

91 lines not on this page · raw message

lib/igt_alsa.h +1 -0
index 50795130..5c804b46 100644
@@ -33,6 +33,7 @@
 
 struct alsa;
 
+bool alsa_has_exclusive_access(void);
 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);
lib/igt_audio.c +202 -83

340 lines not on this page · raw message

lib/igt_audio.h +9 -3
index b3b658a4..4aa43e69 100644
@@ -30,6 +30,7 @@
 #include "config.h"
 
 #include <stdbool.h>
+#include <stdint.h>
 
 struct audio_signal;
 
@@ -37,8 +38,13 @@ 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);
+void audio_signal_fill(struct audio_signal *signal, int16_t *buffer, int frames);
+bool audio_signal_detect(struct audio_signal *signal, int sampling_rate,
+			 double *data, size_t data_len);
+size_t audio_extract_channel_s32_le(double *dst, size_t dst_cap,
+				    int32_t *src, size_t src_len,
+				    int n_channels, int channel);
+int audio_create_wav_file_s32_le(const char *qualifier, uint32_t sample_rate,
+				 uint16_t channels, char **path);
 
 #endif
lib/igt_aux.c +31 -0
index 05528352..95ceb845 100644
@@ -1259,6 +1259,37 @@ void igt_set_module_param_int(const char *name, int val)
 	igt_set_module_param(name, str);
 }
 
+/**
+ * igt_is_process_running:
+ * @comm: Name of process in the form found in /proc/pid/comm (limited to 15
+ * chars)
+ *
+ * Returns: true in case the process has been found, false otherwise.
+ *
+ * This function checks in the process table for an entry with the name @comm.
+ */
+int igt_is_process_running(const char *comm)
+{
+	PROCTAB *proc;
+	proc_t *proc_info;
+	bool found = false;
+
+	proc = openproc(PROC_FILLCOM | PROC_FILLSTAT | PROC_FILLARG);
+	igt_assert(proc != NULL);
+
+	while ((proc_info = readproc(proc, NULL))) {
+		if (!strncasecmp(proc_info->cmd, comm, sizeof(proc_info->cmd))) {
+			freeproc(proc_info);
+			found = true;
+			break;
+		}
+		freeproc(proc_info);
+	}
+
+	closeproc(proc);
+	return found;
+}
+
 /**
  * igt_terminate_process:
  * @sig: Signal to send
lib/igt_aux.h +1 -0
index 55392790..dbd88b67 100644
@@ -279,6 +279,7 @@ bool igt_allow_unlimited_files(void);
 void igt_set_module_param(const char *name, const char *val);
 void igt_set_module_param_int(const char *name, int val);
 
+int igt_is_process_running(const char *comm);
 int igt_terminate_process(int sig, const char *comm);
 void igt_lsof(const char *dpath);
 
lib/igt_chamelium.c +101 -0

113 lines not on this page · raw message

lib/igt_chamelium.h +11 -0
index 233ead85..047f8c5d 100644
@@ -53,6 +53,12 @@ enum chamelium_check {
 	CHAMELIUM_CHECK_CRC,
 };
 
+struct chamelium_audio_file {
+	char *path;
+	int rate; /* Hz */
+	int channels;
+};
+
 struct chamelium *chamelium_init(int drm_fd);
 void chamelium_deinit(struct chamelium *chamelium);
 void chamelium_reset(struct chamelium *chamelium);
@@ -100,6 +106,10 @@ void chamelium_start_capture(struct chamelium *chamelium,
 void chamelium_stop_capture(struct chamelium *chamelium, int frame_count);
 void chamelium_capture(struct chamelium *chamelium, struct chamelium_port *port,
 		       int x, int y, int w, int h, int frame_count);
+void chamelium_start_capturing_audio(struct chamelium *chamelium,
+				    struct chamelium_port *port, bool save_to_file);
+struct chamelium_audio_file *chamelium_stop_capturing_audio(struct chamelium *chamelium,
+							    struct chamelium_port *port);
 igt_crc_t *chamelium_read_captured_crcs(struct chamelium *chamelium,
 					int *frame_count);
 struct chamelium_frame_dump *chamelium_read_captured_frame(struct chamelium *chamelium,
@@ -131,5 +141,6 @@ void chamelium_assert_frame_match_or_dump(struct chamelium *chamelium,
 void chamelium_crop_analog_frame(struct chamelium_frame_dump *dump, int width,
 				 int height);
 void chamelium_destroy_frame_dump(struct chamelium_frame_dump *dump);
+void chamelium_destroy_audio_file(struct chamelium_audio_file *audio_file);
 
 #endif /* IGT_CHAMELIUM_H */
lib/igt_chamelium_stream.c new file +592 -0

592 lines not on this page · raw message

lib/igt_chamelium_stream.h new file +52 -0

52 lines not on this page · raw message

lib/meson.build +3 -2
index a8462933..eead0afb 100644
@@ -92,7 +92,7 @@ if valgrind.found()
 endif
 
 if gsl.found()
-	lib_deps += [ gsl ]
+	lib_deps += gsl
 	lib_sources += [ 'igt_frame.c', 'igt_audio.c' ]
 endif
 
@@ -101,9 +101,10 @@ if alsa.found()
 	lib_sources += 'igt_alsa.c'
 endif
 
-if chamelium.found()
+if chamelium_found
 	lib_deps += chamelium
 	lib_sources += 'igt_chamelium.c'
+	lib_sources += 'igt_chamelium_stream.c'
 endif
 
 srcdir = join_paths(meson.source_root(), 'tests')
meson.build +19 -33

89 lines not on this page · raw message

meson_options.txt +0 -6
index 0cd3b350..888efe56 100644
@@ -10,12 +10,6 @@ option('overlay_backends',
        choices : [ 'auto', 'x', 'xv' ],
        description : 'Overlay backends to enable')
 
-option('build_audio',
-       type : 'combo',
-       value : 'auto',
-       choices : ['auto', 'true', 'false'],
-       description : 'Build audio test')
-
 option('build_chamelium',
        type : 'combo',
        value : 'auto',
tests/audio.c deleted +0 -193

193 lines not on this page · raw message

tests/kms_chamelium.c +270 -6

324 lines not on this page · raw message

tests/meson.build +1 -8
index 5167a6cc..5d3eed82 100644
@@ -238,20 +238,13 @@ if libdrm_nouveau.found()
 	test_deps += libdrm_nouveau
 endif
 
-if _build_chamelium and chamelium.found()
+if chamelium_found
 	test_progs += [
 		'kms_chamelium',
 	]
 	test_deps += chamelium
 endif
 
-if _build_audio and alsa.found() and gsl.found()
-	test_progs += [
-		'audio',
-	]
-	test_deps += alsa
-endif
-
 test_executables = []
 test_list = []
 
Signature · 6 lines
2.21.0

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev
author
#2 lore raw

PATCH v3 2/4 tests/kms_chamelium: capture audio data in real-time

In reply to Simon Ser

From: Simon Ser <[email protected]>

Before this patch, the audio test first sends an audio signal for 2s, and then checks whether the captured signal matches.

This patch makes it so we send and check the signal in parallel. Thus we can stop the test as soon as we receive the correct signal. This saves ~2s per audio test.

---
 lib/igt_alsa.c        | 15 +++++++-------
 tests/kms_chamelium.c | 47 +++++++++++++++++++++++++++++++++----------
 2 files changed, 43 insertions(+), 19 deletions(-)
lib/igt_alsa.c +7 -8
index 456c0c85..cc34e3d1 100644
@@ -497,7 +497,8 @@ void alsa_register_input_callback(struct alsa *alsa,
 /**
  * alsa_run:
  * @alsa: The target alsa structure
- * @duration_ms: The maximum duration of the run in milliseconds
+ * @duration_ms: The maximum duration of the run in milliseconds, or -1 for an
+ * infinite duration.
  *
  * Run ALSA playback and capture on the input and output devices for at
  * most @duration_ms milliseconds, calling the registered callbacks when needed.
@@ -545,7 +546,7 @@ int alsa_run(struct alsa *alsa, int duration_ms)
 	do {
 		reached = true;
 
-		if (output_total < output_limit) {
+		if (output_limit < 0 || output_total < output_limit) {
 			reached = false;
 
 			if (!output_ready) {
@@ -607,7 +608,8 @@ int alsa_run(struct alsa *alsa, int duration_ms)
 
 		}
 
-		if (alsa->input_callback && input_total < input_limit) {
+		if (alsa->input_callback &&
+		    (input_limit < 0 || input_total < input_limit)) {
 			reached = false;
 
 			if (input_count == input_trigger) {
@@ -660,11 +662,8 @@ int alsa_run(struct alsa *alsa, int duration_ms)
 	ret = 0;
 
 complete:
-	if (output_buffer)
-		free(output_buffer);
-
-	if (input_buffer)
-		free(input_buffer);
+	free(output_buffer);
+	free(input_buffer);
 
 	return ret;
 }
tests/kms_chamelium.c +36 -11

98 lines not on this page · raw message

Signature · 6 lines
2.21.0

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev
author
#3 lore raw

PATCH v3 3/4 tests/kms_chamelium: test we receive a signal from both audio channels

In reply to Simon Ser

From: Simon Ser <[email protected]>

This commit updates the audio test to make sure we receive a signal from both audio channels. However this commit doesn't check that left and right channels are not swapped. Such a check requires some more work (because the Chamelium device does swap left and right channels) and will be implemented in a future commit.

This commit adds a new channel argument to audio_signal_add_frequency, to add a frequency to a single channel only.

Some light refactoring has been performed (a proper audio_signal_deinit function has been introduced) and logging has been improved.

---
 lib/igt_alsa.c        |  26 +++++++--
 lib/igt_audio.c       | 121 +++++++++++++++++++++++++-----------------
 lib/igt_audio.h       |  11 ++--
 tests/kms_chamelium.c |  56 +++++++++++--------
 4 files changed, 138 insertions(+), 76 deletions(-)
lib/igt_alsa.c +23 -3
index cc34e3d1..e1848301 100644
@@ -182,6 +182,8 @@ static char *alsa_resolve_indentifier(const char *device_name, int skip)
 					continue;
 				}
 
+				igt_debug("Matched device \"%s\"\n", pcm_name);
+
 				snprintf(name, sizeof(name), "hw:%d,%d", card,
 					 dev);
 
@@ -329,6 +331,9 @@ static bool alsa_test_configuration(snd_pcm_t *handle, int channels,
 {
 	snd_pcm_hw_params_t *params;
 	int ret;
+	unsigned int min_channels, max_channels;
+	unsigned int min_rate, max_rate;
+	int min_rate_dir, max_rate_dir;
 
 	snd_pcm_hw_params_alloca(&params);
 
@@ -337,12 +342,24 @@ static bool alsa_test_configuration(snd_pcm_t *handle, int channels,
 		return false;
 
 	ret = snd_pcm_hw_params_test_rate(handle, params, sampling_rate, 0);
-	if (ret < 0)
+	if (ret < 0) {
+		snd_pcm_hw_params_get_rate_min(params, &min_rate, &min_rate_dir);
+		snd_pcm_hw_params_get_rate_max(params, &max_rate, &max_rate_dir);
+		igt_debug("Output device supports rates between %u and %u, "
+			  "requested %d\n",
+			  min_rate, max_rate, sampling_rate);
 		return false;
+	}
 
 	ret = snd_pcm_hw_params_test_channels(handle, params, channels);
-	if (ret < 0)
+	if (ret < 0) {
+		snd_pcm_hw_params_get_channels_min(params, &min_channels);
+		snd_pcm_hw_params_get_channels_max(params, &max_channels);
+		igt_debug("Output device supports between %u and "
+			  "%u channels, requested %d\n",
+			  min_channels, max_channels, channels);
 		return false;
+	}
 
 	return true;
 }
@@ -409,13 +426,16 @@ void alsa_configure_output(struct alsa *alsa, int channels,
 	snd_pcm_t *handle;
 	int ret;
 	int i;
+	int soft_resample = 0; /* Don't allow ALSA to resample */
+	unsigned int latency = 0;
 
 	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);
+					 channels, sampling_rate,
+					 soft_resample, latency);
 		igt_assert(ret >= 0);
 	}
 
lib/igt_audio.c +73 -48

248 lines not on this page · raw message

lib/igt_audio.h +7 -4
index 4aa43e69..fe26bb57 100644
@@ -35,12 +35,15 @@
 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_deinit(struct audio_signal *signal);
+int audio_signal_add_frequency(struct audio_signal *signal, int frequency,
+			       int channel);
 void audio_signal_synthesize(struct audio_signal *signal);
-void audio_signal_clean(struct audio_signal *signal);
-void audio_signal_fill(struct audio_signal *signal, int16_t *buffer, int frames);
+void audio_signal_reset(struct audio_signal *signal);
+void audio_signal_fill(struct audio_signal *signal, int16_t *buffer,
+		       size_t buffer_len);
 bool audio_signal_detect(struct audio_signal *signal, int sampling_rate,
-			 double *data, size_t data_len);
+			 int channel, double *data, size_t data_len);
 size_t audio_extract_channel_s32_le(double *dst, size_t dst_cap,
 				    int32_t *src, size_t src_len,
 				    int n_channels, int channel);
tests/kms_chamelium.c +35 -21

112 lines not on this page · raw message

Signature · 6 lines
2.21.0

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev
author
#4 lore raw

PATCH v3 4/4 tests/kms_chamelium: test audio channels are not mixed up

In reply to Simon Ser

From: Simon Ser <[email protected]>

Send a different signal to each channel and make sure captured audio channels are not swapped or mixed up.

The Chamelium device has a bug and already swaps the left and right channels. For this reason, clients need to retrieve the Chamelium channel mapping and accomodate for this. See https://crbug.com/950922 for a discussion about this.

---
 lib/igt_chamelium.c   | 34 ++++++++++++++++++++++++++++++++++
 lib/igt_chamelium.h   |  3 +++
 tests/kms_chamelium.c | 37 +++++++++++++++++++++++++++++++------
 3 files changed, 68 insertions(+), 6 deletions(-)
lib/igt_chamelium.c +34 -0
index 7c9030d1..6ac7b722 100644
@@ -930,6 +930,40 @@ int chamelium_get_captured_frame_count(struct chamelium *chamelium)
 	return ret;
 }
 
+/**
+ * chamelium_get_audio_channel_mapping:
+ * @chamelium: the Chamelium instance
+ * @port: the audio port
+ * @mapping: will be filled with the channel mapping
+ *
+ * Obtains the channel mapping for an audio port.
+ *
+ * Audio channels are not guaranteed not to be swapped. Users can use the
+ * channel mapping to match an input channel to a capture channel.
+ *
+ * The mapping contains one element per capture channel. Each element indicates
+ * which input channel the capture channel is mapped to. As a special case, -1
+ * means that the channel isn't mapped.
+ */
+void chamelium_get_audio_channel_mapping(struct chamelium *chamelium,
+					 struct chamelium_port *port,
+					 int mapping[static 8])
+{
+	xmlrpc_value *res, *res_channel;
+	int res_len, i;
+
+	res = chamelium_rpc(chamelium, port, "GetAudioChannelMapping", "(i)",
+			    port->id);
+	res_len = xmlrpc_array_size(&chamelium->env, res);
+	igt_assert(res_len == 8);
+	for (i = 0; i < res_len; i++) {
+		xmlrpc_array_read_item(&chamelium->env, res, i, &res_channel);
+		xmlrpc_read_int(&chamelium->env, res_channel, &mapping[i]);
+		xmlrpc_DECREF(res_channel);
+	}
+	xmlrpc_DECREF(res);
+}
+
 /**
  * chamelium_start_capturing_audio:
  * @chamelium: the Chamelium instance
lib/igt_chamelium.h +3 -0
index 047f8c5d..728d16ea 100644
@@ -106,6 +106,9 @@ void chamelium_start_capture(struct chamelium *chamelium,
 void chamelium_stop_capture(struct chamelium *chamelium, int frame_count);
 void chamelium_capture(struct chamelium *chamelium, struct chamelium_port *port,
 		       int x, int y, int w, int h, int frame_count);
+void chamelium_get_audio_channel_mapping(struct chamelium *chamelium,
+					 struct chamelium_port *port,
+					 int mapping[static 8]);
 void chamelium_start_capturing_audio(struct chamelium *chamelium,
 				    struct chamelium_port *port, bool save_to_file);
 struct chamelium_audio_file *chamelium_stop_capturing_audio(struct chamelium *chamelium,
tests/kms_chamelium.c +31 -6
index 12ab9997..3e4f7473 100644
@@ -777,7 +777,7 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 		      struct alsa *alsa, int playback_channels,
 		      int playback_rate)
 {
-	int ret, capture_rate, capture_channels, msec, freq;
+	int ret, capture_rate, capture_channels, msec, freq, step;
 	struct chamelium_audio_file *audio_file;
 	struct chamelium_stream *stream;
 	enum chamelium_stream_realtime_mode stream_mode;
@@ -792,16 +792,17 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	int dump_fd = -1;
 	pthread_t thread;
 	struct audio_state state = {};
+	int channel_mapping[8], capture_chan;
 
 	if (!alsa_test_output_configuration(alsa, playback_channels,
 					    playback_rate)) {
-		igt_debug("Skipping test with sample rate %d and %d channels "
+		igt_debug("Skipping test with sample rate %d Hz and %d channels "
 			  "because selected output devices don't support this "
 			  "configuration\n", playback_rate, playback_channels);
 		return false;
 	}
 
-	igt_debug("Testing with playback sampling rate %d and %d channels\n",
+	igt_debug("Testing with playback sampling rate %d Hz and %d channels\n",
 		  playback_rate, playback_channels);
 	alsa_configure_output(alsa, playback_channels, playback_rate);
 
@@ -830,9 +831,15 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	signal = audio_signal_init(playback_channels, playback_rate);
 	igt_assert(signal);
 
+	/* We'll choose different frequencies per channel to make sure they are
+	 * independent from each other. To do so, we'll add a different offset
+	 * to the base frequencies for each channel. We need to choose a big
+	 * enough offset so that we're sure to detect mixed up channels.
+	 */
+	step = 2 * capture_rate / CAPTURE_SAMPLES;
 	for (i = 0; i < test_frequencies_count; i++) {
 		for (j = 0; j < playback_channels; j++) {
-			freq = test_frequencies[i];
+			freq = test_frequencies[i] + j * step;
 			audio_signal_add_frequency(signal, freq, j);
 		}
 	}
@@ -847,6 +854,20 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 	ret = pthread_create(&thread, NULL, run_audio_thread, alsa);
 	igt_assert(ret == 0);
 
+	chamelium_get_audio_channel_mapping(data->chamelium, port,
+					    channel_mapping);
+	/* Make sure we can capture all channels we send. */
+	for (i = 0; i < playback_channels; i++) {
+		ok = false;
+		for (j = 0; j < capture_channels; j++) {
+			if (channel_mapping[j] == i) {
+				ok = true;
+				break;
+			}
+		}
+		igt_assert(ok);
+	}
+
 	/* Needs to be a multiple of 128, because that's the number of samples
 	 * we get per channel each time we receive an audio page from the
 	 * Chamelium device. */
@@ -886,11 +907,15 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 		igt_debug("Detecting audio signal, t=%d msec\n", msec);
 
 		for (j = 0; j < playback_channels; j++) {
-			igt_debug("Processing channel %zu\n", j);
+			capture_chan = channel_mapping[j];
+			igt_assert(capture_chan >= 0);
+			igt_debug("Processing channel %zu (captured as "
+				  "channel %d)\n", j, capture_chan);
 
 			audio_extract_channel_s32_le(channel, channel_len,
 						     buf, buf_len,
-						     capture_channels, j);
+						     capture_channels,
+						     capture_chan);
 
 			if (audio_signal_detect(signal, capture_rate, j,
 						channel, channel_len))
Signature · 6 lines
2.21.0

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev
author
#5 lore raw
In reply to Simon Ser
Quoted 2 lines · Simon Ser

The first patch hasn't changed since v2. I've added 3 more patches to implement more features in the audio test.

Gah, I successfully managed to mess up the author of the 3 new patches. Sorry about that. This is fixed locally so the next version won't have this issue. I'll wait for feedback before sending v4.
_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev