SHA256
1
0
forked from pool/alsa-utils
alsa-utils/0001-speaker-test-Add-support-for-channel-mapping-API.patch

246 lines
6.3 KiB
Diff

From 951cb2c2974293db6e12ef067ae7001074887932 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Tue, 11 Sep 2012 11:36:45 +0200
Subject: [PATCH 1/5] speaker-test: Add support for channel mapping API
The surround channel map follows the given channel map from the
driver if available.
Also, the channels can be specified manually via -m option.
Pass the channel map like "FL,FR,FC,LFE".
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
speaker-test/speaker-test.c | 139 +++++++++++++++++++++++++++++++++++++++-----
1 file changed, 124 insertions(+), 15 deletions(-)
--- a/speaker-test/speaker-test.c
+++ b/speaker-test/speaker-test.c
@@ -60,6 +60,10 @@
#include <locale.h>
#endif
+#ifdef SND_CHMAP_API_VERSION
+#define CONFIG_SUPPORT_CHMAP 1
+#endif
+
enum {
TEST_PINK_NOISE = 1,
TEST_SINE,
@@ -100,6 +104,11 @@ static const char *given_test_wav_file =
static char *wav_file_dir = SOUNDSDIR;
static int debug = 0;
+#ifdef CONFIG_SUPPORT_CHMAP
+static snd_pcm_chmap_t *channel_map;
+static int channel_map_set;
+#endif
+
static const char *const channel_name[MAX_CHANNELS] = {
/* 0 */ N_("Front Left"),
/* 1 */ N_("Front Right"),
@@ -143,6 +152,65 @@ static const int channels8[] = {
6, /* Side Left */
5, /* LFE */
};
+
+static int get_mapped_channel(int chn)
+{
+#ifdef CONFIG_SUPPORT_CHMAP
+ static const int maps[MAX_CHANNELS] = {
+ SND_CHMAP_FL,
+ SND_CHMAP_FR,
+ SND_CHMAP_RL,
+ SND_CHMAP_RR,
+ SND_CHMAP_FC,
+ SND_CHMAP_LFE,
+ SND_CHMAP_SL,
+ SND_CHMAP_SR,
+ };
+
+ if (channel_map && maps[chn]) {
+ int i;
+ for (i = 0; i < channel_map->channels; i++) {
+ if (channel_map->pos[i] == maps[chn])
+ return i;
+ }
+ }
+#endif
+ return chn;
+}
+
+static int get_speaker_channel(int chn)
+{
+#ifdef CONFIG_SUPPORT_CHMAP
+ if (channel_map_set)
+ return chn;
+#endif
+
+ switch (channels) {
+ case 4:
+ chn = channels4[chn];
+ break;
+ case 6:
+ chn = channels6[chn];
+ break;
+ case 8:
+ chn = channels8[chn];
+ break;
+ }
+
+ return get_mapped_channel(chn);
+}
+
+static const char *get_channel_name(int chn)
+{
+#ifdef CONFIG_SUPPORT_CHMAP
+ if (channel_map_set && chn < channel_map->channels) {
+ const char *name = snd_pcm_chmap_long_name(channel_map->pos[chn]);
+ return name ? name : "Unknown";
+ }
+#endif
+ return gettext(channel_name[chn]);
+}
+
static const int supported_formats[] = {
SND_PCM_FORMAT_S8,
SND_PCM_FORMAT_S16_LE,
@@ -519,6 +587,31 @@ static int set_swparams(snd_pcm_t *handl
return 0;
}
+#ifdef CONFIG_SUPPORT_CHMAP
+static int config_chmap(snd_pcm_t *handle, const char *mapstr)
+{
+ int err;
+
+ if (mapstr) {
+ channel_map = snd_pcm_chmap_parse_string(mapstr);
+ if (!channel_map) {
+ fprintf(stderr, _("Unable to parse channel map string: %s\n"), mapstr);
+ return -EINVAL;
+ }
+ err = snd_pcm_set_chmap(handle, channel_map);
+ if (err < 0) {
+ fprintf(stderr, _("Unable to set channel map: %s\n"), mapstr);
+ return err;
+ }
+ channel_map_set = 1;
+ return 0;
+ }
+
+ channel_map = snd_pcm_get_chmap(handle);
+ return 0;
+}
+#endif
+
/*
* Underrun and suspend recovery
*/
@@ -815,6 +908,7 @@ static void help(void)
"-s,--speaker single speaker test. Values 1=Left, 2=right, etc\n"
"-w,--wavfile Use the given WAV file as a test sound\n"
"-W,--wavdir Specify the directory containing WAV files\n"
+ "-m,--chmap Specify the channel map to override\n"
"\n"));
printf(_("Recognized sample formats are:"));
for (fmt = supported_formats; *fmt >= 0; fmt++) {
@@ -837,6 +931,9 @@ int main(int argc, char *argv[]) {
double time1,time2,time3;
unsigned int n, nloops;
struct timeval tv1,tv2;
+#ifdef CONFIG_SUPPORT_CHMAP
+ const char *chmap = NULL;
+#endif
static const struct option long_option[] = {
{"help", 0, NULL, 'h'},
@@ -854,6 +951,9 @@ int main(int argc, char *argv[]) {
{"wavfile", 1, NULL, 'w'},
{"wavdir", 1, NULL, 'W'},
{"debug", 0, NULL, 'd'},
+#ifdef CONFIG_SUPPORT_CHMAP
+ {"chmap", 1, NULL, 'm'},
+#endif
{NULL, 0, NULL, 0 },
};
@@ -872,7 +972,11 @@ int main(int argc, char *argv[]) {
while (1) {
int c;
- if ((c = getopt_long(argc, argv, "hD:r:c:f:F:b:p:P:t:l:s:w:W:d", long_option, NULL)) < 0)
+ if ((c = getopt_long(argc, argv, "hD:r:c:f:F:b:p:P:t:l:s:w:W:d"
+#ifdef CONFIG_SUPPORT_CHMAP
+ "m:"
+#endif
+ , long_option, NULL)) < 0)
break;
switch (c) {
@@ -963,6 +1067,11 @@ int main(int argc, char *argv[]) {
case 'd':
debug = 1;
break;
+#ifdef CONFIG_SUPPORT_CHMAP
+ case 'm':
+ chmap = optarg;
+ break;
+#endif
default:
fprintf(stderr, _("Unknown option '%c'\n"), c);
exit(EXIT_FAILURE);
@@ -1008,6 +1117,13 @@ int main(int argc, char *argv[]) {
snd_pcm_close(handle);
exit(EXIT_FAILURE);
}
+
+#ifdef CONFIG_SUPPORT_CHMAP
+ err = config_chmap(handle, chmap);
+ if (err < 0)
+ exit(EXIT_FAILURE);
+#endif
+
if (debug) {
snd_output_t *log;
err = snd_output_stdio_attach(&log, stderr, 0);
@@ -1038,17 +1154,8 @@ int main(int argc, char *argv[]) {
gettimeofday(&tv1, NULL);
for(chn = 0; chn < channels; chn++) {
- int channel=chn;
- if (channels == 4) {
- channel=channels4[chn];
- }
- if (channels == 6) {
- channel=channels6[chn];
- }
- if (channels == 8) {
- channel=channels8[chn];
- }
- printf(" %d - %s\n", channel, gettext(channel_name[channel]));
+ int channel = get_speaker_channel(chn);
+ printf(" %d - %s\n", channel, get_channel_name(channel));
err = write_loop(handle, channel, ((rate*3)/period_size), frames);
@@ -1066,13 +1173,15 @@ int main(int argc, char *argv[]) {
printf(_("Time per period = %lf\n"), time3 );
}
} else {
+ chn = get_speaker_channel(speaker - 1);
+
if (test_type == TEST_WAV) {
- if (setup_wav_file(speaker - 1) < 0)
+ if (setup_wav_file(chn) < 0)
exit(EXIT_FAILURE);
}
- printf(" - %s\n", gettext(channel_name[speaker-1]));
- err = write_loop(handle, speaker-1, ((rate*5)/period_size), frames);
+ printf(" - %s\n", get_channel_name(chn));
+ err = write_loop(handle, chn, ((rate*5)/period_size), frames);
if (err < 0) {
fprintf(stderr, _("Transfer failed: %s\n"), snd_strerror(err));