[igt-dev] [PATCH i-g-t 1/5] lib/igt_alsa: support all alsa formats

Simon Ser simon.ser at intel.com
Fri May 17 16:02:38 UTC 2019


This commit adds a new format argument to alsa_configure_output. This allows
the caller to decide the format used for the audio signal.

This removes the assumption that samples are S16_LE items in igt_alsa. The
alsa function snd_pcm_format_physical_width is used instead of sizeof(short).
This also removes the theorically incorrect assumption that sizeof(short) ==
sizeof(int16_t).

Right now S16_LE is hardcoded in the test. Tests with other formats will be
added in future commits.

Signed-off-by: Simon Ser <simon.ser at intel.com>
---
 lib/igt_alsa.c        | 23 +++++++++++++----------
 lib/igt_alsa.h        |  7 ++++---
 tests/kms_chamelium.c |  7 ++++---
 3 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/lib/igt_alsa.c b/lib/igt_alsa.c
index 28a866e0ee74..2dfb8ccd3ad9 100644
--- a/lib/igt_alsa.c
+++ b/lib/igt_alsa.c
@@ -27,7 +27,6 @@
 #include "config.h"
 
 #include <limits.h>
-#include <alsa/asoundlib.h>
 
 #include "igt_alsa.h"
 #include "igt_aux.h"
@@ -47,10 +46,11 @@
 struct alsa {
 	snd_pcm_t *output_handles[HANDLES_MAX];
 	int output_handles_count;
+	snd_pcm_format_t output_format;
 	int output_sampling_rate;
 	int output_channels;
 
-	int (*output_callback)(void *data, short *buffer, int samples);
+	int (*output_callback)(void *data, void *buffer, int samples);
 	void *output_callback_data;
 	int output_samples_trigger;
 };
@@ -342,8 +342,8 @@ bool alsa_test_output_configuration(struct alsa *alsa, int channels,
  * 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)
+void alsa_configure_output(struct alsa *alsa, snd_pcm_format_t fmt,
+			   int channels, int sampling_rate)
 {
 	snd_pcm_t *handle;
 	int ret;
@@ -354,13 +354,14 @@ void alsa_configure_output(struct alsa *alsa, int channels,
 	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,
+		ret = snd_pcm_set_params(handle, fmt,
 					 SND_PCM_ACCESS_RW_INTERLEAVED,
 					 channels, sampling_rate,
 					 soft_resample, latency);
 		igt_assert(ret >= 0);
 	}
 
+	alsa->output_format = fmt;
 	alsa->output_channels = channels;
 	alsa->output_sampling_rate = sampling_rate;
 }
@@ -379,7 +380,7 @@ void alsa_configure_output(struct alsa *alsa, int channels,
  * for failure.
  */
 void alsa_register_output_callback(struct alsa *alsa,
-				   int (*callback)(void *data, short *buffer, int samples),
+				   int (*callback)(void *data, void *buffer, int samples),
 				   void *callback_data, int samples_trigger)
 {
 	alsa->output_callback = callback;
@@ -402,12 +403,13 @@ void alsa_register_output_callback(struct alsa *alsa,
 int alsa_run(struct alsa *alsa, int duration_ms)
 {
 	snd_pcm_t *handle;
-	short *output_buffer = NULL;
+	char *output_buffer = NULL;
 	int output_limit;
 	int output_total = 0;
 	int output_counts[alsa->output_handles_count];
 	bool output_ready = false;
 	int output_channels;
+	int bytes_per_sample;
 	int output_trigger;
 	bool reached;
 	int index;
@@ -418,9 +420,10 @@ int alsa_run(struct alsa *alsa, int duration_ms)
 
 	output_limit = alsa->output_sampling_rate * duration_ms / 1000;
 	output_channels = alsa->output_channels;
+	bytes_per_sample = snd_pcm_format_physical_width(alsa->output_format) / 8;
 	output_trigger = alsa->output_samples_trigger;
-	output_buffer = malloc(sizeof(short) * output_channels *
-			       output_trigger);
+	output_buffer = malloc(output_channels * output_trigger *
+			       bytes_per_sample);
 
 	do {
 		reached = true;
@@ -454,7 +457,7 @@ int alsa_run(struct alsa *alsa, int duration_ms)
 					count = avail < count ? avail : count;
 
 					ret = snd_pcm_writei(handle,
-							     &output_buffer[index],
+							     &output_buffer[index * bytes_per_sample],
 							     count);
 					if (ret < 0) {
 						ret = snd_pcm_recover(handle,
diff --git a/lib/igt_alsa.h b/lib/igt_alsa.h
index a10985ff777f..46b3568d26fd 100644
--- a/lib/igt_alsa.h
+++ b/lib/igt_alsa.h
@@ -29,6 +29,7 @@
 
 #include "config.h"
 
+#include <alsa/asoundlib.h>
 #include <stdbool.h>
 
 struct alsa;
@@ -39,10 +40,10 @@ int alsa_open_output(struct alsa *alsa, const char *device_name);
 void alsa_close_output(struct alsa *alsa);
 bool alsa_test_output_configuration(struct alsa *alsa, int channels,
 				    int sampling_rate);
-void alsa_configure_output(struct alsa *alsa, int channels,
-			   int sampling_rate);
+void alsa_configure_output(struct alsa *alsa, snd_pcm_format_t fmt,
+			   int channels, int sampling_rate);
 void alsa_register_output_callback(struct alsa *alsa,
-				   int (*callback)(void *data, short *buffer, int samples),
+				   int (*callback)(void *data, void *buffer, int samples),
 				   void *callback_data, int samples_trigger);
 int alsa_run(struct alsa *alsa, int duration_ms);
 
diff --git a/tests/kms_chamelium.c b/tests/kms_chamelium.c
index c8b6b22d7b4a..2b465565418d 100644
--- a/tests/kms_chamelium.c
+++ b/tests/kms_chamelium.c
@@ -801,11 +801,11 @@ struct audio_state {
 };
 
 static int
-audio_output_callback(void *data, short *buffer, int frames)
+audio_output_callback(void *data, void *buffer, int samples)
 {
 	struct audio_state *state = data;
 
-	audio_signal_fill_s16_le(state->signal, buffer, frames);
+	audio_signal_fill_s16_le(state->signal, buffer, samples);
 
 	return state->run ? 0 : -1;
 }
@@ -843,7 +843,8 @@ do_test_display_audio(data_t *data, struct chamelium_port *port,
 
 	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);
+	alsa_configure_output(alsa, SND_PCM_FORMAT_S16_LE,
+			      playback_channels, playback_rate);
 
 	chamelium_start_capturing_audio(data->chamelium, port, false);
 
-- 
2.21.0



More information about the igt-dev mailing list