Skip to contentSkip to conversation

tests/kms_chamelium: add dp-audio test

PATCH Superseded Simon Ser 3 participants 3 messages Apr 5, 2019 – Apr 8, 2019

Subsystems (2)

v1 of 7 Superseded Latest is v7 →

lore
Share & tools
lore

Simon Ser

author
#0 lore raw

PATCH 1/1 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).

---
 lib/igt.h                  |   1 +
 lib/igt_alsa.c             |  16 +-
 lib/igt_audio.c            | 285 +++++++++++++------
 lib/igt_audio.h            |  12 +-
 lib/igt_chamelium.c        | 101 +++++++
 lib/igt_chamelium.h        |  11 +
 lib/igt_chamelium_stream.c | 549 +++++++++++++++++++++++++++++++++++++
 lib/igt_chamelium_stream.h |  69 +++++
 lib/meson.build            |   1 +
 meson.build                |  50 ++--
 meson_options.txt          |   6 -
 tests/audio.c              | 193 -------------
 tests/kms_chamelium.c      | 280 ++++++++++++++++++-
 tests/meson.build          |   7 -
 14 files changed, 1246 insertions(+), 335 deletions(-)
 create mode 100644 lib/igt_chamelium_stream.c
 create mode 100644 lib/igt_chamelium_stream.h
 delete mode 100644 tests/audio.c
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 +12 -4
index bb6682cc..4427811f 100644
@@ -553,16 +553,20 @@ int alsa_run(struct alsa *alsa, int duration_ms)
 					if (ret < 0) {
 						ret = snd_pcm_recover(handle,
 								      ret, 0);
-						if (ret < 0)
+						if (ret < 0) {
+							igt_debug("snd_pcm_recover after snd_pcm_writei failed");
 							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)
+					if (ret < 0) {
+						igt_debug("snd_pcm_recover failed");
 						goto complete;
+					}
 				}
 			}
 
@@ -609,16 +613,20 @@ int alsa_run(struct alsa *alsa, int duration_ms)
 					ret = 0;
 				} else if (ret < 0) {
 					ret = snd_pcm_recover(handle, ret, 0);
-					if (ret < 0)
+					if (ret < 0) {
+						igt_debug("snd_pcm_recover after snd_pcm_readi failed");
 						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)
+				if (ret < 0) {
+					igt_debug("snd_pcm_recover failed");
 					goto complete;
+				}
 			}
 		}
 	} while (!reached);
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_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 +549 -0

549 lines not on this page · raw message

lib/igt_chamelium_stream.h new file +69 -0

69 lines not on this page · raw message

lib/meson.build +1 -0
index 89de06e6..e808dfe5 100644
@@ -103,6 +103,7 @@ endif
 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 +17 -33

87 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 +274 -6

328 lines not on this page · raw message

tests/meson.build +0 -7
index 5167a6cc..158ad395 100644
@@ -245,13 +245,6 @@ if _build_chamelium and chamelium.found()
 	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
#1 lore raw

[igt-dev] ✗ Fi.CI.BAT: failure for tests/kms_chamelium: add dp-audio test

== Series Details ==

== Series Details ==

Series: tests/kms_chamelium: add dp-audio test
URL : https://patchwork.freedesktop.org/series/59058/
State : failure

== Summary ==

IGT patchset build failed on latest successful build 019f892e5d1a0a9643cb726c47ce2d99c14b444f lib: ioctl_wrappers: reach engines by index as well

ninja: Entering directory `build'
[1/333] Generating version.h with a custom command.
[2/164] Linking target tests/kms_chamelium.
FAILED: tests/kms_chamelium
ccache cc -o tests/kms_chamelium 'tests/tests@@kms_chamelium@exe/kms_chamelium.c.o' -Wl,--no-undefined -Wl,--as-needed -Wl,--start-group lib/libigt.so /usr/lib/x86_64-linux-gnu/libcairo.so /usr/lib/x86_64-linux-gnu/libglib-2.0.so /opt/igt/lib/libdrm.so /usr/lib/x86_64-linux-gnu/libdw.so /usr/lib/x86_64-linux-gnu/libelf.so /usr/lib/x86_64-linux-gnu/libkmod.so /usr/lib/x86_64-linux-gnu/libprocps.so /lib/x86_64-linux-gnu/libudev.so -lm /usr/lib/x86_64-linux-gnu/libpciaccess.so /usr/lib/x86_64-linux-gnu/libpixman-1.so -lrt -lz /opt/igt/lib/libdrm_intel.so /usr/lib/x86_64-linux-gnu/libunwind.so /usr/lib/x86_64-linux-gnu/libgsl.so /usr/lib/x86_64-linux-gnu/libgslcblas.so -lm -L/usr/lib/x86_64-linux-gnu -lxmlrpc_client -lxmlrpc -lxmlrpc_xmlparse -lxmlrpc_xmltok -lxmlrpc_util -lcurl -lm /usr/lib/x86_64-linux-gnu/libdrm_nouveau.so -L/usr/lib/x86_64-linux-gnu -lxmlrpc_client -lxmlrpc -lxmlrpc_xmlparse -lxmlrpc_xmltok -lxmlrpc_util -lcurl -lm -Wl,--end-group -pthread '-Wl,-rpath,$ORIGIN/../lib:$ORIGIN/../../../../../opt/igt/lib' -Wl,-rpath-link,/home/cidrm/igt-gpu-tools/build/lib:/opt/igt/lib tests/tests@@kms_chamelium@exe/kms_chamelium.c.o: In function `do_test_display_audio':
/home/cidrm/igt-gpu-tools/build/../tests/kms_chamelium.c:778: undefined reference to `alsa_test_output_configuration'
/home/cidrm/igt-gpu-tools/build/../tests/kms_chamelium.c:783: undefined reference to `alsa_configure_output'
/home/cidrm/igt-gpu-tools/build/../tests/kms_chamelium.c:814: undefined reference to `alsa_register_output_callback'
/home/cidrm/igt-gpu-tools/build/../tests/kms_chamelium.c:818: undefined reference to `alsa_run'
/home/cidrm/igt-gpu-tools/build/../tests/kms_chamelium.c:821: undefined reference to `alsa_close_output'
tests/tests@@kms_chamelium@exe/kms_chamelium.c.o: In function `test_display_audio':
/home/cidrm/igt-gpu-tools/build/../tests/kms_chamelium.c:923: undefined reference to `alsa_init'
/home/cidrm/igt-gpu-tools/build/../tests/kms_chamelium.c:954: undefined reference to `alsa_open_output'
/home/cidrm/igt-gpu-tools/build/../tests/kms_chamelium.c:962: undefined reference to `alsa_close_output'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev

#2 lore raw
In reply to Simon Ser
Quoted 7 lines · Simon Ser

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.

FWIW, I didn't look at the patch, but this sounds awesome! \o/

BR,
Jani.

Signature · 5 lines
Jani Nikula, Intel Open Source Graphics Center
_______________________________________________
igt-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/igt-dev