All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paul Kocialkowski <paul.kocialkowski@linux.intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH i-g-t v2 2/3] lib: Add ALSA library with dedicated helpers
Date: Mon, 21 Aug 2017 18:27:19 +0300	[thread overview]
Message-ID: <20170821152720.5925-3-paul.kocialkowski@linux.intel.com> (raw)
In-Reply-To: <20170821152720.5925-1-paul.kocialkowski@linux.intel.com>

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(&params);
+
+	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

  parent reply	other threads:[~2017-08-21 15:27 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170821152720.5925-3-paul.kocialkowski@linux.intel.com \
    --to=paul.kocialkowski@linux.intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.