Hello community,
here is the log from the commit of package alsa-utils for openSUSE:Factory
checked in at Mon Nov 29 11:53:51 CET 2010.
--------
--- alsa-utils/alsa-utils.changes 2010-09-02 16:07:59.000000000 +0200
+++ /mounts/work_src_done/STABLE/alsa-utils/alsa-utils.changes 2010-11-26 12:56:49.000000000 +0100
@@ -1,0 +2,50 @@
+Fri Nov 26 09:58:58 CET 2010 - tiwai@suse.de
+
+- add /lib/systemd/service/alsasound.service to make systemd
+ skipping old sysv script
+
+-------------------------------------------------------------------
+Fri Nov 26 09:21:16 CET 2010 - tiwai@suse.de
+
+- drop explicit buildrequires on systemd
+
+-------------------------------------------------------------------
+Fri Nov 26 09:05:03 CET 2010 - tiwai@suse.de
+
+- backport GIT PATCHES:
+ * A few alsactl init fix patches:
+ 0014-alsactl-init-Handle-Capture-Source-and-Mic-Boost-in-.patch
+ 0015-alsactl-init-Initialize-also-Master-Front-Playback-V.patch
+ * amixer control-id parse fix
+ 0016-amixer-fix-parsing-of-control-ID-name.patch
+ * new aloop utility
+ 0017-Introduce-alsaloop-utility.patch
+ 0018-alsaloop-Fix-loopbacks-pointer-initialization-and-al.patch
+ 0019-alsaloop-Fix-thread-handling.patch
+ 0020-alsaloop-fix-a-option-and-slave-mode-processing.patch
+ 0021-alsaloop-fix-resample-argument-parsing.patch
+ 0022-alsaloop-added-resampling-for-unsupported-soundcard-.patch
+ 0023-alsaloop-Add-OSS-mixer-redirection-support.patch
+ 0024-alsaloop-Fix-command-line-parsing-and-pollfd-initial.patch
+ 0025-alsaloop-Fixes-and-added-workaround-option.patch
+ 0026-alsaloop-add-pctl-and-cctl-options.patch
+ 0027-alsaloop-add-pctl-and-cctl-options-to-man-page.patch
+ 0028-alsaloop-added-xrun-profiling-support-U-xrun-added-S.patch
+ 0029-alsaloop-add-U-xrun-to-alsaloop.1-man-page.patch
+ 0030-alsaloop-fixes-added-W-wake-option.patch
+ 0031-alsaloop-Fix-latency-print.patch
+ 0033-alsaloop-Delay-the-restart-a-bit-to-handle-snd-aloop.patch
+ 0034-alsaloop-rework-the-ctl-event-handling-routine.patch
+ * robusitfy speaker-test
+ 0032-speaker-test-Don-t-retry-after-fatal-errors.patch
+ * misc clean up, translation updates
+ 0035-alsamixer-remove-obsolete-e-mail.patch
+ 0036-update-German-translations.patch
+ * systemd integration
+ 0037-alsactl-systemd-and-udev-hookup.patch
+ 0038-alsactl-Move-asound.state-location-to-var-lib-alsa.patch
+ 0039-configure.in-Fix-variable-name.patch
+- Use systemd for openSUSE 11.4
+- Put udev rules into this package instead of alsa.rpm
+
+-------------------------------------------------------------------
calling whatdependson for head-i586
New:
----
0014-alsactl-init-Handle-Capture-Source-and-Mic-Boost-in-.patch
0015-alsactl-init-Initialize-also-Master-Front-Playback-V.patch
0016-amixer-fix-parsing-of-control-ID-name.patch
0017-Introduce-alsaloop-utility.patch
0018-alsaloop-Fix-loopbacks-pointer-initialization-and-al.patch
0019-alsaloop-Fix-thread-handling.patch
0020-alsaloop-fix-a-option-and-slave-mode-processing.patch
0021-alsaloop-fix-resample-argument-parsing.patch
0022-alsaloop-added-resampling-for-unsupported-soundcard-.patch
0023-alsaloop-Add-OSS-mixer-redirection-support.patch
0024-alsaloop-Fix-command-line-parsing-and-pollfd-initial.patch
0025-alsaloop-Fixes-and-added-workaround-option.patch
0026-alsaloop-add-pctl-and-cctl-options.patch
0027-alsaloop-add-pctl-and-cctl-options-to-man-page.patch
0028-alsaloop-added-xrun-profiling-support-U-xrun-added-S.patch
0029-alsaloop-add-U-xrun-to-alsaloop.1-man-page.patch
0030-alsaloop-fixes-added-W-wake-option.patch
0031-alsaloop-Fix-latency-print.patch
0032-speaker-test-Don-t-retry-after-fatal-errors.patch
0033-alsaloop-Delay-the-restart-a-bit-to-handle-snd-aloop.patch
0034-alsaloop-rework-the-ctl-event-handling-routine.patch
0035-alsamixer-remove-obsolete-e-mail.patch
0036-update-German-translations.patch
0037-alsactl-systemd-and-udev-hookup.patch
0038-alsactl-Move-asound.state-location-to-var-lib-alsa.patch
0039-configure.in-Fix-variable-name.patch
alsa-utils-po-pre-patch.diff
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ alsa-utils.spec ++++++
--- /var/tmp/diff_new_pack.eeIe1L/_old 2010-11-29 11:53:31.000000000 +0100
+++ /var/tmp/diff_new_pack.eeIe1L/_new 2010-11-29 11:53:31.000000000 +0100
@@ -17,9 +17,14 @@
# norootforbuild
+%if %suse_version > 1130
+%define use_systemd 1
+%else
+%define use_systemd 0
+%endif
Name: alsa-utils
-BuildRequires: alsa-devel ncurses-devel xmlto
+BuildRequires: alsa-devel ncurses-devel pkgconfig xmlto
%define package_version 1.0.23
License: GPLv2+
Group: Productivity/Multimedia/Sound/Players
@@ -28,7 +33,7 @@
AutoReqProv: on
Summary: Advanced Linux Sound Architecture Utilities
Version: 1.0.23
-Release: 4
+Release: 5
Source: ftp://ftp.alsa-project.org/pub/util/alsa-utils-%{package_version}.tar.bz2
# Patch: alsa-utils-git-fixes.diff
Patch1: 0001-alsactl-use-snd_config_imake-functions.patch
@@ -44,8 +49,34 @@
Patch11: 0011-alsactl-init-Use-Found-hardware-instead-Unknown-hard.patch
Patch12: 0012-alsactl-init-use-generic-method-instead-guess-method.patch
Patch13: 0013-alsactl-Change-handling-of-inactive-controls.patch
+Patch14: 0014-alsactl-init-Handle-Capture-Source-and-Mic-Boost-in-.patch
+Patch15: 0015-alsactl-init-Initialize-also-Master-Front-Playback-V.patch
+Patch16: 0016-amixer-fix-parsing-of-control-ID-name.patch
+Patch17: 0017-Introduce-alsaloop-utility.patch
+Patch18: 0018-alsaloop-Fix-loopbacks-pointer-initialization-and-al.patch
+Patch19: 0019-alsaloop-Fix-thread-handling.patch
+Patch20: 0020-alsaloop-fix-a-option-and-slave-mode-processing.patch
+Patch21: 0021-alsaloop-fix-resample-argument-parsing.patch
+Patch22: 0022-alsaloop-added-resampling-for-unsupported-soundcard-.patch
+Patch23: 0023-alsaloop-Add-OSS-mixer-redirection-support.patch
+Patch24: 0024-alsaloop-Fix-command-line-parsing-and-pollfd-initial.patch
+Patch25: 0025-alsaloop-Fixes-and-added-workaround-option.patch
+Patch26: 0026-alsaloop-add-pctl-and-cctl-options.patch
+Patch27: 0027-alsaloop-add-pctl-and-cctl-options-to-man-page.patch
+Patch28: 0028-alsaloop-added-xrun-profiling-support-U-xrun-added-S.patch
+Patch29: 0029-alsaloop-add-U-xrun-to-alsaloop.1-man-page.patch
+Patch30: 0030-alsaloop-fixes-added-W-wake-option.patch
+Patch31: 0031-alsaloop-Fix-latency-print.patch
+Patch32: 0032-speaker-test-Don-t-retry-after-fatal-errors.patch
+Patch33: 0033-alsaloop-Delay-the-restart-a-bit-to-handle-snd-aloop.patch
+Patch34: 0034-alsaloop-rework-the-ctl-event-handling-routine.patch
+Patch35: 0035-alsamixer-remove-obsolete-e-mail.patch
+Patch36: 0036-update-German-translations.patch
+Patch37: 0037-alsactl-systemd-and-udev-hookup.patch
+Patch38: 0038-alsactl-Move-asound.state-location-to-var-lib-alsa.patch
+Patch39: 0039-configure.in-Fix-variable-name.patch
Patch99: alsa-utils-gettext-version-removal.diff
-# Patch100: alsa-utils-po-pre-patch.diff
+Patch100: alsa-utils-po-pre-patch.diff
Url: http://www.alsa-project.org/
BuildRoot: %{_tmppath}/%{name}-%{version}-build
@@ -65,9 +96,9 @@
# fix stupid automake's automatic action
sed -i -e's/EXTRA_DIST= config.rpath /EXTRA_DIST=/' Makefile.am
# fix po changes in tarball first
-# %patch100 -p1
+%patch100 -p1
# rm -f po/Makefile* po/*.gmo po/*.pot po/*.header po/stamp-*
-# %patch -p1
+# %%patch -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
@@ -81,6 +112,32 @@
%patch11 -p1
%patch12 -p1
%patch13 -p1
+%patch14 -p1
+%patch15 -p1
+%patch16 -p1
+%patch17 -p1
+%patch18 -p1
+%patch19 -p1
+%patch20 -p1
+%patch21 -p1
+%patch22 -p1
+%patch23 -p1
+%patch24 -p1
+%patch25 -p1
+%patch26 -p1
+%patch27 -p1
+%patch28 -p1
+%patch29 -p1
+%patch30 -p1
+%patch31 -p1
+%patch32 -p1
+%patch33 -p1
+%patch34 -p1
+%patch35 -p1
+%patch36 -p1
+%patch37 -p1
+%patch38 -p1
+%patch39 -p1
%if %suse_version < 1020
%patch99 -p1
%endif
@@ -91,17 +148,25 @@
gettextize -f
%endif
autoreconf -fi
+opts=""
+%if %use_systemd
+opts="$opts --with-systemdsystemunitdir=/lib/systemd/system"
+%endif
+%if %suse_version < 1140
+opts="$opts --with-asound-state-dir=/etc"
+%endif
%if %suse_version < 1030
-%define moreopts --disable-xmlto
-%else
-%define moreopts
+opts="$opts --disable-xmlto"
%endif
-%configure --with-curses=ncursesw %moreopts
+%configure --with-curses=ncursesw $opts
make %{?jobs:-j %jobs}
%install
%makeinstall
%find_lang %{name} --all-name
+%if %use_systemd
+ln -s alsa-restore.service $RPM_BUILD_ROOT/lib/systemd/system/alsasound.service
+%endif
%clean
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
@@ -117,5 +182,9 @@
%{_sbindir}/*
%{_datadir}/sounds/alsa
%{_datadir}/alsa
+/lib/udev
+%if %use_systemd
+/lib/systemd
+%endif
%changelog
++++++ 0014-alsactl-init-Handle-Capture-Source-and-Mic-Boost-in-.patch ++++++
From 52bd2f8acedaacce32ca8e89cb1f21683658648e Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Tue, 7 Sep 2010 17:07:12 +0200
Subject: [PATCH 14/38] alsactl init: Handle "Capture Source" and "Mic Boost" in the default script
Signed-off-by: Jaroslav Kysela
---
alsactl/init/default | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/alsactl/init/default b/alsactl/init/default
index 35acfc3..9fd7972 100644
--- a/alsactl/init/default
+++ b/alsactl/init/default
@@ -185,6 +185,11 @@ CTL{name}="Capture Volume",CTL{do_search}=="1", \
CTL{name}="Capture Switch",CTL{do_search}=="1", \
CTL{values}="on"
+CTL{name}="Capture Source",PROGRAM!="__ctl_search", GOTO=""
+CTL{enums}=="*|Internal Mic|*",CTL{values}="Internal Mic", GOTO=""
+CTL{enums}=="*|Mic|*",CTL{values}="Mic"
+LABEL=""
+
CTL{name}="Input Source",PROGRAM!="__ctl_search", GOTO=""
CTL{enums}=="*|Internal Mic|*",CTL{values}="Internal Mic", GOTO=""
CTL{enums}=="*|Mic|*",CTL{values}="Mic"
@@ -195,4 +200,5 @@ CTL{enums}=="*|Digital Mic 1|*",CTL{values}="Digital Mic 1", GOTO=""
CTL{enums}=="*|Mic|*",CTL{values}="Mic"
LABEL=""
+CTL{name}="Mic Boost",CTL{do_search}=="1", CTL{values}="on"
CTL{name}="Internal Mic Boost",CTL{do_search}=="1", CTL{values}="on"
--
1.7.3.1
++++++ 0015-alsactl-init-Initialize-also-Master-Front-Playback-V.patch ++++++
From ef919a4724169f4c0dc14168dec32c168b2471e4 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Tue, 7 Sep 2010 17:33:14 +0200
Subject: [PATCH 15/38] alsactl init: Initialize also "Master Front Playback Volume" & "Switch"
Signed-off-by: Jaroslav Kysela
---
alsactl/init/default | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/alsactl/init/default b/alsactl/init/default
index 9fd7972..7f8ec4c 100644
--- a/alsactl/init/default
+++ b/alsactl/init/default
@@ -30,6 +30,13 @@ CTL{name}="Master Playback Switch",CTL{do_search}=="1", \
CTL{values}="on"
CTL{reset}="mixer"
+CTL{name}="Master Front Playback Volume",CTL{do_search}=="1", \
+ ENV{has_pmaster_vol}:="true", \
+ CTL{write}!="$env{pvolume}",CTL{values}="$env{ppercent}"
+CTL{name}="Master Front Playback Switch",CTL{do_search}=="1", \
+ CTL{values}="on"
+
+CTL{reset}="mixer"
CTL{name}="Master Digital Playback Volume",CTL{do_search}=="1", \
CTL{write}!="$env{pvolume}",CTL{values}="$env{ppercent}"
CTL{name}="Master Digital Playback Switch",CTL{do_search}=="1", \
--
1.7.3.1
++++++ 0016-amixer-fix-parsing-of-control-ID-name.patch ++++++
From 87c58b59b5c443fe3244bd06417c451581d1f635 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Tue, 5 Oct 2010 10:02:45 +0200
Subject: [PATCH 16/38] amixer: fix parsing of control ID name
Signed-off-by: Jaroslav Kysela
---
amixer/amixer.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/amixer/amixer.c b/amixer/amixer.c
index c9ea572..a177288 100644
--- a/amixer/amixer.c
+++ b/amixer/amixer.c
@@ -1120,8 +1120,8 @@ static int parse_control_id(const char *str, snd_ctl_elem_id_t *id)
}
str++;
}
- *ptr = '\0';
}
+ *ptr = '\0';
snd_ctl_elem_id_set_name(id, buf);
} else if (!strncasecmp(str, "index=", 6)) {
str += 6;
--
1.7.3.1
++++++ 0017-Introduce-alsaloop-utility.patch ++++++
++++ 3313 lines (skipped)
++++++ 0018-alsaloop-Fix-loopbacks-pointer-initialization-and-al.patch ++++++
From ad0e562373af1de5e911cf1d5def598a7b6523f2 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Wed, 6 Oct 2010 18:30:18 +0200
Subject: [PATCH 18/38] alsaloop: Fix loopbacks pointer initialization and allocation, fix -T option
Signed-off-by: Jaroslav Kysela
---
alsaloop/alsaloop.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/alsaloop/alsaloop.c b/alsaloop/alsaloop.c
index 4ba5203..0001358 100644
--- a/alsaloop/alsaloop.c
+++ b/alsaloop/alsaloop.c
@@ -45,7 +45,7 @@ struct loopback_thread {
int verbose = 0;
int daemonize = 0;
int use_syslog = 0;
-struct loopback **loopbacks;
+struct loopback **loopbacks = NULL;
int loopbacks_count = 0;
static void my_exit(struct loopback_thread *thread, int exitcode)
@@ -199,7 +199,8 @@ static long timediff(struct timeval t1, struct timeval t2)
static void add_loop(struct loopback *loop)
{
- loopbacks = realloc(loopbacks, loopbacks_count * sizeof(struct loopback *));
+ loopbacks = realloc(loopbacks, (loopbacks_count + 1) *
+ sizeof(struct loopback *));
if (loopbacks == NULL) {
logit(LOG_CRIT, "No enough memory\n");
exit(EXIT_FAILURE);
@@ -321,7 +322,7 @@ static int parse_config(int argc, char *argv[], snd_output_t *output)
morehelp = 0;
while (1) {
int c;
- if ((c = getopt_long(argc, argv, "hdg:P:C:l:t:F:f:c:r:s:benvA:S:a:m:", long_option, NULL)) < 0)
+ if ((c = getopt_long(argc, argv, "hdg:P:C:l:t:F:f:c:r:s:benvA:S:a:m:T:", long_option, NULL)) < 0)
break;
switch (c) {
case 'h':
--
1.7.3.1
++++++ 0019-alsaloop-Fix-thread-handling.patch ++++++
From 4fe4d22b73dd205521348583f8105de1c155f4a6 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Wed, 6 Oct 2010 18:51:29 +0200
Subject: [PATCH 19/38] alsaloop: Fix thread handling
Signed-off-by: Jaroslav Kysela
---
alsaloop/alsaloop.c | 5 ++---
alsaloop/test.sh | 19 +++++++++++++++++++
2 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/alsaloop/alsaloop.c b/alsaloop/alsaloop.c
index 0001358..743e0ef 100644
--- a/alsaloop/alsaloop.c
+++ b/alsaloop/alsaloop.c
@@ -687,7 +687,7 @@ int main(int argc, char *argv[])
}
/* we must sort thread IDs */
- j = 0;
+ j = -1;
do {
k = 0x7fffffff;
for (i = 0; i < loopbacks_count; i++) {
@@ -695,11 +695,11 @@ int main(int argc, char *argv[])
loopbacks[i]->thread > j)
k = loopbacks[i]->thread;
}
+ j++;
for (i = 0; i < loopbacks_count; i++) {
if (loopbacks[i]->thread == k)
loopbacks[i]->thread = j;
}
- j++;
} while (k != 0x7fffffff);
/* fix maximum thread id */
for (i = 0, j = -1; i < loopbacks_count; i++) {
@@ -729,7 +729,6 @@ int main(int argc, char *argv[])
for (k = 0; k < j; k++)
thread_job(&threads[k]);
- logit(LOG_CRIT, "threads = %i %i\n", j, loopbacks_count);
if (j > 1) {
for (k = 0; k < j; k++)
pthread_join(threads[k].thread, NULL);
diff --git a/alsaloop/test.sh b/alsaloop/test.sh
index 2033add..bc42480 100755
--- a/alsaloop/test.sh
+++ b/alsaloop/test.sh
@@ -27,8 +27,27 @@ EOF
$DBG ./alsaloop -d --config $CFGFILE
}
+test3() {
+ echo "TEST2"
+cat > $CFGFILE <
From 5ad13c4825085ac28ed12afb0daf73c315fe0ed6 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Wed, 6 Oct 2010 20:34:03 +0200
Subject: [PATCH 20/38] alsaloop: fix -a option and slave mode processing
Signed-off-by: Jaroslav Kysela
---
alsaloop/alsaloop.c | 4 ++--
alsaloop/pcmjob.c | 3 +++
alsaloop/test.sh | 18 +++++++++---------
3 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/alsaloop/alsaloop.c b/alsaloop/alsaloop.c
index 743e0ef..48bd21a 100644
--- a/alsaloop/alsaloop.c
+++ b/alsaloop/alsaloop.c
@@ -424,9 +424,9 @@ static int parse_config(int argc, char *argv[], snd_output_t *output)
case 'a':
if (optarg[0] == 'a')
arg_slave = SLAVE_TYPE_AUTO;
- else if (strcasecmp(optarg, "off"))
+ else if (strcasecmp(optarg, "on") == 0)
arg_slave = SLAVE_TYPE_ON;
- else if (strcasecmp(optarg, "on"))
+ else if (strcasecmp(optarg, "off") == 0)
arg_slave = SLAVE_TYPE_OFF;
else
arg_slave = atoi(optarg);
diff --git a/alsaloop/pcmjob.c b/alsaloop/pcmjob.c
index 47256e0..51d9ea6 100644
--- a/alsaloop/pcmjob.c
+++ b/alsaloop/pcmjob.c
@@ -1432,6 +1432,8 @@ int pcmjob_pollfds_handle(struct loopback *loop, struct pollfd *fds)
}
if (verbose > 9)
snd_output_printf(loop->output, "%s: prevents = 0x%x, crevents = 0x%x\n", loop->id, prevents, crevents);
+ if (prevents == 0 && crevents == 0)
+ goto __pcm_end;
do {
ccount = readit(capt);
buf_add(loop, ccount);
@@ -1520,6 +1522,7 @@ int pcmjob_pollfds_handle(struct loopback *loop, struct pollfd *fds)
else
snd_output_printf(loop->output, "%s: end delay %li\n", capt->id, cdelay);
}
+ __pcm_end:
if (verbose > 13) {
getcurtimestamp(&loop->tstamp_end);
snd_output_printf(loop->output, "%s: processing time %lius\n", capt->id, timediff(loop->tstamp_end, loop->tstamp_start));
diff --git a/alsaloop/test.sh b/alsaloop/test.sh
index bc42480..a1d4dbe 100755
--- a/alsaloop/test.sh
+++ b/alsaloop/test.sh
@@ -28,19 +28,19 @@ EOF
}
test3() {
- echo "TEST2"
+ echo "TEST3"
cat > $CFGFILE <
From f956c329aa1271c89cf13a01d1bcea8fae6b03f8 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Thu, 7 Oct 2010 00:12:38 +0200
Subject: [PATCH 21/38] alsaloop: fix resample argument parsing
Signed-off-by: Jaroslav Kysela
---
alsaloop/alsaloop.c | 4 ++--
alsaloop/pcmjob.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/alsaloop/alsaloop.c b/alsaloop/alsaloop.c
index 48bd21a..6fb9c2a 100644
--- a/alsaloop/alsaloop.c
+++ b/alsaloop/alsaloop.c
@@ -81,7 +81,7 @@ static int create_loopback_handle(struct loopback_handle **_handle,
handle->format = SND_PCM_FORMAT_S16_LE;
handle->rate = 48000;
handle->channels = 2;
- handle->resample = 1;
+ handle->resample = 0;
*_handle = handle;
return 0;
}
@@ -384,7 +384,7 @@ static int parse_config(int argc, char *argv[], snd_output_t *output)
arg_effect = 1;
break;
case 'n':
- arg_resample = 0;
+ arg_resample = 1;
break;
case 'A':
if (strcasecmp(optarg, "sincbest") == 0)
diff --git a/alsaloop/pcmjob.c b/alsaloop/pcmjob.c
index 51d9ea6..4ad752d 100644
--- a/alsaloop/pcmjob.c
+++ b/alsaloop/pcmjob.c
@@ -108,7 +108,7 @@ static int setparams_stream(struct loopback_handle *lhandle,
rrate = 0;
snd_pcm_hw_params_get_rate(params, &rrate, 0);
if ((int)rrate != lhandle->rate) {
- logit(LOG_CRIT, "Rate does not match (requested %iHz, get %iHz)\n", lhandle->rate, err);
+ logit(LOG_CRIT, "Rate does not match (requested %iHz, got %iHz, resample %i)\n", lhandle->rate, rrate, lhandle->resample);
return -EINVAL;
}
return 0;
--
1.7.3.1
++++++ 0022-alsaloop-added-resampling-for-unsupported-soundcard-.patch ++++++
++++ 618 lines (skipped)
++++++ 0023-alsaloop-Add-OSS-mixer-redirection-support.patch ++++++
From 147a1cc75cf6002eb5ea2983a374d2e84eee8e1d Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Fri, 8 Oct 2010 15:10:23 +0200
Subject: [PATCH 23/38] alsaloop: Add OSS mixer redirection support
Signed-off-by: Jaroslav Kysela
---
alsaloop/alsaloop.1 | 16 +++++++++++++
alsaloop/alsaloop.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++-
alsaloop/alsaloop.h | 12 +++++++++-
alsaloop/control.c | 48 +++++++++++++++++++++++++++++++++++++-
alsaloop/pcmjob.c | 1 +
alsaloop/test.sh | 4 ++-
6 files changed, 138 insertions(+), 6 deletions(-)
diff --git a/alsaloop/alsaloop.1 b/alsaloop/alsaloop.1
index 66be499..1554b6e 100644
--- a/alsaloop/alsaloop.1
+++ b/alsaloop/alsaloop.1
@@ -153,6 +153,22 @@ Known attributes:
numid - control ID numid
.TP
+\fI\-O <ossmixid>\fP | \fI\-\-ossmixer=<midid>\fP
+
+Redirect mixer control from the OSS Mixer emulation layer (capture card)
+to the ALSA layer (capture card). Format of \fIossmixid\fP is
+ALSAID[,INDEX]@OSSID:
+
+ "Master@VOLUME"
+ "PCM,1@ALTPCM"
+
+Known OSS attributes:
+
+ VOLUME, BASS, TREBLE, SYNTH, PCM, SPEAKER, LINE, MIC, CD, IMIX, ALTPCM,
+ RECLEV, IGAIN, OGAIN, LINE1, LINE2, LINE3, DIGITAL1, DIGITAL2, DIGITAL3,
+ PHONEIN, PHONEOUT, VIDEO, RADIO, MONITOR
+
+.TP
\fI\-v\fP | \fI\-\-verbose\fP
Verbose mode. Use multiple times to increase verbosity.
diff --git a/alsaloop/alsaloop.c b/alsaloop/alsaloop.c
index bbf570e..effa073 100644
--- a/alsaloop/alsaloop.c
+++ b/alsaloop/alsaloop.c
@@ -164,7 +164,9 @@ void help(void)
"-a,--slave stream parameters slave mode (0=auto, 1=on, 2=off)\n"
"-T,--thread thread number (-1 = create unique)\n"
"-m,--mixer redirect mixer, argument is:\n"
-" SRC_SLAVE_ID(PLAYBACK)@DST_SLAVE_ID(CAPTURE)\n"
+" SRC_SLAVE_ID(PLAYBACK)[@DST_SLAVE_ID(CAPTURE)]\n"
+"-O,--ossmixer rescan and redirect oss mixer, argument is:\n"
+" ALSA_ID@OSS_ID (for example: \"Master@VOLUME\")\n"
"-e,--effect apply an effect (bandpass filter sweep)\n"
"-v,--verbose verbose mode (more -v means more verbose)\n"
);
@@ -266,6 +268,46 @@ static int add_mixers(struct loopback *loop,
return 0;
}
+static int add_oss_mixers(struct loopback *loop,
+ char **mixers,
+ int mixers_count)
+{
+ struct loopback_ossmixer *mixer, *last = NULL;
+ char *str1, *str2;
+
+ while (mixers_count > 0) {
+ mixer = calloc(1, sizeof(*mixer));
+ if (mixer == NULL)
+ return -ENOMEM;
+ if (last)
+ last->next = mixer;
+ else
+ loop->oss_controls = mixer;
+ last = mixer;
+ str1 = strchr(*mixers, ',');
+ if (str1)
+ *str1 = '\0';
+ str2 = strchr(str1 ? str1 + 1 : *mixers, '@');
+ if (str2)
+ *str2 = '\0';
+ mixer->alsa_id = strdup(*mixers);
+ if (str1)
+ mixer->alsa_index = atoi(str1);
+ mixer->oss_id = strdup(str2 ? str2 + 1 : *mixers);
+ if (mixer->alsa_id == NULL || mixer->oss_id == NULL) {
+ logit(LOG_CRIT, "Not enough memory");
+ return -ENOMEM;
+ }
+ if (str1)
+ *str1 = ',';
+ if (str2)
+ *str2 = ',';
+ mixers++;
+ mixers_count--;
+ }
+ return 0;
+}
+
static int parse_config_file(const char *file, snd_output_t *output);
static int parse_config(int argc, char *argv[], snd_output_t *output)
@@ -294,6 +336,7 @@ static int parse_config(int argc, char *argv[], snd_output_t *output)
{"slave", 1, NULL, 'a'},
{"thread", 1, NULL, 'T'},
{"mixer", 1, NULL, 'm'},
+ {"ossmixer", 1, NULL, 'O'},
{NULL, 0, NULL, 0},
};
int err, morehelp;
@@ -318,11 +361,15 @@ static int parse_config(int argc, char *argv[], snd_output_t *output)
struct loopback *loop = NULL;
char *arg_mixers[MAX_MIXERS];
int arg_mixers_count = 0;
+ char *arg_ossmixers[MAX_MIXERS];
+ int arg_ossmixers_count = 0;
morehelp = 0;
while (1) {
int c;
- if ((c = getopt_long(argc, argv, "hdg:P:C:l:t:F:f:c:r:s:benvA:S:a:m:T:", long_option, NULL)) < 0)
+ if ((c = getopt_long(argc, argv,
+ "hdg:P:C:l:t:F:f:c:r:s:benvA:S:a:m:T:O:",
+ long_option, NULL)) < 0)
break;
switch (c) {
case 'h':
@@ -445,6 +492,13 @@ static int parse_config(int argc, char *argv[], snd_output_t *output)
}
arg_mixers[arg_mixers_count++] = optarg;
break;
+ case 'O':
+ if (arg_ossmixers_count >= MAX_MIXERS) {
+ logit(LOG_CRIT, "Maximum redirected mixer controls reached (max %i)\n", (int)MAX_MIXERS);
+ exit(EXIT_FAILURE);
+ }
+ arg_ossmixers[arg_ossmixers_count++] = optarg;
+ break;
case 'v':
verbose++;
break;
@@ -490,6 +544,11 @@ static int parse_config(int argc, char *argv[], snd_output_t *output)
logit(LOG_CRIT, "Unable to add mixer controls.\n");
exit(EXIT_FAILURE);
}
+ err = add_oss_mixers(loop, arg_ossmixers, arg_ossmixers_count);
+ if (err < 0) {
+ logit(LOG_CRIT, "Unable to add ossmixer controls.\n");
+ exit(EXIT_FAILURE);
+ }
#ifdef USE_SAMPLERATE
loop->src_enable = arg_samplerate > 0;
if (loop->src_enable)
diff --git a/alsaloop/alsaloop.h b/alsaloop/alsaloop.h
index 9753c41..366a296 100644
--- a/alsaloop/alsaloop.h
+++ b/alsaloop/alsaloop.h
@@ -65,16 +65,25 @@ struct loopback_control {
};
struct loopback_mixer {
- unsigned int skip: 1;
+ unsigned int skip:1;
struct loopback_control src;
struct loopback_control dst;
struct loopback_mixer *next;
};
+struct loopback_ossmixer {
+ unsigned int skip:1;
+ const char *alsa_id;
+ int alsa_index;
+ const char *oss_id;
+ struct loopback_ossmixer *next;
+};
+
struct loopback_handle {
struct loopback *loopback;
char *device;
char *id;
+ int card_number;
snd_pcm_t *handle;
snd_pcm_access_t access;
snd_pcm_format_t format;
@@ -143,6 +152,7 @@ struct loopback {
snd_timestamp_t tstamp_end;
/* control mixer */
struct loopback_mixer *controls;
+ struct loopback_ossmixer *oss_controls;
/* sample rate */
unsigned int use_samplerate:1;
#ifdef USE_SAMPLERATE
diff --git a/alsaloop/control.c b/alsaloop/control.c
index ade7733..967f1e9 100644
--- a/alsaloop/control.c
+++ b/alsaloop/control.c
@@ -205,6 +205,34 @@ static int copy_value(struct loopback_control *dst,
return 0;
}
+static int oss_set(struct loopback *loop,
+ struct loopback_ossmixer *ossmix,
+ int enable)
+{
+ char buf[128], file[128];
+ int fd;
+
+ if (loop->capt->card_number < 0)
+ return 0;
+ if (!enable) {
+ sprintf(buf, "%s \"\" 0\n", ossmix->oss_id);
+ } else {
+ sprintf(buf, "%s \"%s\" %i\n", ossmix->oss_id, ossmix->alsa_id, ossmix->alsa_index);
+ }
+ sprintf(file, "/proc/asound/card%i/oss_mixer", loop->capt->card_number);
+ if (verbose)
+ snd_output_printf(loop->output, "%s: Initialize OSS volume %s: %s", loop->id, file, buf);
+ fd = open(file, O_WRONLY);
+ if (fd >= 0 && write(fd, buf, strlen(buf)) == strlen(buf)) {
+ close(fd);
+ return 0;
+ }
+ if (fd >= 0)
+ close(fd);
+ logit(LOG_INFO, "%s: Unable to initialize OSS Mixer ID '%s'\n", loop->id, ossmix->oss_id);
+ return -1;
+}
+
static int control_init2(struct loopback *loop,
struct loopback_mixer *mix)
{
@@ -280,12 +308,15 @@ static int control_init2(struct loopback *loop,
int control_init(struct loopback *loop)
{
struct loopback_mixer *mix;
+ struct loopback_ossmixer *ossmix;
int err;
+ for (ossmix = loop->oss_controls; ossmix; ossmix = ossmix->next)
+ oss_set(loop, ossmix, 0);
for (mix = loop->controls; mix; mix = mix->next) {
err = control_init1(loop->play, &mix->src);
if (err < 0) {
- logit(LOG_WARNING, "Disabling playback control '%s'\n", id_str(mix->src.id));
+ logit(LOG_WARNING, "%s: Disabling playback control '%s'\n", loop->id, id_str(mix->src.id));
mix->skip = 1;
continue;
}
@@ -293,22 +324,35 @@ int control_init(struct loopback *loop)
if (err < 0)
return err;
}
+ for (ossmix = loop->oss_controls; ossmix; ossmix = ossmix->next) {
+ err = oss_set(loop, ossmix, 1);
+ if (err < 0) {
+ ossmix->skip = 1;
+ logit(LOG_WARNING, "%s: Disabling OSS mixer ID '%s'\n", loop->id, ossmix->oss_id);
+ }
+ }
return 0;
}
int control_done(struct loopback *loop)
{
struct loopback_mixer *mix;
+ struct loopback_ossmixer *ossmix;
int err;
if (loop->capt->ctl == NULL)
return 0;
+ for (ossmix = loop->oss_controls; ossmix; ossmix = ossmix->next) {
+ err = oss_set(loop, ossmix, 0);
+ if (err < 0)
+ logit(LOG_WARNING, "%s: Unable to remove OSS control '%s'\n", loop->id, ossmix->oss_id);
+ }
for (mix = loop->controls; mix; mix = mix->next) {
if (mix->skip)
continue;
err = snd_ctl_elem_remove(loop->capt->ctl, mix->dst.id);
if (err < 0)
- logit(LOG_WARNING, "Unable to remove control '%s': %s\n", id_str(mix->dst.id), snd_strerror(err));
+ logit(LOG_WARNING, "%s: Unable to remove control '%s': %s\n", loop->id, id_str(mix->dst.id), snd_strerror(err));
}
return 0;
}
diff --git a/alsaloop/pcmjob.c b/alsaloop/pcmjob.c
index 86917ef..5c2fed0 100644
--- a/alsaloop/pcmjob.c
+++ b/alsaloop/pcmjob.c
@@ -1022,6 +1022,7 @@ static int openit(struct loopback_handle *lhandle)
device = snd_pcm_info_get_device(info);
subdevice = snd_pcm_info_get_subdevice(info);
snd_pcm_info_free(info);
+ lhandle->card_number = card;
lhandle->ctl = NULL;
if (card >= 0) {
char name[16];
diff --git a/alsaloop/test.sh b/alsaloop/test.sh
index fbd40c0..13a5ba7 100755
--- a/alsaloop/test.sh
+++ b/alsaloop/test.sh
@@ -10,7 +10,9 @@ test1() {
--tlatency 50000 \
--mixer "name='Master Playback Volume'@name='Master Playback Volume'" \
--mixer "name='Master Playback Switch'@name='Master Playback Switch'" \
- --mixer "name='PCM Playback Volume'"
+ --mixer "name='PCM Playback Volume'" \
+ --ossmixer "Master@VOLUME" \
+ --ossmixer "PCM@PCM"
}
test2() {
--
1.7.3.1
++++++ 0024-alsaloop-Fix-command-line-parsing-and-pollfd-initial.patch ++++++
From e77983d3c55a7822e2151dfd60d9a20ec2023c9f Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Fri, 8 Oct 2010 22:23:05 +0200
Subject: [PATCH 24/38] alsaloop: Fix command-line parsing and pollfd initialization
Signed-off-by: Jaroslav Kysela
---
alsaloop/alsaloop.c | 28 ++++++++++++++++++++--------
alsaloop/control.c | 4 ++++
alsaloop/pcmjob.c | 24 +++++++++++++-----------
alsaloop/test.sh | 18 +++++++++++++++++-
4 files changed, 54 insertions(+), 20 deletions(-)
diff --git a/alsaloop/alsaloop.c b/alsaloop/alsaloop.c
index effa073..97b00d5 100644
--- a/alsaloop/alsaloop.c
+++ b/alsaloop/alsaloop.c
@@ -47,6 +47,8 @@ int daemonize = 0;
int use_syslog = 0;
struct loopback **loopbacks = NULL;
int loopbacks_count = 0;
+char **my_argv = NULL;
+int my_argc = 0;
static void my_exit(struct loopback_thread *thread, int exitcode)
{
@@ -575,9 +577,6 @@ static int parse_config_file(const char *file, snd_output_t *output)
int argc, c, err = 0;
char **argv;
- argv = malloc(sizeof(char *) * MAX_ARGS);
- if (argv == NULL)
- return -ENOMEM;
fp = fopen(file, "r");
if (fp == NULL) {
logit(LOG_CRIT, "Unable to open file '%s': %s\n", file, strerror(errno));
@@ -587,8 +586,13 @@ static int parse_config_file(const char *file, snd_output_t *output)
if (fgets(line, sizeof(line)-1, fp) == NULL)
break;
line[sizeof(line)-1] = '\0';
+ my_argv = realloc(my_argv, my_argc + MAX_ARGS * sizeof(char *));
+ if (my_argv == NULL)
+ return -ENOMEM;
+ argv = my_argv + my_argc;
argc = 0;
argv[argc++] = strdup("<prog>");
+ my_argc++;
str = line;
while (*str) {
ptr = word;
@@ -607,25 +611,30 @@ static int parse_config_file(const char *file, snd_output_t *output)
*ptr++ = *str++;
}
if (ptr != word) {
+ if (*(ptr-1) == '\n')
+ ptr--;
*ptr = '\0';
+ if (argc >= MAX_ARGS) {
+ logit(LOG_CRIT, "Too many arguments.");
+ goto __error;
+ }
argv[argc++] = strdup(word);
+ my_argc++;
}
}
/* erase runtime variables for getopt */
optarg = NULL;
optind = opterr = 1;
- optopt = 63;
+ optopt = '?';
err = parse_config(argc, argv, output);
__next:
- while (argc > 0)
- free(argv[--argc]);
if (err < 0)
break;
err = 0;
}
+ __error:
fclose(fp);
- free(argv);
return err;
}
@@ -656,7 +665,7 @@ static void thread_job1(void *_data)
pfds_count += thread->loopbacks[i]->pollfd_count;
}
pfds = calloc(pfds_count, sizeof(struct pollfd));
- if (pfds == NULL) {
+ if (pfds == NULL || pfds_count <= 0) {
logit(LOG_CRIT, "Poll FDs allocation failed.\n");
my_exit(thread, EXIT_FAILURE);
}
@@ -723,6 +732,9 @@ int main(int argc, char *argv[])
logit(LOG_CRIT, "Unable to parse arguments or configuration...\n");
exit(EXIT_FAILURE);
}
+ while (my_argc > 0)
+ free(my_argv[--my_argc]);
+ free(my_argv);
if (loopbacks_count <= 0) {
logit(LOG_CRIT, "No loopback defined...\n");
diff --git a/alsaloop/control.c b/alsaloop/control.c
index 967f1e9..8383d79 100644
--- a/alsaloop/control.c
+++ b/alsaloop/control.c
@@ -164,6 +164,10 @@ static int control_init1(struct loopback_handle *lhandle,
snd_ctl_elem_info_set_id(ctl->info, ctl->id);
snd_ctl_elem_value_set_id(ctl->value, ctl->id);
+ if (lhandle->ctl == NULL) {
+ logit(LOG_WARNING, "Unable to read control info for '%s'\n", id_str(ctl->id));
+ return -EIO;
+ }
err = snd_ctl_elem_info(lhandle->ctl, ctl->info);
if (err < 0) {
logit(LOG_WARNING, "Unable to read control info '%s': %s\n", id_str(ctl->id), snd_strerror(err));
diff --git a/alsaloop/pcmjob.c b/alsaloop/pcmjob.c
index 5c2fed0..df835f0 100644
--- a/alsaloop/pcmjob.c
+++ b/alsaloop/pcmjob.c
@@ -1195,6 +1195,16 @@ int pcmjob_start(struct loopback *loop)
snd_pcm_uframes_t count;
int err;
+ loop->pollfd_count = loop->play->ctl_pollfd_count +
+ loop->capt->ctl_pollfd_count;
+ if ((err = snd_pcm_poll_descriptors_count(loop->play->handle)) < 0)
+ goto __error;
+ loop->play->pollfd_count = err;
+ loop->pollfd_count += err;
+ if ((err = snd_pcm_poll_descriptors_count(loop->capt->handle)) < 0)
+ goto __error;
+ loop->capt->pollfd_count = err;
+ loop->pollfd_count += err;
if (loop->slave == SLAVE_TYPE_ON) {
err = get_active(loop->capt);
if (err < 0)
@@ -1214,8 +1224,6 @@ int pcmjob_start(struct loopback *loop)
goto __error;
loop->play->channels = loop->capt->channels = err;
}
- loop->pollfd_count = loop->play->ctl_pollfd_count +
- loop->capt->ctl_pollfd_count;
loop->reinit = 0;
loop->use_samplerate = 0;
loop->latency = loop->latency_req;
@@ -1258,14 +1266,6 @@ int pcmjob_start(struct loopback *loop)
if (loop->capt->rate_req != loop->capt->rate)
loop->use_samplerate = 1;
}
- if ((err = snd_pcm_poll_descriptors_count(loop->play->handle)) < 0)
- goto __error;
- loop->play->pollfd_count = err;
- loop->pollfd_count += err;
- if ((err = snd_pcm_poll_descriptors_count(loop->capt->handle)) < 0)
- goto __error;
- loop->capt->pollfd_count = err;
- loop->pollfd_count += err;
#ifdef USE_SAMPLERATE
if (loop->sync == SYNC_TYPE_SAMPLERATE)
loop->use_samplerate = 1;
@@ -1463,9 +1463,11 @@ static int handle_ctl_events(struct loopback_handle *lhandle,
if (lhandle == lhandle->loopback->play)
goto __ctl_check;
if (verbose > 6)
- snd_output_printf(lhandle->loopback->output, "ctl event!!!! %s\n", snd_ctl_event_elem_get_name(ev));
+ snd_output_printf(lhandle->loopback->output, "%s: ctl event!!!! %s\n", lhandle->id, snd_ctl_event_elem_get_name(ev));
if (ctl_event_check(lhandle->ctl_active, ev)) {
err = get_active(lhandle);
+ if (verbose > 7)
+ snd_output_printf(lhandle->loopback->output, "%s: ctl event active %i\n", lhandle->id, err);
if (err != lhandle->loopback->running)
goto __restart;
} else if (ctl_event_check(lhandle->ctl_format, ev)) {
diff --git a/alsaloop/test.sh b/alsaloop/test.sh
index 13a5ba7..91f4cbc 100755
--- a/alsaloop/test.sh
+++ b/alsaloop/test.sh
@@ -2,6 +2,7 @@
#DBG="gdb --args "
#DBG="strace"
+#DBG="valgrind --leak-check=full"
CFGFILE="/tmp/alsaloop.test.cfg"
test1() {
@@ -35,7 +36,8 @@ cat > $CFGFILE < $CFGFILE <
From bee994f509e6829647aa68fd276f5e8821d15445 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Mon, 11 Oct 2010 10:24:14 +0200
Subject: [PATCH 25/38] alsaloop: Fixes and added --workaround option
- added workaround for alsa-lib (pthread configuration parsing issue) -
the workaround must be activated manually using ('--workaround serialopen')
- fixed avail_min initialization (caused high CPU usage or xruns)
- fixed shared buffer initialization (both capture and playback buffers
must have equal number of samples in this config)
Signed-off-by: Jaroslav Kysela
---
alsaloop/Makefile.am | 1 +
alsaloop/alsaloop.c | 9 ++++-
alsaloop/alsaloop.h | 3 +
alsaloop/pcmjob.c | 111 ++++++++++++++++++++++++++++++++++++++------------
alsaloop/test.sh | 26 +++++++-----
5 files changed, 112 insertions(+), 38 deletions(-)
diff --git a/alsaloop/Makefile.am b/alsaloop/Makefile.am
index 97d2e6f..f76eafd 100644
--- a/alsaloop/Makefile.am
+++ b/alsaloop/Makefile.am
@@ -1,5 +1,6 @@
INCLUDES = -I$(top_srcdir)/include
LDADD = -lm
+CFLAGS += -D_GNU_SOURCE
if HAVE_SAMPLERATE
LDADD += -lsamplerate
endif
diff --git a/alsaloop/alsaloop.c b/alsaloop/alsaloop.c
index 97b00d5..3af3dd7 100644
--- a/alsaloop/alsaloop.c
+++ b/alsaloop/alsaloop.c
@@ -43,6 +43,7 @@ struct loopback_thread {
};
int verbose = 0;
+int workarounds = 0;
int daemonize = 0;
int use_syslog = 0;
struct loopback **loopbacks = NULL;
@@ -171,6 +172,7 @@ void help(void)
" ALSA_ID@OSS_ID (for example: \"Master@VOLUME\")\n"
"-e,--effect apply an effect (bandpass filter sweep)\n"
"-v,--verbose verbose mode (more -v means more verbose)\n"
+"-w,--workaround use workaround (serialopen)\n"
);
printf("\nRecognized sample formats are:");
for (k = 0; k < SND_PCM_FORMAT_LAST; ++k) {
@@ -339,6 +341,7 @@ static int parse_config(int argc, char *argv[], snd_output_t *output)
{"thread", 1, NULL, 'T'},
{"mixer", 1, NULL, 'm'},
{"ossmixer", 1, NULL, 'O'},
+ {"workaround", 1, NULL, 'w'},
{NULL, 0, NULL, 0},
};
int err, morehelp;
@@ -370,7 +373,7 @@ static int parse_config(int argc, char *argv[], snd_output_t *output)
while (1) {
int c;
if ((c = getopt_long(argc, argv,
- "hdg:P:C:l:t:F:f:c:r:s:benvA:S:a:m:T:O:",
+ "hdg:P:C:l:t:F:f:c:r:s:benvA:S:a:m:T:O:w:",
long_option, NULL)) < 0)
break;
switch (c) {
@@ -504,6 +507,10 @@ static int parse_config(int argc, char *argv[], snd_output_t *output)
case 'v':
verbose++;
break;
+ case 'w':
+ if (strcasecmp(optarg, "serialopen") == 0)
+ workarounds |= WORKAROUND_SERIALOPEN;
+ break;
}
}
diff --git a/alsaloop/alsaloop.h b/alsaloop/alsaloop.h
index 366a296..6c4f40a 100644
--- a/alsaloop/alsaloop.h
+++ b/alsaloop/alsaloop.h
@@ -40,6 +40,8 @@ enum {
#define FILE_CWRITE "/tmp/alsaloop.craw"
#endif
+#define WORKAROUND_SERIALOPEN (1<<0)
+
typedef enum _sync_type {
SYNC_TYPE_NONE = 0,
SYNC_TYPE_SIMPLE, /* add or remove samples */
@@ -171,6 +173,7 @@ struct loopback {
};
extern int verbose;
+extern int workarounds;
extern int use_syslog;
#define logit(priority, fmt, args...) do { \
diff --git a/alsaloop/pcmjob.c b/alsaloop/pcmjob.c
index df835f0..8b3e568 100644
--- a/alsaloop/pcmjob.c
+++ b/alsaloop/pcmjob.c
@@ -31,9 +31,11 @@
#include
#include
#include
+#include
#include "alsaloop.h"
static int set_rate_shift(struct loopback_handle *lhandle, double pitch);
+static int get_rate(struct loopback_handle *lhandle);
#define SYNCTYPE(v) [SYNC_TYPE_##v] = #v
@@ -56,6 +58,21 @@ static const char *src_types[] = {
SRCTYPE(LINEAR)
};
+static pthread_mutex_t pcm_open_mutex =
+ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+
+static inline void pcm_open_lock(void)
+{
+ if (workarounds & WORKAROUND_SERIALOPEN)
+ pthread_mutex_lock(&pcm_open_mutex);
+}
+
+static inline void pcm_open_unlock(void)
+{
+ if (workarounds & WORKAROUND_SERIALOPEN)
+ pthread_mutex_unlock(&pcm_open_mutex);
+}
+
static inline snd_pcm_uframes_t get_whole_latency(struct loopback *loop)
{
return loop->latency;
@@ -76,7 +93,7 @@ static int setparams_stream(struct loopback_handle *lhandle,
err = snd_pcm_hw_params_any(handle, params);
if (err < 0) {
- logit(LOG_CRIT, "Broken configuration for %s PCM: no configurations available: %s\n", snd_strerror(err), lhandle->id);
+ logit(LOG_CRIT, "Broken configuration for %s PCM: no configurations available: %s\n", lhandle->id, snd_strerror(err));
return err;
}
err = snd_pcm_hw_params_set_rate_resample(handle, params, lhandle->resample);
@@ -153,6 +170,8 @@ static int setparams_bufsize(struct loopback_handle *lhandle,
goto __again;
}
snd_pcm_hw_params_get_buffer_size(params, &periodsize);
+ if (verbose > 6)
+ snd_output_printf(lhandle->loopback->output, "%s: buffer_size=%li\n", lhandle->id, periodsize);
if (lhandle->period_size_req > 0)
periodsize = lhandle->period_size_req;
else
@@ -163,6 +182,8 @@ static int setparams_bufsize(struct loopback_handle *lhandle,
goto __again;
}
snd_pcm_hw_params_get_period_size(params, &periodsize, NULL);
+ if (verbose > 6)
+ snd_output_printf(lhandle->loopback->output, "%s: period_size=%li\n", lhandle->id, periodsize);
if (periodsize != bufsize)
bufsize = periodsize;
snd_pcm_hw_params_get_buffer_size(params, &buffersize);
@@ -175,11 +196,12 @@ static int setparams_bufsize(struct loopback_handle *lhandle,
static int setparams_set(struct loopback_handle *lhandle,
snd_pcm_hw_params_t *params,
- snd_pcm_sw_params_t *swparams)
+ snd_pcm_sw_params_t *swparams,
+ snd_pcm_uframes_t bufsize)
{
snd_pcm_t *handle = lhandle->handle;
int err;
- snd_pcm_uframes_t val, val1;
+ snd_pcm_uframes_t val, period_size, buffer_size;
err = snd_pcm_hw_params(handle, params);
if (err < 0) {
@@ -196,21 +218,29 @@ static int setparams_set(struct loopback_handle *lhandle,
logit(LOG_CRIT, "Unable to set start threshold mode for %s: %s\n", lhandle->id, snd_strerror(err));
return err;
}
- snd_pcm_hw_params_get_period_size(params, &val, NULL);
- snd_pcm_hw_params_get_buffer_size(params, &val1);
+ snd_pcm_hw_params_get_period_size(params, &period_size, NULL);
+ snd_pcm_hw_params_get_buffer_size(params, &buffer_size);
if (lhandle->nblock) {
if (lhandle == lhandle->loopback->play) {
- val = val1 - (2 * val - 4);
+ val = buffer_size - (2 * period_size - 4);
} else {
val = 4;
}
+ if (verbose > 6)
+ snd_output_printf(lhandle->loopback->output, "%s: avail_min1=%li\n", lhandle->id, val);
} else {
if (lhandle == lhandle->loopback->play) {
- snd_pcm_hw_params_get_buffer_size(params, &val1);
- val = val1 - val - val / 2;
+ val = bufsize / 2 + bufsize / 4 + bufsize / 8;
+ if (val > buffer_size / 4)
+ val = buffer_size / 4;
+ val = buffer_size - val;
} else {
- val /= 2;
+ val = bufsize / 2;
+ if (val > buffer_size / 4)
+ val = buffer_size / 4;
}
+ if (verbose > 6)
+ snd_output_printf(lhandle->loopback->output, "%s: avail_min2=%li\n", lhandle->id, val);
}
err = snd_pcm_sw_params_set_avail_min(handle, swparams, val);
if (err < 0) {
@@ -256,11 +286,11 @@ static int setparams(struct loopback *loop, snd_pcm_uframes_t bufsize)
return err;
}
- if ((err = setparams_set(loop->play, p_params, p_swparams)) < 0) {
+ if ((err = setparams_set(loop->play, p_params, p_swparams, bufsize / loop->play->pitch)) < 0) {
logit(LOG_CRIT, "Unable to set sw parameters for %s stream: %s\n", loop->play->id, snd_strerror(err));
return err;
}
- if ((err = setparams_set(loop->capt, c_params, c_swparams)) < 0) {
+ if ((err = setparams_set(loop->capt, c_params, c_swparams, bufsize / loop->capt->pitch)) < 0) {
logit(LOG_CRIT, "Unable to set sw parameters for %s stream: %s\n", loop->capt->id, snd_strerror(err));
return err;
}
@@ -495,6 +525,12 @@ static int readit(struct loopback_handle *lhandle)
int err;
avail = snd_pcm_avail_update(lhandle->handle);
+ if (avail == -EPIPE) {
+ return xrun(lhandle);
+ } else if (avail == -ESTRPIPE) {
+ if ((err = suspend(lhandle)) < 0)
+ return err;
+ }
if (avail > buf_avail(lhandle)) {
lhandle->buf_over += avail - buf_avail(lhandle);
avail = buf_avail(lhandle);
@@ -1008,7 +1044,10 @@ static int openit(struct loopback_handle *lhandle)
SND_PCM_STREAM_PLAYBACK :
SND_PCM_STREAM_CAPTURE;
int err, card, device, subdevice;
- if ((err = snd_pcm_open(&lhandle->handle, lhandle->device, stream, SND_PCM_NONBLOCK)) < 0) {
+ pcm_open_lock();
+ err = snd_pcm_open(&lhandle->handle, lhandle->device, stream, SND_PCM_NONBLOCK);
+ pcm_open_unlock();
+ if (err < 0) {
logit(LOG_CRIT, "%s open error: %s\n", lhandle->id, snd_strerror(err));
return err;
}
@@ -1027,7 +1066,9 @@ static int openit(struct loopback_handle *lhandle)
if (card >= 0) {
char name[16];
sprintf(name, "hw:%i", card);
+ pcm_open_lock();
err = snd_ctl_open(&lhandle->ctl, name, SND_CTL_NONBLOCK);
+ pcm_open_unlock();
if (err < 0) {
logit(LOG_CRIT, "%s [%s] ctl open error: %s\n", lhandle->id, name, snd_strerror(err));
lhandle->ctl = NULL;
@@ -1254,6 +1295,17 @@ int pcmjob_start(struct loopback *loop)
goto __error;
}
loop->play->buf = nbuf;
+ loop->play->buf_size = loop->capt->buf_size;
+ } else if (loop->capt->buf_size < loop->play->buf_size) {
+ char *nbuf = realloc(loop->capt->buf,
+ loop->play->buf_size *
+ loop->play->frame_size);
+ if (nbuf == NULL) {
+ err = -ENOMEM;
+ goto __error;
+ }
+ loop->capt->buf = nbuf;
+ loop->capt->buf_size = loop->play->buf_size;
}
loop->capt->buf = loop->play->buf;
} else {
@@ -1278,7 +1330,7 @@ int pcmjob_start(struct loopback *loop)
if (loop->use_samplerate) {
if (loop->capt->format != SND_PCM_FORMAT_S16 ||
loop->play->format != SND_PCM_FORMAT_S16) {
- logit(LOG_CRIT, "samplerate conversion supports only S16_LE format (%i, %i)\n", loop->play->format, loop->capt->format);
+ logit(LOG_CRIT, "samplerate conversion supports only %s format (play=%s, capt=%s)\n", snd_pcm_format_name(SND_PCM_FORMAT_S16), snd_pcm_format_name(loop->play->format), snd_pcm_format_name(loop->capt->format));
loop->use_samplerate = 0;
err = -EIO;
goto __error;
@@ -1325,6 +1377,8 @@ int pcmjob_start(struct loopback *loop)
logit(LOG_CRIT, "%s: silence error\n", loop->id);
goto __error;
}
+ if (verbose > 4)
+ snd_output_printf(loop->output, "%s: capt->buffer_size = %li, play->buffer_size = %li\n", loop->id, loop->capt->buf_size, loop->play->buf_size);
loop->pitch = 1.0;
update_pitch(loop);
loop->pitch_delta = 1.0 / ((double)loop->capt->rate * 4);
@@ -1334,8 +1388,13 @@ int pcmjob_start(struct loopback *loop)
loop->play->buf_count = count;
if (loop->play->buf == loop->capt->buf)
loop->capt->buf_pos = count;
- if (writeit(loop->play) != count) {
- logit(LOG_CRIT, "%s: initial playback fill error\n", loop->id);
+ err = writeit(loop->play);
+ if (verbose > 4)
+ snd_output_printf(loop->output, "%s: silence queued %i samples\n", loop->id, err);
+ if (count > loop->play->buffer_size)
+ count = loop->play->buffer_size;
+ if (err != count) {
+ logit(LOG_CRIT, "%s: initial playback fill error (%i/%i/%i)\n", loop->id, err, (int)count, loop->play->buffer_size);
err = -EIO;
goto __error;
}
@@ -1511,13 +1570,13 @@ int pcmjob_pollfds_handle(struct loopback *loop, struct pollfd *fds)
if (verbose > 12) {
snd_pcm_sframes_t pdelay, cdelay;
if ((err = snd_pcm_delay(play->handle, &pdelay)) < 0)
- snd_output_printf(loop->output, "%s: delay error: %s\n", play->id, snd_strerror(err));
+ snd_output_printf(loop->output, "%s: delay error: %s / %li / %li\n", play->id, snd_strerror(err), play->buf_size, play->buf_count);
else
- snd_output_printf(loop->output, "%s: delay %li\n", play->id, pdelay);
+ snd_output_printf(loop->output, "%s: delay %li / %li / %li\n", play->id, pdelay, play->buf_size, play->buf_count);
if ((err = snd_pcm_delay(capt->handle, &cdelay)) < 0)
- snd_output_printf(loop->output, "%s: delay error: %s\n", capt->id, snd_strerror(err));
+ snd_output_printf(loop->output, "%s: delay error: %s / %li / %li\n", capt->id, snd_strerror(err), capt->buf_size, capt->buf_count);
else
- snd_output_printf(loop->output, "%s: delay %li\n", capt->id, cdelay);
+ snd_output_printf(loop->output, "%s: delay %li / %li / %li\n", capt->id, cdelay, capt->buf_size, capt->buf_count);
}
idx = 0;
if (loop->running) {
@@ -1570,7 +1629,7 @@ int pcmjob_pollfds_handle(struct loopback *loop, struct pollfd *fds)
}
if (verbose > 9)
snd_output_printf(loop->output, "%s: prevents = 0x%x, crevents = 0x%x\n", loop->id, prevents, crevents);
- if (prevents == 0 && crevents == 0)
+ if (!loop->running)
goto __pcm_end;
do {
ccount = readit(capt);
@@ -1637,22 +1696,22 @@ int pcmjob_pollfds_handle(struct loopback *loop, struct pollfd *fds)
if (verbose > 4)
snd_output_printf(loop->output, "%s: queued %li/%li samples\n", loop->id, pqueued, cqueued);
if (pqueued > 0)
- loop->play->total_queued += pqueued;
+ play->total_queued += pqueued;
if (cqueued > 0)
- loop->capt->total_queued += cqueued;
+ capt->total_queued += cqueued;
if (pqueued > 0 || cqueued > 0)
loop->total_queued_count += 1;
}
if (verbose > 12) {
snd_pcm_sframes_t pdelay, cdelay;
if ((err = snd_pcm_delay(play->handle, &pdelay)) < 0)
- snd_output_printf(loop->output, "%s: end delay error: %s\n", play->id, snd_strerror(err));
+ snd_output_printf(loop->output, "%s: end delay error: %s / %li / %li\n", play->id, snd_strerror(err), play->buf_size, play->buf_count);
else
- snd_output_printf(loop->output, "%s: end delay %li\n", play->id, pdelay);
+ snd_output_printf(loop->output, "%s: end delay %li / %li / %li\n", play->id, pdelay, play->buf_size, play->buf_count);
if ((err = snd_pcm_delay(capt->handle, &cdelay)) < 0)
- snd_output_printf(loop->output, "%s: end delay error: %s\n", capt->id, snd_strerror(err));
+ snd_output_printf(loop->output, "%s: end delay error: %s / %li / %li\n", capt->id, snd_strerror(err), capt->buf_size, capt->buf_count);
else
- snd_output_printf(loop->output, "%s: end delay %li\n", capt->id, cdelay);
+ snd_output_printf(loop->output, "%s: end delay %li / %li / %li\n", capt->id, cdelay, capt->buf_size, capt->buf_count);
}
__pcm_end:
if (verbose > 13) {
diff --git a/alsaloop/test.sh b/alsaloop/test.sh
index 91f4cbc..e3d81b1 100755
--- a/alsaloop/test.sh
+++ b/alsaloop/test.sh
@@ -3,6 +3,7 @@
#DBG="gdb --args "
#DBG="strace"
#DBG="valgrind --leak-check=full"
+ARGS=
CFGFILE="/tmp/alsaloop.test.cfg"
test1() {
@@ -13,7 +14,8 @@ test1() {
--mixer "name='Master Playback Switch'@name='Master Playback Switch'" \
--mixer "name='PCM Playback Volume'" \
--ossmixer "Master@VOLUME" \
- --ossmixer "PCM@PCM"
+ --ossmixer "PCM@PCM" \
+ $ARGS
}
test2() {
@@ -27,7 +29,7 @@ cat > $CFGFILE < $CFGFILE < $CFGFILE <
From 38c2ef96b78d8733957f03b74799d953b83e045d Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Mon, 11 Oct 2010 11:53:50 +0200
Subject: [PATCH 26/38] alsaloop: add --pctl and --cctl options
In some cases it might be usefull to specify another CTL device names.
Add -X/--pctl and -Y/--cctl options.
Signed-off-by: Jaroslav Kysela
---
alsaloop/alsaloop.c | 28 +++++++++++++++++++++++++---
alsaloop/alsaloop.h | 1 +
alsaloop/pcmjob.c | 13 ++++++++-----
3 files changed, 34 insertions(+), 8 deletions(-)
diff --git a/alsaloop/alsaloop.c b/alsaloop/alsaloop.c
index 3af3dd7..1b3505e 100644
--- a/alsaloop/alsaloop.c
+++ b/alsaloop/alsaloop.c
@@ -66,6 +66,7 @@ static void my_exit(struct loopback_thread *thread, int exitcode)
static int create_loopback_handle(struct loopback_handle **_handle,
const char *device,
+ const char *ctldev,
const char *id)
{
char idbuf[1024];
@@ -77,6 +78,15 @@ static int create_loopback_handle(struct loopback_handle **_handle,
if (device == NULL)
device = "hw:0,0";
handle->device = strdup(device);
+ if (handle->device == NULL)
+ return -ENOMEM;
+ if (ctldev) {
+ handle->ctldev = strdup(ctldev);
+ if (handle->ctldev == NULL)
+ return -ENOMEM;
+ } else {
+ handle->ctldev = NULL;
+ }
snprintf(idbuf, sizeof(idbuf)-1, "%s %s", id, device);
idbuf[sizeof(idbuf)-1] = '\0';
handle->id = strdup(idbuf);
@@ -150,6 +160,8 @@ void help(void)
"-d,--daemonize daemonize the main process and use syslog for errors\n"
"-P,--pdevice playback device\n"
"-C,--cdevice capture device\n"
+"-X,--pctl playback ctl device\n"
+"-Y,--cctl capture ctl device\n"
"-l,--latency requested latency in frames\n"
"-t,--tlatency requested latency in usec (1/1000000sec)\n"
"-f,--format sample format\n"
@@ -323,6 +335,8 @@ static int parse_config(int argc, char *argv[], snd_output_t *output)
{"daemonize", 0, NULL, 'd'},
{"pdevice", 1, NULL, 'P'},
{"cdevice", 1, NULL, 'C'},
+ {"pctl", 1, NULL, 'X'},
+ {"cctl", 1, NULL, 'Y'},
{"latency", 1, NULL, 'l'},
{"tlatency", 1, NULL, 't'},
{"format", 1, NULL, 'f'},
@@ -348,6 +362,8 @@ static int parse_config(int argc, char *argv[], snd_output_t *output)
char *arg_config = NULL;
char *arg_pdevice = NULL;
char *arg_cdevice = NULL;
+ char *arg_pctl = NULL;
+ char *arg_cctl = NULL;
unsigned int arg_latency_req = 0;
unsigned int arg_latency_reqtime = 10000;
snd_pcm_format_t arg_format = SND_PCM_FORMAT_S16_LE;
@@ -373,7 +389,7 @@ static int parse_config(int argc, char *argv[], snd_output_t *output)
while (1) {
int c;
if ((c = getopt_long(argc, argv,
- "hdg:P:C:l:t:F:f:c:r:s:benvA:S:a:m:T:O:w:",
+ "hdg:P:C:X:Y:l:t:F:f:c:r:s:benvA:S:a:m:T:O:w:",
long_option, NULL)) < 0)
break;
switch (c) {
@@ -394,6 +410,12 @@ static int parse_config(int argc, char *argv[], snd_output_t *output)
case 'C':
arg_cdevice = strdup(optarg);
break;
+ case 'X':
+ arg_pctl = strdup(optarg);
+ break;
+ case 'Y':
+ arg_cctl = strdup(optarg);
+ break;
case 'l':
err = atoi(optarg);
arg_latency_req = err >= 4 ? err : 4;
@@ -521,12 +543,12 @@ static int parse_config(int argc, char *argv[], snd_output_t *output)
if (arg_config == NULL) {
struct loopback_handle *play;
struct loopback_handle *capt;
- err = create_loopback_handle(&play, arg_pdevice, "playback");
+ err = create_loopback_handle(&play, arg_pdevice, arg_pctl, "playback");
if (err < 0) {
logit(LOG_CRIT, "Unable to create playback handle.\n");
exit(EXIT_FAILURE);
}
- err = create_loopback_handle(&capt, arg_cdevice, "capture");
+ err = create_loopback_handle(&capt, arg_cdevice, arg_cctl, "capture");
if (err < 0) {
logit(LOG_CRIT, "Unable to create capture handle.\n");
exit(EXIT_FAILURE);
diff --git a/alsaloop/alsaloop.h b/alsaloop/alsaloop.h
index 6c4f40a..7516807 100644
--- a/alsaloop/alsaloop.h
+++ b/alsaloop/alsaloop.h
@@ -84,6 +84,7 @@ struct loopback_ossmixer {
struct loopback_handle {
struct loopback *loopback;
char *device;
+ char *ctldev;
char *id;
int card_number;
snd_pcm_t *handle;
diff --git a/alsaloop/pcmjob.c b/alsaloop/pcmjob.c
index 8b3e568..9d1bb01 100644
--- a/alsaloop/pcmjob.c
+++ b/alsaloop/pcmjob.c
@@ -1063,14 +1063,17 @@ static int openit(struct loopback_handle *lhandle)
snd_pcm_info_free(info);
lhandle->card_number = card;
lhandle->ctl = NULL;
- if (card >= 0) {
- char name[16];
- sprintf(name, "hw:%i", card);
+ if (card >= 0 || lhandle->ctldev) {
+ char name[16], *dev = lhandle->ctldev;
+ if (dev == NULL) {
+ sprintf(name, "hw:%i", card);
+ dev = name;
+ }
pcm_open_lock();
- err = snd_ctl_open(&lhandle->ctl, name, SND_CTL_NONBLOCK);
+ err = snd_ctl_open(&lhandle->ctl, dev, SND_CTL_NONBLOCK);
pcm_open_unlock();
if (err < 0) {
- logit(LOG_CRIT, "%s [%s] ctl open error: %s\n", lhandle->id, name, snd_strerror(err));
+ logit(LOG_CRIT, "%s [%s] ctl open error: %s\n", lhandle->id, dev, snd_strerror(err));
lhandle->ctl = NULL;
}
if (lhandle->ctl)
--
1.7.3.1
++++++ 0027-alsaloop-add-pctl-and-cctl-options-to-man-page.patch ++++++
From af61ea60cfabb6b59b29a1e26769a7068a5742e1 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Mon, 11 Oct 2010 11:56:16 +0200
Subject: [PATCH 27/38] alsaloop: add --pctl and --cctl options to man page
Signed-off-by: Jaroslav Kysela # Please enter the commit message for your changes. Lines starting
---
alsaloop/alsaloop.1 | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/alsaloop/alsaloop.1 b/alsaloop/alsaloop.1
index 1554b6e..0b57b59 100644
--- a/alsaloop/alsaloop.1
+++ b/alsaloop/alsaloop.1
@@ -48,6 +48,16 @@ Use given playback device.
Use given capture device.
.TP
+\fI\-X <device>\fP | \fI\-\-pctl=<device>\fP
+
+Use given CTL device for playback.
+
+.TP
+\fI\-Y <device>\fP | \fI\-\-cctl=<device>\fP
+
+Use given CTL device for capture.
+
+.TP
\fI\-l <latency>\fP | \fI\-\-latency=<frames>\fP
Requested latency in frames.
--
1.7.3.1
++++++ 0028-alsaloop-added-xrun-profiling-support-U-xrun-added-S.patch ++++++
++++ 677 lines (skipped)
++++++ 0029-alsaloop-add-U-xrun-to-alsaloop.1-man-page.patch ++++++
From b68986fb4a946ef736295d3b2f24f1e6fab1e77d Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Wed, 13 Oct 2010 23:41:29 +0200
Subject: [PATCH 29/38] alsaloop: add -U/--xrun to alsaloop.1 man page
Signed-off-by: Jaroslav Kysela
---
alsaloop/alsaloop.1 | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/alsaloop/alsaloop.1 b/alsaloop/alsaloop.1
index 0b57b59..65edba1 100644
--- a/alsaloop/alsaloop.1
+++ b/alsaloop/alsaloop.1
@@ -184,6 +184,12 @@ Known OSS attributes:
Verbose mode. Use multiple times to increase verbosity.
+.TP
+\fI\-U\fP | \fI\-\-xrun\fP
+
+Verbose xrun profiling.
+
+
.SH EXAMPLES
.TP
--
1.7.3.1
++++++ 0030-alsaloop-fixes-added-W-wake-option.patch ++++++
From 513a9c7ad179e9786a7d2ff0aa651d42f9674697 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Thu, 14 Oct 2010 11:17:25 +0200
Subject: [PATCH 30/38] alsaloop: fixes, added -W/--wake option
- added -W/--wake option to reduce poll time
- another try to fix the avail_min parameter for playback
- fixed initial silence fill
Signed-off-by: Jaroslav Kysela
---
alsaloop/alsaloop.1 | 4 ++
alsaloop/alsaloop.c | 20 +++++++++--
alsaloop/alsaloop.h | 4 ++
alsaloop/pcmjob.c | 90 ++++++++++++++++++++++++++++++++++++++-------------
alsaloop/test.sh | 17 +++++----
5 files changed, 101 insertions(+), 34 deletions(-)
diff --git a/alsaloop/alsaloop.1 b/alsaloop/alsaloop.1
index 65edba1..048d1e0 100644
--- a/alsaloop/alsaloop.1
+++ b/alsaloop/alsaloop.1
@@ -189,6 +189,10 @@ Verbose mode. Use multiple times to increase verbosity.
Verbose xrun profiling.
+.TP
+\fI\-W <timeout>\fP | \fI\-\-wake=<timeout>\fP
+
+Set process wake timeout.
.SH EXAMPLES
diff --git a/alsaloop/alsaloop.c b/alsaloop/alsaloop.c
index 561fdd7..8710dd1 100644
--- a/alsaloop/alsaloop.c
+++ b/alsaloop/alsaloop.c
@@ -56,6 +56,7 @@ struct loopback_thread *threads;
int threads_count = 0;
pthread_t main_job;
int arg_default_xrun = 0;
+int arg_default_wake = 0;
static void my_exit(struct loopback_thread *thread, int exitcode)
{
@@ -193,6 +194,7 @@ void help(void)
"-v,--verbose verbose mode (more -v means more verbose)\n"
"-w,--workaround use workaround (serialopen)\n"
"-U,--xrun xrun profiling\n"
+"-W,--wake process wake timeout in ms\n"
);
printf("\nRecognized sample formats are:");
for (k = 0; k < SND_PCM_FORMAT_LAST; ++k) {
@@ -395,12 +397,13 @@ static int parse_config(int argc, char *argv[], snd_output_t *output,
char *arg_ossmixers[MAX_MIXERS];
int arg_ossmixers_count = 0;
int arg_xrun = arg_default_xrun;
+ int arg_wake = arg_default_wake;
morehelp = 0;
while (1) {
int c;
if ((c = getopt_long(argc, argv,
- "hdg:P:C:X:Y:l:t:F:f:c:r:s:benvA:S:a:m:T:O:w:U",
+ "hdg:P:C:X:Y:l:t:F:f:c:r:s:benvA:S:a:m:T:O:w:UW:",
long_option, NULL)) < 0)
break;
switch (c) {
@@ -549,6 +552,11 @@ static int parse_config(int argc, char *argv[], snd_output_t *output,
if (cmdline)
arg_default_xrun = 1;
break;
+ case 'W':
+ arg_wake = atoi(optarg);
+ if (cmdline)
+ arg_default_wake = arg_wake;
+ break;
}
}
@@ -587,6 +595,7 @@ static int parse_config(int argc, char *argv[], snd_output_t *output,
loop->slave = arg_slave;
loop->thread = arg_thread;
loop->xrun = arg_xrun;
+ loop->wake = arg_wake;
err = add_mixers(loop, arg_mixers, arg_mixers_count);
if (err < 0) {
logit(LOG_CRIT, "Unable to add mixer controls.\n");
@@ -691,7 +700,7 @@ static void thread_job1(void *_data)
snd_output_t *output = thread->output;
struct pollfd *pfds = NULL;
int pfds_count = 0;
- int i, j, err;
+ int i, j, err, wake = 1000000;
setscheduler();
@@ -709,7 +718,12 @@ static void thread_job1(void *_data)
my_exit(thread, EXIT_FAILURE);
}
pfds_count += thread->loopbacks[i]->pollfd_count;
+ j = thread->loopbacks[i]->wake;
+ if (j > 0 && j < wake)
+ wake = j;
}
+ if (wake >= 1000000)
+ wake = -1;
pfds = calloc(pfds_count, sizeof(struct pollfd));
if (pfds == NULL || pfds_count <= 0) {
logit(LOG_CRIT, "Poll FDs allocation failed.\n");
@@ -727,7 +741,7 @@ static void thread_job1(void *_data)
}
if (verbose > 10)
gettimeofday(&tv1, NULL);
- err = poll(pfds, j, -1);
+ err = poll(pfds, j, wake);
if (err < 0)
err = -errno;
if (verbose > 10) {
diff --git a/alsaloop/alsaloop.h b/alsaloop/alsaloop.h
index 839fc6d..e506427 100644
--- a/alsaloop/alsaloop.h
+++ b/alsaloop/alsaloop.h
@@ -146,6 +146,7 @@ struct loopback {
sync_type_t sync; /* type of sync */
slave_type_t slave;
int thread; /* thread number */
+ unsigned int wake;
/* statistics */
double pitch;
double pitch_delta;
@@ -164,6 +165,9 @@ struct loopback {
snd_timestamp_t xrun_last_check;
snd_pcm_sframes_t xrun_last_pdelay;
snd_pcm_sframes_t xrun_last_cdelay;
+ snd_pcm_uframes_t xrun_buf_pcount;
+ snd_pcm_uframes_t xrun_buf_ccount;
+ unsigned int xrun_out_frames;
long xrun_max_proctime;
double xrun_max_missing;
/* control mixer */
diff --git a/alsaloop/pcmjob.c b/alsaloop/pcmjob.c
index 0f1a853..6aa8bfe 100644
--- a/alsaloop/pcmjob.c
+++ b/alsaloop/pcmjob.c
@@ -83,16 +83,16 @@ static inline snd_pcm_uframes_t get_whole_latency(struct loopback *loop)
}
static inline unsigned long long
- frames_to_time(struct loopback_handle *lhandle,
+ frames_to_time(unsigned int rate,
snd_pcm_uframes_t frames)
{
- return (frames * 1000000ULL) / lhandle->rate;
+ return (frames * 1000000ULL) / rate;
}
-static inline snd_pcm_uframes_t time_to_frames(struct loopback_handle *lhandle,
+static inline snd_pcm_uframes_t time_to_frames(unsigned int rate,
unsigned long long time)
{
- return (time * lhandle->rate) / 1000000ULL;
+ return (time * rate) / 1000000ULL;
}
static int setparams_stream(struct loopback_handle *lhandle,
@@ -245,12 +245,16 @@ static int setparams_set(struct loopback_handle *lhandle,
snd_output_printf(lhandle->loopback->output, "%s: avail_min1=%li\n", lhandle->id, val);
} else {
if (lhandle == lhandle->loopback->play) {
- val = bufsize / 2 + bufsize / 4 + bufsize / 8;
- if (val > buffer_size / 4)
- val = buffer_size / 4;
+ val = bufsize + bufsize / 2;
+ if (val < (period_size * 3) / 4)
+ val = (period_size * 3) / 4;
+ if (val > (buffer_size * 3) / 4)
+ val = (buffer_size * 3) / 4;
val = buffer_size - val;
} else {
val = bufsize / 2;
+ if (val < period_size / 2)
+ val = period_size / 2;
if (val > buffer_size / 4)
val = buffer_size / 4;
}
@@ -372,6 +376,11 @@ static void xrun_profile0(struct loopback *loop)
getcurtimestamp(&loop->xrun_last_update);
loop->xrun_last_pdelay = pdelay;
loop->xrun_last_cdelay = cdelay;
+ loop->xrun_buf_pcount = loop->play->buf_count;
+ loop->xrun_buf_ccount = loop->capt->buf_count;
+#ifdef USE_SAMPLERATE
+ loop->xrun_out_frames = loop->src_out_frames;
+#endif
}
}
@@ -384,27 +393,45 @@ static inline void xrun_profile(struct loopback *loop)
static void xrun_stats0(struct loopback *loop)
{
snd_timestamp_t t;
- double expected, last, wake, check, queued = -1, proc, missing;
+ double expected, last, wake, check, queued = -1, proc, missing = -1;
+ double maxbuf, pfilled, cfilled, cqueued = -1, avail_min;
+ double sincejob;
expected = ((double)loop->latency /
- (double)loop->play->rate) * 1000;
+ (double)loop->play->rate_req) * 1000;
getcurtimestamp(&t);
last = (double)timediff(t, loop->xrun_last_update) / 1000;
wake = (double)timediff(t, loop->xrun_last_wake) / 1000;
check = (double)timediff(t, loop->xrun_last_check) / 1000;
+ sincejob = (double)timediff(t, loop->tstamp_start) / 1000;
if (loop->xrun_last_pdelay != XRUN_PROFILE_UNKNOWN)
- queued = (((double)loop->xrun_last_pdelay *
- loop->play->pitch) /
+ queued = ((double)loop->xrun_last_pdelay /
+ (double)loop->play->rate) * 1000;
+ if (loop->xrun_last_cdelay != XRUN_PROFILE_UNKNOWN)
+ cqueued = ((double)loop->xrun_last_cdelay /
+ (double)loop->capt->rate) * 1000;
+ maxbuf = ((double)loop->play->buffer_size /
(double)loop->play->rate) * 1000;
proc = (double)loop->xrun_max_proctime / 1000;
- missing = last - queued;
- if (loop->xrun_max_missing < missing)
+ pfilled = ((double)(loop->xrun_buf_pcount + loop->xrun_out_frames) /
+ (double)loop->play->rate) * 1000;
+ cfilled = ((double)loop->xrun_buf_ccount /
+ (double)loop->capt->rate) * 1000;
+ avail_min = (((double)loop->play->buffer_size -
+ (double)loop->play->avail_min ) /
+ (double)loop->play->rate) * 1000;
+ avail_min = expected - avail_min;
+ if (queued >= 0)
+ missing = last - queued;
+ if (missing >= 0 && loop->xrun_max_missing < missing)
loop->xrun_max_missing = missing;
loop->xrun_max_proctime = 0;
getcurtimestamp(&t);
- logit(LOG_INFO, " last write before %.4fms, queued %.4fms -> missing %.4fms\n", last, queued, missing);
+ logit(LOG_INFO, " last write before %.4fms, queued %.4fms/%.4fms -> missing %.4fms\n", last, queued, cqueued, missing);
logit(LOG_INFO, " expected %.4fms, processing %.4fms, max missing %.4fms\n", expected, proc, loop->xrun_max_missing);
- logit(LOG_INFO, " last wake before %.4fms, last check before %.4fms\n", wake, check);
+ logit(LOG_INFO, " last wake %.4fms, last check %.4fms, avail_min %.4fms\n", wake, check, avail_min);
+ logit(LOG_INFO, " max buf %.4fms, pfilled %.4fms, cfilled %.4fms\n", maxbuf, pfilled, cfilled);
+ logit(LOG_INFO, " job started before %.4fms\n", sincejob);
}
static inline void xrun_stats(struct loopback *loop)
@@ -483,7 +510,14 @@ static void buf_add_src(struct loopback *loop)
count1 = count;
if (count1 + pos1 > capt->buf_size)
count1 = capt->buf_size - pos1;
- src_short_to_float_array((short *)(capt->buf +
+ if (capt->format == SND_PCM_FORMAT_S32)
+ src_int_to_float_array((int *)(capt->buf +
+ pos1 * capt->frame_size),
+ loop->src_data.data_in +
+ pos * capt->channels,
+ count1 * capt->channels);
+ else
+ src_short_to_float_array((short *)(capt->buf +
pos1 * capt->frame_size),
loop->src_data.data_in +
pos * capt->channels,
@@ -514,7 +548,14 @@ static void buf_add_src(struct loopback *loop)
count1 = buf_avail(play);
if (count1 == 0)
break;
- src_float_to_short_array(loop->src_data.data_out +
+ if (capt->format == SND_PCM_FORMAT_S32)
+ src_float_to_int_array(loop->src_data.data_out +
+ pos * play->channels,
+ (int *)(play->buf +
+ pos1 * play->frame_size),
+ count1 * play->channels);
+ else
+ src_float_to_short_array(loop->src_data.data_out +
pos * play->channels,
(short *)(play->buf +
pos1 * play->frame_size),
@@ -691,12 +732,12 @@ static int writeit(struct loopback_handle *lhandle)
fwrite(lhandle->buf + lhandle->buf_pos * lhandle->frame_size,
r, lhandle->frame_size, lhandle->loopback->pfile);
#endif
- xrun_profile(lhandle->loopback);
res += r;
lhandle->counter += r;
lhandle->buf_count -= r;
lhandle->buf_pos += r;
lhandle->buf_pos %= lhandle->buf_size;
+ xrun_profile(lhandle->loopback);
}
return res;
}
@@ -919,6 +960,7 @@ static int xrun_sync(struct loopback *loop)
snd_output_printf(loop->output, "%s: sync verify: %li\n", loop->id, delay1);
}
}
+ loop->xrun_max_proctime = 0;
return 0;
}
@@ -1344,11 +1386,11 @@ int pcmjob_start(struct loopback *loop)
loop->reinit = 0;
loop->use_samplerate = 0;
if (loop->latency_req) {
- loop->latency_reqtime = frames_to_time(loop->play,
+ loop->latency_reqtime = frames_to_time(loop->play->rate_req,
loop->latency_req);
loop->latency_req = 0;
}
- loop->latency = time_to_frames(loop->play, loop->latency_reqtime);
+ loop->latency = time_to_frames(loop->play->rate_req, loop->latency_reqtime);
if ((err = setparams(loop, loop->latency/2)) < 0)
goto __error;
if (verbose)
@@ -1406,9 +1448,11 @@ int pcmjob_start(struct loopback *loop)
goto __error;
}
if (loop->use_samplerate) {
- if (loop->capt->format != SND_PCM_FORMAT_S16 ||
- loop->play->format != SND_PCM_FORMAT_S16) {
- logit(LOG_CRIT, "samplerate conversion supports only %s format (play=%s, capt=%s)\n", snd_pcm_format_name(SND_PCM_FORMAT_S16), snd_pcm_format_name(loop->play->format), snd_pcm_format_name(loop->capt->format));
+ if ((loop->capt->format != SND_PCM_FORMAT_S16 ||
+ loop->play->format != SND_PCM_FORMAT_S16) &&
+ (loop->capt->format != SND_PCM_FORMAT_S32 ||
+ loop->play->format != SND_PCM_FORMAT_S32)) {
+ logit(LOG_CRIT, "samplerate conversion supports only %s or %s formats (play=%s, capt=%s)\n", snd_pcm_format_name(SND_PCM_FORMAT_S16), snd_pcm_format_name(SND_PCM_FORMAT_S32), snd_pcm_format_name(loop->play->format), snd_pcm_format_name(loop->capt->format));
loop->use_samplerate = 0;
err = -EIO;
goto __error;
diff --git a/alsaloop/test.sh b/alsaloop/test.sh
index ff9aa4e..fac72b9 100755
--- a/alsaloop/test.sh
+++ b/alsaloop/test.sh
@@ -34,19 +34,20 @@ EOF
test3() {
echo "TEST3"
+ LATENCY=180000
cat > $CFGFILE <
From 1ae28cae89a12ed39532bc2a3596e4efa0189e4c Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Thu, 14 Oct 2010 15:39:28 +0200
Subject: [PATCH 31/38] alsaloop: Fix latency print
Signed-off-by: Jaroslav Kysela
---
alsaloop/pcmjob.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/alsaloop/pcmjob.c b/alsaloop/pcmjob.c
index 6aa8bfe..925380c 100644
--- a/alsaloop/pcmjob.c
+++ b/alsaloop/pcmjob.c
@@ -1394,7 +1394,7 @@ int pcmjob_start(struct loopback *loop)
if ((err = setparams(loop, loop->latency/2)) < 0)
goto __error;
if (verbose)
- showlatency(loop->output, loop->latency, loop->play->rate, "Latency");
+ showlatency(loop->output, loop->latency, loop->play->rate_req, "Latency");
if (loop->play->access == loop->capt->access &&
loop->play->format == loop->capt->format &&
loop->play->rate == loop->capt->rate &&
--
1.7.3.1
++++++ 0032-speaker-test-Don-t-retry-after-fatal-errors.patch ++++++
From b67d215d20bcf546617de962dec60cc29b238e4e Mon Sep 17 00:00:00 2001
From: David Henningsson
Date: Fri, 15 Oct 2010 12:30:44 +0200
Subject: [PATCH 32/38] speaker-test: Don't retry after fatal errors
Fixup commit 9b1a2566: Remove error loop
Signed-off-by: David Henningsson
Signed-off-by: Takashi Iwai
---
speaker-test/speaker-test.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/speaker-test/speaker-test.c b/speaker-test/speaker-test.c
index 458a8d7..3029110 100644
--- a/speaker-test/speaker-test.c
+++ b/speaker-test/speaker-test.c
@@ -993,9 +993,9 @@ int main(int argc, char *argv[]) {
}
- while ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
+ if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
printf(_("Playback open error: %d,%s\n"), err,snd_strerror(err));
- sleep(1);
+ exit(EXIT_FAILURE);
}
if ((err = set_hwparams(handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
--
1.7.3.1
++++++ 0033-alsaloop-Delay-the-restart-a-bit-to-handle-snd-aloop.patch ++++++
From d53eb0309df34f058b33c18210c8949c8a2d8b8e Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Wed, 20 Oct 2010 09:26:24 +0200
Subject: [PATCH 33/38] alsaloop: Delay the restart a bit (to handle snd-aloop playback xruns better)
Signed-off-by: Jaroslav Kysela
---
alsaloop/alsaloop.h | 2 ++
alsaloop/pcmjob.c | 33 ++++++++++++++++++++++++++-------
2 files changed, 28 insertions(+), 7 deletions(-)
diff --git a/alsaloop/alsaloop.h b/alsaloop/alsaloop.h
index e506427..8dc445a 100644
--- a/alsaloop/alsaloop.h
+++ b/alsaloop/alsaloop.h
@@ -143,6 +143,8 @@ struct loopback {
unsigned int linked:1; /* linked streams */
unsigned int reinit:1;
unsigned int running:1;
+ unsigned int stop_pending:1;
+ snd_pcm_uframes_t stop_count;
sync_type_t sync; /* type of sync */
slave_type_t slave;
int thread; /* thread number */
diff --git a/alsaloop/pcmjob.c b/alsaloop/pcmjob.c
index 925380c..23270a0 100644
--- a/alsaloop/pcmjob.c
+++ b/alsaloop/pcmjob.c
@@ -738,6 +738,15 @@ static int writeit(struct loopback_handle *lhandle)
lhandle->buf_pos += r;
lhandle->buf_pos %= lhandle->buf_size;
xrun_profile(lhandle->loopback);
+ if (lhandle->loopback->stop_pending) {
+ lhandle->loopback->stop_count += r;
+ if (lhandle->loopback->stop_count * lhandle->pitch >
+ lhandle->loopback->latency * 3) {
+ lhandle->loopback->stop_pending = 0;
+ lhandle->loopback->reinit = 1;
+ break;
+ }
+ }
}
return res;
}
@@ -1521,6 +1530,7 @@ int pcmjob_start(struct loopback *loop)
goto __error;
}
loop->running = 1;
+ loop->stop_pending = 0;
if (loop->xrun) {
getcurtimestamp(&loop->xrun_last_update);
loop->xrun_last_pdelay = XRUN_PROFILE_UNKNOWN;
@@ -1638,6 +1648,7 @@ static int ctl_event_check(snd_ctl_elem_value_t *val, snd_ctl_event_t *ev)
static int handle_ctl_events(struct loopback_handle *lhandle,
unsigned short events)
{
+ struct loopback *loop = lhandle->loopback;
snd_ctl_event_t *ev;
int err;
@@ -1647,16 +1658,24 @@ static int handle_ctl_events(struct loopback_handle *lhandle,
break;
if (snd_ctl_event_get_type(ev) != SND_CTL_EVENT_ELEM)
continue;
- if (lhandle == lhandle->loopback->play)
+ if (lhandle == loop->play)
goto __ctl_check;
if (verbose > 6)
- snd_output_printf(lhandle->loopback->output, "%s: ctl event!!!! %s\n", lhandle->id, snd_ctl_event_elem_get_name(ev));
+ snd_output_printf(loop->output, "%s: ctl event!!!! %s\n", lhandle->id, snd_ctl_event_elem_get_name(ev));
if (ctl_event_check(lhandle->ctl_active, ev)) {
err = get_active(lhandle);
if (verbose > 7)
- snd_output_printf(lhandle->loopback->output, "%s: ctl event active %i\n", lhandle->id, err);
- if (err != lhandle->loopback->running)
- goto __restart;
+ snd_output_printf(loop->output, "%s: ctl event active %i\n", lhandle->id, err);
+ if (!err) {
+ if (lhandle->loopback->running) {
+ loop->stop_pending = 1;
+ loop->stop_count = 0;
+ }
+ } else {
+ loop->stop_pending = 0;
+ if (loop->running == 0)
+ goto __restart;
+ }
} else if (ctl_event_check(lhandle->ctl_format, ev)) {
err = get_format(lhandle);
if (lhandle->format != err)
@@ -1676,8 +1695,8 @@ static int handle_ctl_events(struct loopback_handle *lhandle,
return 0;
__restart:
- pcmjob_stop(lhandle->loopback);
- err = pcmjob_start(lhandle->loopback);
+ pcmjob_stop(loop);
+ err = pcmjob_start(loop);
if (err < 0)
return err;
return 1;
--
1.7.3.1
++++++ 0034-alsaloop-rework-the-ctl-event-handling-routine.patch ++++++
From 7a11a2b5464e86573f01af6cf4637ffdc0351478 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela
Date: Thu, 21 Oct 2010 20:38:06 +0200
Subject: [PATCH 34/38] alsaloop: rework the ctl event handling routine
Signed-off-by: Jaroslav Kysela
---
alsaloop/pcmjob.c | 51 +++++++++++++++++++++++++++------------------------
1 files changed, 27 insertions(+), 24 deletions(-)
diff --git a/alsaloop/pcmjob.c b/alsaloop/pcmjob.c
index 23270a0..0b84803 100644
--- a/alsaloop/pcmjob.c
+++ b/alsaloop/pcmjob.c
@@ -1650,7 +1650,7 @@ static int handle_ctl_events(struct loopback_handle *lhandle,
{
struct loopback *loop = lhandle->loopback;
snd_ctl_event_t *ev;
- int err;
+ int err, restart = 0;
snd_ctl_event_alloca(&ev);
while ((err = snd_ctl_read(lhandle->ctl, ev)) != 0 && err != -EAGAIN) {
@@ -1663,42 +1663,45 @@ static int handle_ctl_events(struct loopback_handle *lhandle,
if (verbose > 6)
snd_output_printf(loop->output, "%s: ctl event!!!! %s\n", lhandle->id, snd_ctl_event_elem_get_name(ev));
if (ctl_event_check(lhandle->ctl_active, ev)) {
- err = get_active(lhandle);
- if (verbose > 7)
- snd_output_printf(loop->output, "%s: ctl event active %i\n", lhandle->id, err);
- if (!err) {
- if (lhandle->loopback->running) {
- loop->stop_pending = 1;
- loop->stop_count = 0;
- }
- } else {
- loop->stop_pending = 0;
- if (loop->running == 0)
- goto __restart;
- }
+ continue;
} else if (ctl_event_check(lhandle->ctl_format, ev)) {
err = get_format(lhandle);
if (lhandle->format != err)
- goto __restart;
+ restart = 1;
+ continue;
} else if (ctl_event_check(lhandle->ctl_rate, ev)) {
err = get_rate(lhandle);
if (lhandle->rate != err)
- goto __restart;
+ restart = 1;
+ continue;
} else if (ctl_event_check(lhandle->ctl_channels, ev)) {
err = get_channels(lhandle);
if (lhandle->channels != err)
- goto __restart;
+ restart = 1;
+ continue;
}
__ctl_check:
control_event(lhandle, ev);
}
- return 0;
-
- __restart:
- pcmjob_stop(loop);
- err = pcmjob_start(loop);
- if (err < 0)
- return err;
+ err = get_active(lhandle);
+ if (verbose > 7)
+ snd_output_printf(loop->output, "%s: ctl event active %i\n", lhandle->id, err);
+ if (!err) {
+ if (lhandle->loopback->running) {
+ loop->stop_pending = 1;
+ loop->stop_count = 0;
+ }
+ } else {
+ loop->stop_pending = 0;
+ if (loop->running == 0)
+ restart = 1;
+ }
+ if (restart) {
+ pcmjob_stop(loop);
+ err = pcmjob_start(loop);
+ if (err < 0)
+ return err;
+ }
return 1;
}
--
1.7.3.1
++++++ 0035-alsamixer-remove-obsolete-e-mail.patch ++++++
From f2e9e9a5b017a3834941256da52e1d608f9c4c7b Mon Sep 17 00:00:00 2001
From: Clemens Ladisch
Date: Wed, 10 Nov 2010 10:14:53 +0100
Subject: [PATCH 35/38] alsamixer: remove obsolete e-mail
Tim Janik's e-mail address is no longer valid.
Signed-off-by: Clemens Ladisch
---
alsamixer/cli.c | 2 +-
alsamixer/colors.c | 2 +-
alsamixer/mixer_controls.c | 2 +-
alsamixer/mixer_widget.c | 4 ++--
alsamixer/textbox.c | 2 +-
5 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/alsamixer/cli.c b/alsamixer/cli.c
index ab6255f..3898196 100644
--- a/alsamixer/cli.c
+++ b/alsamixer/cli.c
@@ -1,6 +1,6 @@
/*
* alsamixer - curses mixer for the ALSA project
- * Copyright (c) 1998,1999 Tim Janik
+ * Copyright (c) 1998,1999 Tim Janik
* Jaroslav Kysela
* Copyright (c) 2009 Clemens Ladisch
*
diff --git a/alsamixer/colors.c b/alsamixer/colors.c
index fcceb16..b4b98e5 100644
--- a/alsamixer/colors.c
+++ b/alsamixer/colors.c
@@ -1,6 +1,6 @@
/*
* colors.c - color and attribute definitions
- * Copyright (c) 1998,1999 Tim Janik
+ * Copyright (c) 1998,1999 Tim Janik
* Jaroslav Kysela
* Copyright (c) 2009 Clemens Ladisch
*
diff --git a/alsamixer/mixer_controls.c b/alsamixer/mixer_controls.c
index 796df7b..cc98b64 100644
--- a/alsamixer/mixer_controls.c
+++ b/alsamixer/mixer_controls.c
@@ -1,6 +1,6 @@
/*
* mixer_controls.c - handles mixer controls and mapping from selems
- * Copyright (c) 1998,1999 Tim Janik
+ * Copyright (c) 1998,1999 Tim Janik
* Jaroslav Kysela
* Copyright (c) 2009 Clemens Ladisch
*
diff --git a/alsamixer/mixer_widget.c b/alsamixer/mixer_widget.c
index 796ea1d..c8ca156 100644
--- a/alsamixer/mixer_widget.c
+++ b/alsamixer/mixer_widget.c
@@ -1,6 +1,6 @@
/*
* mixer_widget.c - mixer widget and keys handling
- * Copyright (c) 1998,1999 Tim Janik
+ * Copyright (c) 1998,1999 Tim Janik
* Jaroslav Kysela
* Copyright (c) 2009 Clemens Ladisch
*
@@ -211,7 +211,7 @@ static void show_help(void)
_("; ' Toggle left/right capture"),
"",
_("Authors:"),
- _(" Tim Janik "),
+ _(" Tim Janik"),
_(" Jaroslav Kysela "),
_(" Clemens Ladisch "),
};
diff --git a/alsamixer/textbox.c b/alsamixer/textbox.c
index d743a14..a979d3c 100644
--- a/alsamixer/textbox.c
+++ b/alsamixer/textbox.c
@@ -1,6 +1,6 @@
/*
* textbox.c - show a text box for messages, files or help
- * Copyright (c) 1998,1999 Tim Janik
+ * Copyright (c) 1998,1999 Tim Janik
* Jaroslav Kysela
* Copyright (c) 2009 Clemens Ladisch
*
--
1.7.3.1
++++++ 0036-update-German-translations.patch ++++++
++++ 1170 lines (skipped)
++++++ 0037-alsactl-systemd-and-udev-hookup.patch ++++++
From de7c3eff0e371ce155403bbcdcf81ee79266fa0f Mon Sep 17 00:00:00 2001
From: Lennart Poettering
Date: Tue, 23 Nov 2010 01:45:08 +0100
Subject: [PATCH 37/38] alsactl: systemd and udev hookup
Add minimal systemd and udev support to alsactl so that mixer settings
are restored at boot, when sound cards are plugged in and saved on
shutdown.
This is similar to existing udev/init script solutions in various
distributions.
Note that alsactl is called both synchronously from the udev rules as
well as asynchronously at boot. This is intended, and to ensure two
things:
- At boot the asound.state file might not be readable, since it resides
on a different file system. That means exclusively restoring sound card
settings from udev rules will no suffice, since if the rule is
executed at early boot (for example within udev settle) then the file
will no be readable and cannot be restored.
- We need to ensure that applications monitoring sound cards coming and
going (such as PA) must not get these events before the mixer settings
have been restored. That means the mixer settings must be restored
synchronously withing the udev rules, before the events are passed on
to the apps.
That basically means we need to restore the settings once in udev, to
deal with sound cards becoming available during runtime. And once in
early boot to deal with coldplugged soundcards whose data files might
not have been available at time of plugging. Hence we call alsactl
twice: one from the udev rule, and once from he systemd unit file.
Signed-off-by: Lennart Poettering
Signed-off-by: Jaroslav Kysela
---
Makefile.am | 3 ++
alsactl/90-alsa-restore.rules.in | 2 +
alsactl/Makefile.am | 46 ++++++++++++++++++++++++++++++++++++++
alsactl/alsa-restore.service.in | 11 +++++++++
alsactl/alsa-store.service.in | 9 +++++++
configure.in | 17 +++++++++++--
7 files changed, 88 insertions(+), 3 deletions(-)
create mode 100644 alsactl/90-alsa-restore.rules.in
create mode 100644 alsactl/alsa-restore.service.in
create mode 100644 alsactl/alsa-store.service.in
diff --git a/Makefile.am b/Makefile.am
index 9951c46..62e1ba6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -37,3 +37,6 @@ dist-hook:
else \
$(TAR) --create --verbose --file=- $(distdir) | bzip2 -c -9 > $(distdir).tar.bz2 ; \
fi
+
+DISTCHECK_CONFIGURE_FLAGS = \
+ --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
diff --git a/alsactl/90-alsa-restore.rules.in b/alsactl/90-alsa-restore.rules.in
new file mode 100644
index 0000000..0bcee5b
--- /dev/null
+++ b/alsactl/90-alsa-restore.rules.in
@@ -0,0 +1,2 @@
+ACTION=="add", SUBSYSTEM=="sound", KERNEL=="controlC*", KERNELS=="card*", \
+ RUN+="@sbindir@/alsactl restore $attr{number}"
diff --git a/alsactl/Makefile.am b/alsactl/Makefile.am
index 359f73a..9a2d30e 100644
--- a/alsactl/Makefile.am
+++ b/alsactl/Makefile.am
@@ -10,5 +10,51 @@ EXTRA_DIST=alsactl.1 alsactl_init.xml
alsactl_SOURCES=alsactl.c state.c utils.c init_parse.c
noinst_HEADERS=alsactl.h list.h init_sysdeps.c init_utils_string.c init_utils_run.c init_sysfs.c
+udevrulesdir=/lib/udev/rules.d
+
+dist_udevrules_DATA = \
+ 90-alsa-restore.rules
+
+if HAVE_SYSTEMD
+
+systemdsystemunit_DATA = \
+ alsa-store.service \
+ alsa-restore.service
+
+install-data-hook:
+ $(MKDIR_P) -m 0755 \
+ $(DESTDIR)$(systemdsystemunitdir)/basic.target.wants \
+ $(DESTDIR)$(systemdsystemunitdir)/shutdown.target.wants
+ ( cd $(DESTDIR)$(systemdsystemunitdir)/basic.target.wants && \
+ rm -f alsa-restore.service && \
+ $(LN_S) ../alsa-restore.service alsa-restore.service )
+ ( cd $(DESTDIR)$(systemdsystemunitdir)/shutdown.target.wants && \
+ rm -f alsa-store.service && \
+ $(LN_S) ../alsa-store.service alsa-store.service )
+
+endif
+
+edit = \
+ sed $(SED) -r 's,@sbindir\@,$(sbindir),g' < $< > $@ || rm $@
+
+alsa-store.service: alsa-store.service.in
+ $(edit)
+
+alsa-restore.service: alsa-restore.service.in
+ $(edit)
+
+90-alsa-restore.rules: 90-alsa-restore.rules.in
+ $(edit)
+
+EXTRA_DIST += \
+ alsa-store.service.in \
+ alsa-restore.service.in \
+ 90-alsa-restore.rules.in
+
+CLEANFILES = \
+ alsa-store.service \
+ alsa-restore.service \
+ 90-alsa-restore.rules
+
%.7: %.xml
xmlto man $?
diff --git a/alsactl/alsa-restore.service.in b/alsactl/alsa-restore.service.in
new file mode 100644
index 0000000..e97d196
--- /dev/null
+++ b/alsactl/alsa-restore.service.in
@@ -0,0 +1,11 @@
+[Unit]
+Description=Restore Sound Card State
+DefaultDependencies=no
+After=sysinit.target
+Before=shutdown.target
+Conflicts=shutdown.target
+
+[Service]
+Type=oneshot
+ExecStart=-@sbindir@/alsactl restore
+StandardOutput=syslog
diff --git a/alsactl/alsa-store.service.in b/alsactl/alsa-store.service.in
new file mode 100644
index 0000000..0e2823c
--- /dev/null
+++ b/alsactl/alsa-store.service.in
@@ -0,0 +1,9 @@
+[Unit]
+Description=Store Sound Card State
+DefaultDependencies=no
+Before=shutdown.target
+
+[Service]
+Type=oneshot
+ExecStart=@sbindir@/alsactl store
+StandardOutput=syslog
diff --git a/configure.in b/configure.in
index 31fd581..54ea74c 100644
--- a/configure.in
+++ b/configure.in
@@ -26,6 +26,7 @@ fi
AC_PROG_CC
dnl AC_PROG_CXX
AC_PROG_INSTALL
+AC_PROG_MKDIR_P
AC_PROG_LN_S
AM_PATH_ALSA(1.0.16)
@@ -130,7 +131,7 @@ if test x$alsamixer = xtrue; then
CURSES_CFLAGS=`ncursesw5-config --cflags`
curseslib="ncursesw"
else
- AC_CHECK_LIB(ncursesw, initscr,
+ AC_CHECK_LIB(ncursesw, initscr,
[ CURSESINC=''; CURSESLIB='-lncursesw'; curseslib="ncursesw"])
fi
if test -n "$CURSESINC"; then
@@ -147,12 +148,12 @@ if test x$alsamixer = xtrue; then
CURSES_CFLAGS=`ncurses5-config --cflags`
curseslib="ncurses"
else
- AC_CHECK_LIB(ncurses, initscr,
+ AC_CHECK_LIB(ncurses, initscr,
[ CURSESINC=''; CURSESLIB='-lncurses'; curseslib="ncurses"])
fi
fi
if test "$curseslib" = "curses" -o "$curseslib" = "auto"; then
- AC_CHECK_LIB(curses, initscr,
+ AC_CHECK_LIB(curses, initscr,
[ CURSESINC=''; CURSESLIB='-lcurses'; curseslib="curses"])
fi
if test -z "$CURSESINC"; then
@@ -278,6 +279,16 @@ SAVE_UTIL_VERSION
AC_SUBST(LIBRT)
+dnl Check for systemd
+PKG_PROG_PKG_CONFIG
+AC_ARG_WITH([systemdsystemunitdir],
+ AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
+ [], [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)])
+if test "x$with_systemdsystemunitdir" != xno; then
+ AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
+fi
+AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ])
+
AC_OUTPUT(Makefile alsactl/Makefile alsactl/init/Makefile \
alsamixer/Makefile amidi/Makefile amixer/Makefile \
m4/Makefile po/Makefile.in \
--
1.7.3.1
++++++ 0038-alsactl-Move-asound.state-location-to-var-lib-alsa.patch ++++++
From 81f015f5abdd8e6cfa75e37bd97eb22781019eec Mon Sep 17 00:00:00 2001
From: Lennart Poettering
Date: Tue, 23 Nov 2010 02:59:18 +0100
Subject: [PATCH 38/38] alsactl: Move asound.state location to /var/lib/alsa
.... and add configure switch for it.
/etc might be on a read-only partition which is not suitable for dynamic
data such as the mixer settings. Hence move the location of asound.state
to /var/lib.
This is based on a patch from Ubuntu/Debian which hardcoded the pah in
/var/lib.
Signed-off-by: Lennart Poettering
Signed-off-by: Jaroslav Kysela
---
Makefile.am | 3 +++
alsaconf/alsaconf.in | 5 +++--
alsactl/Makefile.am | 1 +
alsactl/alsactl.1 | 4 ++--
alsactl/alsactl.c | 4 +++-
configure.in | 6 ++++++
6 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 62e1ba6..48a4780 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -38,5 +38,8 @@ dist-hook:
$(TAR) --create --verbose --file=- $(distdir) | bzip2 -c -9 > $(distdir).tar.bz2 ; \
fi
+install-data-hook:
+ $(MKDIR_P) -m 0755 $(DESTDIR)$(ASOUND_STATE_DIR)
+
DISTCHECK_CONFIGURE_FLAGS = \
--with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
diff --git a/alsaconf/alsaconf.in b/alsaconf/alsaconf.in
index ccc1b37..5c23787 100644
--- a/alsaconf/alsaconf.in
+++ b/alsaconf/alsaconf.in
@@ -956,8 +956,9 @@ If you have a big amplifier, lower your volumes or say no.
aplay -N $TESTSOUND
fi
fi
- if [ ! -r /etc/asound.state ]; then
- xecho "Saving the mixer setup used for this in /etc/asound.state."
+ mkdir -p -m 0755 @ASOUND_STATE_DIR@
+ if [ ! -r @ASOUND_STATE_DIR@/asound.state ]; then
+ xecho "Saving the mixer setup used for this in @ASOUND_STATE_DIR@/asound.state."
$sbindir/alsactl store
fi
clear
diff --git a/alsactl/Makefile.am b/alsactl/Makefile.am
index 9a2d30e..721b619 100644
--- a/alsactl/Makefile.am
+++ b/alsactl/Makefile.am
@@ -8,6 +8,7 @@ endif
EXTRA_DIST=alsactl.1 alsactl_init.xml
alsactl_SOURCES=alsactl.c state.c utils.c init_parse.c
+alsactl_CFLAGS=$(AM_CFLAGS) -DSYS_ASOUNDRC=\"$(ASOUND_STATE_DIR)/asound.state\"
noinst_HEADERS=alsactl.h list.h init_sysdeps.c init_utils_string.c init_utils_run.c init_sysfs.c
udevrulesdir=/lib/udev/rules.d
diff --git a/alsactl/alsactl.1 b/alsactl/alsactl.1
index eb3cbd1..eb5968c 100644
--- a/alsactl/alsactl.1
+++ b/alsactl/alsactl.1
@@ -43,7 +43,7 @@ Print alsactl version number.
.TP
\fI\-f, \-\-file\fP
-Select the configuration file to use. The default is /etc/asound.state.
+Select the configuration file to use. The default is /var/lib/alsa/asound.state.
.TP
\fI\-F, \-\-force\fP
@@ -90,7 +90,7 @@ The configuration file for init. By default, PREFIX/share/alsa/init/00main
is used.
.SH FILES
-\fI/etc/asound.state\fP (or whatever file you specify with the
+\fI/var/lib/alsa/asound.state\fP (or whatever file you specify with the
\fB\-f\fP flag) is used to store current settings for your
soundcards. The settings include all the usual soundcard mixer
settings. More importantly, alsactl is
diff --git a/alsactl/alsactl.c b/alsactl/alsactl.c
index 3b5dfda..c2120bd 100644
--- a/alsactl/alsactl.c
+++ b/alsactl/alsactl.c
@@ -30,7 +30,9 @@
#include
#include "alsactl.h"
-#define SYS_ASOUNDRC "/etc/asound.state"
+#ifndef SYS_ASOUNDRC
+#define SYS_ASOUNDRC "/var/lib/alsa/asound.state"
+#endif
int debugflag = 0;
int force_restore = 1;
diff --git a/configure.in b/configure.in
index 54ea74c..94a2b17 100644
--- a/configure.in
+++ b/configure.in
@@ -289,6 +289,12 @@ if test "x$with_systemdsystemunitdir" != xno; then
fi
AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ])
+AC_ARG_WITH(ASOUND_STATE_DIR,
+ AS_HELP_STRING([--with-asound-state-dir=DIR], [Directory to place asound.state file in]),
+ [ASOUND_STATE_DIR="$withval"],
+ [ASOUND_STATE_DIR="/var/lib/alsa"])
+AC_SUBST(ASOUND_STATE_DIR)
+
AC_OUTPUT(Makefile alsactl/Makefile alsactl/init/Makefile \
alsamixer/Makefile amidi/Makefile amixer/Makefile \
m4/Makefile po/Makefile.in \
--
1.7.3.1
++++++ 0039-configure.in-Fix-variable-name.patch ++++++
From 53b08bfc1451937bb19a86e4b116d28cd15c81ac Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ozan=20=C3=87a=C4=9Flayan?=
Date: Thu, 25 Nov 2010 09:36:37 +0200
Subject: [PATCH] configure.in: Fix variable name
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fix variable name for --with-asound-state-dir as currently we have
to pass --with-ASOUND_STATE_DIR= which is wrong and inconsistent with
the other switches.
Signed-off-by: Ozan Çağlayan
Signed-off-by: Takashi Iwai
---
configure.in | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/configure.in b/configure.in
index 94a2b17..77778da 100644
--- a/configure.in
+++ b/configure.in
@@ -289,7 +289,7 @@ if test "x$with_systemdsystemunitdir" != xno; then
fi
AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ])
-AC_ARG_WITH(ASOUND_STATE_DIR,
+AC_ARG_WITH([asound-state-dir],
AS_HELP_STRING([--with-asound-state-dir=DIR], [Directory to place asound.state file in]),
[ASOUND_STATE_DIR="$withval"],
[ASOUND_STATE_DIR="/var/lib/alsa"])
--
1.7.3.1
++++++ alsa-utils-po-pre-patch.diff ++++++
++++ 2200 lines (skipped)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Remember to have fun...
--
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org