forked from pool/alsa-utils
Accepting request 138458 from home:tiwai:branches:multimedia:libs
- backport from upstream tree: * add support for the new chmap API OBS-URL: https://build.opensuse.org/request/show/138458 OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/alsa-utils?expand=0&rev=60
This commit is contained in:
parent
b2a2bba2b4
commit
f57427e846
245
0001-speaker-test-Add-support-for-channel-mapping-API.patch
Normal file
245
0001-speaker-test-Add-support-for-channel-mapping-API.patch
Normal file
@ -0,0 +1,245 @@
|
||||
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));
|
106
0002-aplay-Add-support-for-channel-mapping.patch
Normal file
106
0002-aplay-Add-support-for-channel-mapping.patch
Normal file
@ -0,0 +1,106 @@
|
||||
From a9add2252f44fae3eb0ce5470cb842f220fb0454 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Tue, 11 Sep 2012 12:20:55 +0200
|
||||
Subject: [PATCH 2/5] aplay: Add support for channel mapping
|
||||
|
||||
With -m option, user can specify the order of channel map.
|
||||
As of this commit, it just tries to override the channel map, thus it
|
||||
works only on devices that support the channel map override like HDMI.
|
||||
Adjusting the channel order in aplay itself will be added later.
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
aplay/aplay.c | 40 ++++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 38 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/aplay/aplay.c
|
||||
+++ b/aplay/aplay.c
|
||||
@@ -54,6 +54,10 @@
|
||||
#include "formats.h"
|
||||
#include "version.h"
|
||||
|
||||
+#ifdef SND_CHMAP_API_VERSION
|
||||
+#define CONFIG_SUPPORT_CHMAP 1
|
||||
+#endif
|
||||
+
|
||||
#ifndef LLONG_MAX
|
||||
#define LLONG_MAX 9223372036854775807LL
|
||||
#endif
|
||||
@@ -140,6 +144,10 @@ static char *pidfile_name = NULL;
|
||||
FILE *pidf = NULL;
|
||||
static int pidfile_written = 0;
|
||||
|
||||
+#ifdef CONFIG_SUPPORT_CHMAP
|
||||
+static snd_pcm_chmap_t *channel_map = NULL;
|
||||
+#endif
|
||||
+
|
||||
/* needed prototypes */
|
||||
|
||||
static void done_stdin(void);
|
||||
@@ -227,7 +235,9 @@ _("Usage: %s [OPTION]... [FILE]...\n"
|
||||
" --process-id-file write the process ID here\n"
|
||||
" --use-strftime apply the strftime facility to the output file name\n"
|
||||
" --dump-hw-params dump hw_params of the device\n"
|
||||
-" --fatal-errors treat all errors as fatal\n")
|
||||
+" --fatal-errors treat all errors as fatal\n"
|
||||
+"-m, --chmap=ch1,ch2,.. Give the channel map to override\n"
|
||||
+ )
|
||||
, command);
|
||||
printf(_("Recognized sample formats are:"));
|
||||
for (k = 0; k < SND_PCM_FORMAT_LAST; ++k) {
|
||||
@@ -428,7 +438,11 @@ enum {
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int option_index;
|
||||
- static const char short_options[] = "hnlLD:qt:c:f:r:d:MNF:A:R:T:B:vV:IPCi";
|
||||
+ static const char short_options[] = "hnlLD:qt:c:f:r:d:MNF:A:R:T:B:vV:IPCi"
|
||||
+#ifdef CONFIG_SUPPORT_CHMAP
|
||||
+ "m:"
|
||||
+#endif
|
||||
+ ;
|
||||
static const struct option long_options[] = {
|
||||
{"help", 0, 0, 'h'},
|
||||
{"version", 0, 0, OPT_VERSION},
|
||||
@@ -469,6 +483,9 @@ int main(int argc, char *argv[])
|
||||
{"interactive", 0, 0, 'i'},
|
||||
{"dump-hw-params", 0, 0, OPT_DUMP_HWPARAMS},
|
||||
{"fatal-errors", 0, 0, OPT_FATAL_ERRORS},
|
||||
+#ifdef CONFIG_SUPPORT_CHMAP
|
||||
+ {"chmap", 1, 0, 'm'},
|
||||
+#endif
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
char *pcm_name = "default";
|
||||
@@ -676,6 +693,15 @@ int main(int argc, char *argv[])
|
||||
case OPT_FATAL_ERRORS:
|
||||
fatal_errors = 1;
|
||||
break;
|
||||
+#ifdef CONFIG_SUPPORT_CHMAP
|
||||
+ case 'm':
|
||||
+ channel_map = snd_pcm_chmap_parse_string(optarg);
|
||||
+ if (!channel_map) {
|
||||
+ fprintf(stderr, _("Unable to parse channel map string: %s\n"), optarg);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ break;
|
||||
+#endif
|
||||
default:
|
||||
fprintf(stderr, _("Try `%s --help' for more information.\n"), command);
|
||||
return 1;
|
||||
@@ -1206,6 +1232,16 @@ static void set_params(void)
|
||||
prg_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_SUPPORT_CHMAP
|
||||
+ if (channel_map) {
|
||||
+ err = snd_pcm_set_chmap(handle, channel_map);
|
||||
+ if (err < 0) {
|
||||
+ error(_("Unable to set channel map"));
|
||||
+ prg_exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
if (verbose)
|
||||
snd_pcm_dump(handle, log);
|
||||
|
244
0003-aplay-More-support-for-channel-map-option.patch
Normal file
244
0003-aplay-More-support-for-channel-map-option.patch
Normal file
@ -0,0 +1,244 @@
|
||||
From 000bf230cfb3b0abe88d27701dd77982675126ec Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Thu, 20 Sep 2012 13:53:46 +0200
|
||||
Subject: [PATCH 3/5] aplay: More support for channel map option
|
||||
|
||||
Now aplay tries to follow the given channel map by rearranging the
|
||||
channels even when the channel map override isn't allowed but if the
|
||||
device is still capable to return a channel map.
|
||||
|
||||
Also update the man page appropriately.
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
aplay/aplay.1 | 11 ++++
|
||||
aplay/aplay.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
|
||||
2 files changed, 149 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/aplay/aplay.1
|
||||
+++ b/aplay/aplay.1
|
||||
@@ -141,6 +141,17 @@ by typing arecord.
|
||||
Allow interactive operation via stdin.
|
||||
Currently only pause/resume via space or enter key is implemented.
|
||||
.TP
|
||||
+\fI-m, \-\-chmap=ch1,ch2,...\fP
|
||||
+Give the channel map to override or follow. Pass channel position
|
||||
+strings like \fIFL\fP, \fIFR\fP, etc.
|
||||
+
|
||||
+If a device supports the override of the channel map, \fBaplay\fP
|
||||
+tries to pass the given channel map.
|
||||
+If it doesn't support the channel map override but still it provides
|
||||
+the channel map information, \fBaplay\fP tries to rearrange the
|
||||
+channel order in the buffer to match with the returned channel map
|
||||
+from the device.
|
||||
+.TP
|
||||
\fI\-\-disable\-resample\fP
|
||||
Disable automatic rate resample.
|
||||
.TP
|
||||
--- a/aplay/aplay.c
|
||||
+++ b/aplay/aplay.c
|
||||
@@ -145,7 +145,8 @@ FILE *pidf = NULL;
|
||||
static int pidfile_written = 0;
|
||||
|
||||
#ifdef CONFIG_SUPPORT_CHMAP
|
||||
-static snd_pcm_chmap_t *channel_map = NULL;
|
||||
+static snd_pcm_chmap_t *channel_map = NULL; /* chmap to override */
|
||||
+static unsigned int *hw_map = NULL; /* chmap to follow */
|
||||
#endif
|
||||
|
||||
/* needed prototypes */
|
||||
@@ -222,6 +223,7 @@ _("Usage: %s [OPTION]... [FILE]...\n"
|
||||
"-V, --vumeter=TYPE enable VU meter (TYPE: mono or stereo)\n"
|
||||
"-I, --separate-channels one file for each channel\n"
|
||||
"-i, --interactive allow interactive operation from stdin\n"
|
||||
+"-m, --chmap=ch1,ch2,.. Give the channel map to override or follow\n"
|
||||
" --disable-resample disable automatic rate resample\n"
|
||||
" --disable-channels disable automatic channel conversions\n"
|
||||
" --disable-format disable automatic format conversions\n"
|
||||
@@ -236,7 +238,6 @@ _("Usage: %s [OPTION]... [FILE]...\n"
|
||||
" --use-strftime apply the strftime facility to the output file name\n"
|
||||
" --dump-hw-params dump hw_params of the device\n"
|
||||
" --fatal-errors treat all errors as fatal\n"
|
||||
-"-m, --chmap=ch1,ch2,.. Give the channel map to override\n"
|
||||
)
|
||||
, command);
|
||||
printf(_("Recognized sample formats are:"));
|
||||
@@ -1083,6 +1084,74 @@ static void show_available_sample_format
|
||||
}
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_SUPPORT_CHMAP
|
||||
+static int setup_chmap(void)
|
||||
+{
|
||||
+ snd_pcm_chmap_t *chmap = channel_map;
|
||||
+ char mapped[hwparams.channels];
|
||||
+ snd_pcm_chmap_t *hw_chmap;
|
||||
+ unsigned int ch, i;
|
||||
+ int err;
|
||||
+
|
||||
+ if (!chmap)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (chmap->channels != hwparams.channels) {
|
||||
+ error(_("Channel numbers don't match between hw_params and channel map"));
|
||||
+ return -1;
|
||||
+ }
|
||||
+ err = snd_pcm_set_chmap(handle, chmap);
|
||||
+ if (!err)
|
||||
+ return 0;
|
||||
+
|
||||
+ hw_chmap = snd_pcm_get_chmap(handle);
|
||||
+ if (!hw_chmap) {
|
||||
+ fprintf(stderr, _("Warning: unable to get channel map\n"));
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (hw_chmap->channels == chmap->channels &&
|
||||
+ !memcmp(hw_chmap, chmap, 4 * (chmap->channels + 1))) {
|
||||
+ /* maps are identical, so no need to convert */
|
||||
+ free(hw_chmap);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ hw_map = calloc(hwparams.channels, sizeof(int));
|
||||
+ if (!hw_map) {
|
||||
+ error(_("not enough memory"));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ memset(mapped, 0, sizeof(mapped));
|
||||
+ for (ch = 0; ch < hw_chmap->channels; ch++) {
|
||||
+ if (chmap->pos[ch] == hw_chmap->pos[ch]) {
|
||||
+ mapped[ch] = 1;
|
||||
+ hw_map[ch] = ch;
|
||||
+ continue;
|
||||
+ }
|
||||
+ for (i = 0; i < hw_chmap->channels; i++) {
|
||||
+ if (!mapped[i] && chmap->pos[ch] == hw_chmap->pos[i]) {
|
||||
+ mapped[i] = 1;
|
||||
+ hw_map[ch] = i;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (i >= hw_chmap->channels) {
|
||||
+ char buf[256];
|
||||
+ error(_("Channel %d doesn't match with hw_parmas"), ch);
|
||||
+ snd_pcm_chmap_print(hw_chmap, sizeof(buf), buf);
|
||||
+ fprintf(stderr, "hardware chmap = %s\n", buf);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+ free(hw_chmap);
|
||||
+ return 0;
|
||||
+}
|
||||
+#else
|
||||
+#define setup_chmap() 0
|
||||
+#endif
|
||||
+
|
||||
static void set_params(void)
|
||||
{
|
||||
snd_pcm_hw_params_t *params;
|
||||
@@ -1232,15 +1301,8 @@ static void set_params(void)
|
||||
prg_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_SUPPORT_CHMAP
|
||||
- if (channel_map) {
|
||||
- err = snd_pcm_set_chmap(handle, channel_map);
|
||||
- if (err < 0) {
|
||||
- error(_("Unable to set channel map"));
|
||||
- prg_exit(EXIT_FAILURE);
|
||||
- }
|
||||
- }
|
||||
-#endif
|
||||
+ if (setup_chmap())
|
||||
+ prg_exit(EXIT_FAILURE);
|
||||
|
||||
if (verbose)
|
||||
snd_pcm_dump(handle, log);
|
||||
@@ -1743,6 +1805,69 @@ static void do_test_position(void)
|
||||
}
|
||||
|
||||
/*
|
||||
+ */
|
||||
+#ifdef CONFIG_SUPPORT_CHMAP
|
||||
+static u_char *remap_data(u_char *data, size_t count)
|
||||
+{
|
||||
+ static u_char *tmp, *src, *dst;
|
||||
+ static size_t tmp_size;
|
||||
+ size_t sample_bytes = bits_per_sample / 8;
|
||||
+ size_t step = bits_per_frame / 8;
|
||||
+ size_t chunk_bytes;
|
||||
+ unsigned int ch, i;
|
||||
+
|
||||
+ if (!hw_map)
|
||||
+ return data;
|
||||
+
|
||||
+ chunk_bytes = count * bits_per_frame / 8;
|
||||
+ if (tmp_size < chunk_bytes) {
|
||||
+ free(tmp);
|
||||
+ tmp = malloc(chunk_bytes);
|
||||
+ if (!tmp) {
|
||||
+ error(_("not enough memory"));
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ tmp_size = count;
|
||||
+ }
|
||||
+
|
||||
+ src = data;
|
||||
+ dst = tmp;
|
||||
+ for (i = 0; i < count; i++) {
|
||||
+ for (ch = 0; ch < hwparams.channels; ch++) {
|
||||
+ memcpy(dst, src + sample_bytes * hw_map[ch],
|
||||
+ sample_bytes);
|
||||
+ dst += sample_bytes;
|
||||
+ }
|
||||
+ src += step;
|
||||
+ }
|
||||
+ return tmp;
|
||||
+}
|
||||
+
|
||||
+static u_char **remap_datav(u_char **data, size_t count)
|
||||
+{
|
||||
+ static u_char **tmp;
|
||||
+ unsigned int ch;
|
||||
+
|
||||
+ if (!hw_map)
|
||||
+ return data;
|
||||
+
|
||||
+ if (!tmp) {
|
||||
+ tmp = malloc(sizeof(*tmp) * hwparams.channels);
|
||||
+ if (!tmp) {
|
||||
+ error(_("not enough memory"));
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ for (ch = 0; ch < hwparams.channels; ch++)
|
||||
+ tmp[ch] = data[hw_map[ch]];
|
||||
+ }
|
||||
+ return tmp;
|
||||
+}
|
||||
+#else
|
||||
+#define remap_data(data, count) (data)
|
||||
+#define remapv_data(data, count) (data)
|
||||
+#endif
|
||||
+
|
||||
+/*
|
||||
* write function
|
||||
*/
|
||||
|
||||
@@ -1755,6 +1880,7 @@ static ssize_t pcm_write(u_char *data, s
|
||||
snd_pcm_format_set_silence(hwparams.format, data + count * bits_per_frame / 8, (chunk_size - count) * hwparams.channels);
|
||||
count = chunk_size;
|
||||
}
|
||||
+ data = remap_data(data, count);
|
||||
while (count > 0) {
|
||||
if (test_position)
|
||||
do_test_position();
|
||||
@@ -1797,6 +1923,7 @@ static ssize_t pcm_writev(u_char **data,
|
||||
snd_pcm_format_set_silence(hwparams.format, data[channel] + offset * bits_per_sample / 8, remaining);
|
||||
count = chunk_size;
|
||||
}
|
||||
+ data = remap_datav(data, count);
|
||||
while (count > 0) {
|
||||
unsigned int channel;
|
||||
void *bufs[channels];
|
35
0004-speaker-test-Update-man-page-for-chmap-option.patch
Normal file
35
0004-speaker-test-Update-man-page-for-chmap-option.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From 7b14c00b56784f69ecc954a2de36e0a058fc8849 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Thu, 20 Sep 2012 14:00:02 +0200
|
||||
Subject: [PATCH 4/5] speaker-test: Update man page for chmap option
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
speaker-test/speaker-test.1 | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
--- a/speaker-test/speaker-test.1
|
||||
+++ b/speaker-test/speaker-test.1
|
||||
@@ -131,6 +131,11 @@ Use the given WAV file for the playback
|
||||
Specify the directory containing WAV files for playback.
|
||||
The default path is \fI/usr/share/sounds/alsa\fP.
|
||||
|
||||
+.TP
|
||||
+\fB\-m\fP | \fB\-\-chmap\fP
|
||||
+Pass the channel map to override.
|
||||
+If the playback in a specific channel order or channel positions is
|
||||
+required, pass the channel position strings to this option.
|
||||
|
||||
.SH USAGE EXAMPLES
|
||||
|
||||
@@ -159,6 +164,10 @@ To do a 2-speaker test using the spdif (
|
||||
speaker-test -Dplug:spdif -c2
|
||||
.EE
|
||||
|
||||
+Play in the order of front-right and front-left from the front PCM
|
||||
+.EX
|
||||
+ speaker-test -Dplug:front -c2 -mFR,FL
|
||||
+.EE
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR aplay(1)
|
44
0005-aplay-fix-typo-silence-warning.patch
Normal file
44
0005-aplay-fix-typo-silence-warning.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From 6017849f1b9d406ac2c882ddbde408ada38c3d61 Mon Sep 17 00:00:00 2001
|
||||
From: Jaroslav Kysela <perex@perex.cz>
|
||||
Date: Mon, 24 Sep 2012 16:18:54 +0200
|
||||
Subject: [PATCH 5/5] aplay: fix typo & silence warning..
|
||||
|
||||
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||
---
|
||||
aplay/aplay.c | 10 ++++++----
|
||||
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/aplay/aplay.c
|
||||
+++ b/aplay/aplay.c
|
||||
@@ -1864,7 +1864,7 @@ static u_char **remap_datav(u_char **dat
|
||||
}
|
||||
#else
|
||||
#define remap_data(data, count) (data)
|
||||
-#define remapv_data(data, count) (data)
|
||||
+#define remap_datav(data, count) (data)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -2122,7 +2122,6 @@ static void voc_play(int fd, int ofs, ch
|
||||
u_char *data, *buf;
|
||||
char was_extended = 0, output = 0;
|
||||
u_short *sp, repeat = 0;
|
||||
- size_t silence;
|
||||
off64_t filepos = 0;
|
||||
|
||||
#define COUNT(x) nextblock -= x; in_buffer -= x; data += x
|
||||
@@ -2226,9 +2225,12 @@ static void voc_play(int fd, int ofs, ch
|
||||
COUNT1(1);
|
||||
hwparams.rate = 1000000 / (256 - hwparams.rate);
|
||||
set_params();
|
||||
- silence = (((size_t) * sp) * 1000) / hwparams.rate;
|
||||
#if 0
|
||||
- d_printf("Silence for %d ms\n", (int) silence);
|
||||
+ {
|
||||
+ size_t silence;
|
||||
+ silence = (((size_t) * sp) * 1000) / hwparams.rate;
|
||||
+ d_printf("Silence for %d ms\n", (int) silence);
|
||||
+ }
|
||||
#endif
|
||||
voc_write_silence(*sp);
|
||||
break;
|
@ -1,3 +1,9 @@
|
||||
-------------------------------------------------------------------
|
||||
Wed Oct 17 10:10:38 CEST 2012 - tiwai@suse.de
|
||||
|
||||
- backport from upstream tree:
|
||||
* add support for the new chmap API
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Sep 10 15:24:42 CEST 2012 - tiwai@suse.de
|
||||
|
||||
|
@ -44,6 +44,12 @@ Release: 0
|
||||
Source: ftp://ftp.alsa-project.org/pub/utils/alsa-utils-%{package_version}.tar.bz2
|
||||
Source1: 01beep.conf
|
||||
# Patch: alsa-utils-git-fixes.diff
|
||||
Patch1: 0001-speaker-test-Add-support-for-channel-mapping-API.patch
|
||||
Patch2: 0002-aplay-Add-support-for-channel-mapping.patch
|
||||
Patch3: 0003-aplay-More-support-for-channel-map-option.patch
|
||||
Patch4: 0004-speaker-test-Update-man-page-for-chmap-option.patch
|
||||
Patch5: 0005-aplay-fix-typo-silence-warning.patch
|
||||
#
|
||||
Patch99: alsa-utils-gettext-version-removal.diff
|
||||
Url: http://www.alsa-project.org/
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
@ -58,6 +64,11 @@ Sound Architecture.
|
||||
sed -i -e's/EXTRA_DIST= config.rpath /EXTRA_DIST=/' Makefile.am
|
||||
# rm -f po/Makefile* po/*.gmo po/*.pot po/*.header po/stamp-*
|
||||
# patch -p1
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%if %suse_version < 1020
|
||||
%patch99 -p1
|
||||
%endif
|
||||
|
Loading…
Reference in New Issue
Block a user