forked from pool/alsa-utils
Accepting request 55434 from home:tiwai:branches:multimedia:libs
OBS-URL: https://build.opensuse.org/request/show/55434 OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/alsa-utils?expand=0&rev=29
This commit is contained in:
parent
afb2a445da
commit
24132c8d0f
@ -0,0 +1,53 @@
|
|||||||
|
From a97bcd19dcea98be86f15c6af0b5e0a8d234d190 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Colin Guthrie <cguthrie@mandriva.org>
|
||||||
|
Date: Thu, 25 Nov 2010 21:40:25 +0000
|
||||||
|
Subject: [PATCH 40/43] alsactl: Add a --with-udev-rules-dir configure option.
|
||||||
|
|
||||||
|
After the previous patch to install udev rules it is impossible to do a
|
||||||
|
non-root, custom-prefix make install. This is generally not a problem
|
||||||
|
when building official packages but it can be a pain for developers
|
||||||
|
and debuggers etc.
|
||||||
|
|
||||||
|
This is essentially the same patch as was already made in PulseAudio
|
||||||
|
in commit e8a5746f2fcae59bfd18d39b621509b3ef130453.
|
||||||
|
|
||||||
|
Signed-off-by: Colin Guthrie <gmane@colin.guthr.ie>
|
||||||
|
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
||||||
|
---
|
||||||
|
alsactl/Makefile.am | 2 --
|
||||||
|
configure.in | 6 ++++++
|
||||||
|
2 files changed, 6 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/alsactl/Makefile.am b/alsactl/Makefile.am
|
||||||
|
index 721b619..5cfc415 100644
|
||||||
|
--- a/alsactl/Makefile.am
|
||||||
|
+++ b/alsactl/Makefile.am
|
||||||
|
@@ -11,8 +11,6 @@ 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
|
||||||
|
-
|
||||||
|
dist_udevrules_DATA = \
|
||||||
|
90-alsa-restore.rules
|
||||||
|
|
||||||
|
diff --git a/configure.in b/configure.in
|
||||||
|
index 77778da..2d6c80c 100644
|
||||||
|
--- a/configure.in
|
||||||
|
+++ b/configure.in
|
||||||
|
@@ -112,6 +112,12 @@ if test x"$alsaconf" = xtrue; then
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL(USE_XMLTO, test x"$xmlto" = xyes)
|
||||||
|
|
||||||
|
+AC_ARG_WITH(
|
||||||
|
+ [udev-rules-dir],
|
||||||
|
+ AS_HELP_STRING([--with-udev-rules-dir],[Directory where to install udev rules to (defaults to /lib/udev/rules.d)]),
|
||||||
|
+ [udevrulesdir=$withval], [udevrulesdir="/lib/udev/rules.d"])
|
||||||
|
+AC_SUBST(udevrulesdir)
|
||||||
|
+
|
||||||
|
dnl Checks for header files.
|
||||||
|
AC_HEADER_STDC
|
||||||
|
if test x$alsamixer = xtrue; then
|
||||||
|
--
|
||||||
|
1.7.3.1
|
||||||
|
|
28
0041-alsamixer-remove-obsolete-e-mail.patch
Normal file
28
0041-alsamixer-remove-obsolete-e-mail.patch
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
From e57f619c82e2fec20c20c30f56d3fa4db22a8353 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Clemens Ladisch <clemens@ladisch.de>
|
||||||
|
Date: Mon, 6 Dec 2010 14:04:39 +0100
|
||||||
|
Subject: [PATCH 41/43] alsamixer: remove obsolete e-mail
|
||||||
|
|
||||||
|
Remove the no-longer-valid e-mail address also from the man page.
|
||||||
|
|
||||||
|
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
|
||||||
|
---
|
||||||
|
alsamixer/alsamixer.1 | 2 +-
|
||||||
|
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/alsamixer/alsamixer.1 b/alsamixer/alsamixer.1
|
||||||
|
index ba05aca..cd88404 100644
|
||||||
|
--- a/alsamixer/alsamixer.1
|
||||||
|
+++ b/alsamixer/alsamixer.1
|
||||||
|
@@ -171,7 +171,7 @@ fault. Plain old \fBxterm\fP seems to be fine.
|
||||||
|
|
||||||
|
.SH AUTHOR
|
||||||
|
.B alsamixer
|
||||||
|
-has been written by Tim Janik <timj@gtk.org> and
|
||||||
|
+has been written by Tim Janik and
|
||||||
|
been further improved by Jaroslav Kysela <perex@perex.cz>
|
||||||
|
and Clemens Ladisch <clemens@ladisch.de>.
|
||||||
|
|
||||||
|
--
|
||||||
|
1.7.3.1
|
||||||
|
|
@ -0,0 +1,40 @@
|
|||||||
|
From 70a01748d594ef57a1962e4cb012927faf6d852f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Clemens Ladisch <clemens@ladisch.de>
|
||||||
|
Date: Mon, 6 Dec 2010 14:05:10 +0100
|
||||||
|
Subject: [PATCH 42/43] alsamixer: increase step size for big control value ranges
|
||||||
|
|
||||||
|
For controls with a big range, stepping through all values can become
|
||||||
|
tedious and make it impossible to adjust the volume easily. Therefore,
|
||||||
|
ensure that all steps are big enough so that the full range has at most
|
||||||
|
one hundred steps.
|
||||||
|
|
||||||
|
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
|
||||||
|
---
|
||||||
|
alsamixer/mixer_widget.c | 4 +++-
|
||||||
|
1 files changed, 3 insertions(+), 1 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/alsamixer/mixer_widget.c b/alsamixer/mixer_widget.c
|
||||||
|
index c8ca156..adb4568 100644
|
||||||
|
--- a/alsamixer/mixer_widget.c
|
||||||
|
+++ b/alsamixer/mixer_widget.c
|
||||||
|
@@ -318,7 +318,7 @@ static void change_volume_to_percent(struct control *control, int value, unsigne
|
||||||
|
set_func(control->elem, control->volume_channels[1], min + (max - min) * value / 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void change_volume_relative(struct control *control, int delta, unsigned int channels)
|
||||||
|
+static void change_volume_relative(struct control *control, long delta, unsigned int channels)
|
||||||
|
{
|
||||||
|
int (*get_range_func)(snd_mixer_elem_t *, long *, long *);
|
||||||
|
int (*get_func)(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t, long *);
|
||||||
|
@@ -352,6 +352,8 @@ static void change_volume_relative(struct control *control, int delta, unsigned
|
||||||
|
if (err < 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
+ if (max - min > 100)
|
||||||
|
+ delta = (delta * (max - min) + (delta > 0 ? 99 : -99)) / 100;
|
||||||
|
if (channels & LEFT) {
|
||||||
|
value = left + delta;
|
||||||
|
if (value < min)
|
||||||
|
--
|
||||||
|
1.7.3.1
|
||||||
|
|
538
0043-alsamixer-use-cubic-scale-for-volume-bars.patch
Normal file
538
0043-alsamixer-use-cubic-scale-for-volume-bars.patch
Normal file
@ -0,0 +1,538 @@
|
|||||||
|
From 34bb514b5fd1d6f91ba9a7b3a70b0ea0c6014250 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Clemens Ladisch <clemens@ladisch.de>
|
||||||
|
Date: Mon, 6 Dec 2010 14:07:48 +0100
|
||||||
|
Subject: [PATCH 43/43] alsamixer: use cubic scale for volume bars
|
||||||
|
|
||||||
|
Instead of mapping the raw volume values linearly to the screen, use
|
||||||
|
a mapping where the bar height is proportional to the audible volume,
|
||||||
|
i.e., where the amplitude is the cube of the bar height.
|
||||||
|
|
||||||
|
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
|
||||||
|
---
|
||||||
|
alsamixer/Makefile.am | 1 +
|
||||||
|
alsamixer/mixer_display.c | 53 ++++---------
|
||||||
|
alsamixer/mixer_widget.c | 120 +++++++++++-------------------
|
||||||
|
alsamixer/volume_mapping.c | 180 ++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
alsamixer/volume_mapping.h | 19 +++++
|
||||||
|
5 files changed, 260 insertions(+), 113 deletions(-)
|
||||||
|
create mode 100644 alsamixer/volume_mapping.c
|
||||||
|
create mode 100644 alsamixer/volume_mapping.h
|
||||||
|
|
||||||
|
diff --git a/alsamixer/Makefile.am b/alsamixer/Makefile.am
|
||||||
|
index 1de47c6..8a82323 100644
|
||||||
|
--- a/alsamixer/Makefile.am
|
||||||
|
+++ b/alsamixer/Makefile.am
|
||||||
|
@@ -15,6 +15,7 @@ alsamixer_SOURCES = card_select.c card_select.h \
|
||||||
|
proc_files.c proc_files.h \
|
||||||
|
textbox.c textbox.h \
|
||||||
|
utils.c utils.h \
|
||||||
|
+ volume_mapping.c volume_mapping.h \
|
||||||
|
widget.c widget.h
|
||||||
|
man_MANS = alsamixer.1
|
||||||
|
EXTRA_DIST = alsamixer.1
|
||||||
|
diff --git a/alsamixer/mixer_display.c b/alsamixer/mixer_display.c
|
||||||
|
index 20d6d6a..51a1546 100644
|
||||||
|
--- a/alsamixer/mixer_display.c
|
||||||
|
+++ b/alsamixer/mixer_display.c
|
||||||
|
@@ -17,10 +17,12 @@
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#define _C99_SOURCE /* lrint() */
|
||||||
|
#include "aconfig.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
+#include <math.h>
|
||||||
|
#include CURSESINC
|
||||||
|
#include <alsa/asoundlib.h>
|
||||||
|
#include "gettext_curses.h"
|
||||||
|
@@ -28,6 +30,7 @@
|
||||||
|
#include "mem.h"
|
||||||
|
#include "colors.h"
|
||||||
|
#include "widget.h"
|
||||||
|
+#include "volume_mapping.h"
|
||||||
|
#include "mixer_widget.h"
|
||||||
|
#include "mixer_controls.h"
|
||||||
|
#include "mixer_display.h"
|
||||||
|
@@ -390,24 +393,14 @@ static void display_string_centered_in_control(int y, int col, const char *s, in
|
||||||
|
display_string_in_field(y, x, s, width, ALIGN_CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static long clamp(long value, long min, long max)
|
||||||
|
-{
|
||||||
|
- if (value < min)
|
||||||
|
- return min;
|
||||||
|
- if (value > max)
|
||||||
|
- return max;
|
||||||
|
- return value;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static void display_control(unsigned int control_index)
|
||||||
|
{
|
||||||
|
struct control *control;
|
||||||
|
int col;
|
||||||
|
int i, c;
|
||||||
|
int left, frame_left;
|
||||||
|
- int bar_height, value;
|
||||||
|
- long volumes[2];
|
||||||
|
- long min, max;
|
||||||
|
+ int bar_height;
|
||||||
|
+ double volumes[2];
|
||||||
|
int switches[2];
|
||||||
|
unsigned int index;
|
||||||
|
const char *s;
|
||||||
|
@@ -452,35 +445,22 @@ static void display_control(unsigned int control_index)
|
||||||
|
waddch(mixer_widget.window, ACS_LRCORNER);
|
||||||
|
}
|
||||||
|
if (control->flags & (TYPE_PVOLUME | TYPE_CVOLUME)) {
|
||||||
|
- int (*get_vol_func)(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t, long *);
|
||||||
|
+ double (*get_vol_func)(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t);
|
||||||
|
|
||||||
|
if (control->flags & TYPE_PVOLUME)
|
||||||
|
- get_vol_func = snd_mixer_selem_get_playback_volume;
|
||||||
|
+ get_vol_func = get_normalized_playback_volume;
|
||||||
|
else
|
||||||
|
- get_vol_func = snd_mixer_selem_get_capture_volume;
|
||||||
|
- err = get_vol_func(control->elem, control->volume_channels[0], &volumes[0]);
|
||||||
|
- if (err >= 0 && (control->flags & HAS_VOLUME_1))
|
||||||
|
- err = get_vol_func(control->elem, control->volume_channels[1], &volumes[1]);
|
||||||
|
+ get_vol_func = get_normalized_capture_volume;
|
||||||
|
+ volumes[0] = get_vol_func(control->elem, control->volume_channels[0]);
|
||||||
|
+ if (control->flags & HAS_VOLUME_1)
|
||||||
|
+ volumes[1] = get_vol_func(control->elem, control->volume_channels[1]);
|
||||||
|
else
|
||||||
|
volumes[1] = volumes[0];
|
||||||
|
- if (err < 0)
|
||||||
|
- return;
|
||||||
|
- if (control->flags & TYPE_PVOLUME)
|
||||||
|
- err = snd_mixer_selem_get_playback_volume_range(control->elem, &min, &max);
|
||||||
|
- else
|
||||||
|
- err = snd_mixer_selem_get_capture_volume_range(control->elem, &min, &max);
|
||||||
|
- if (err < 0)
|
||||||
|
- return;
|
||||||
|
- if (min >= max)
|
||||||
|
- max = min + 1;
|
||||||
|
- volumes[0] = clamp(volumes[0], min, max);
|
||||||
|
- volumes[1] = clamp(volumes[1], min, max);
|
||||||
|
|
||||||
|
if (control->flags & IS_ACTIVE)
|
||||||
|
wattrset(mixer_widget.window, 0);
|
||||||
|
for (c = 0; c < 2; c++) {
|
||||||
|
- bar_height = ((volumes[c] - min) * volume_height +
|
||||||
|
- max - min - 1) / (max - min);
|
||||||
|
+ bar_height = lrint(volumes[c] * volume_height);
|
||||||
|
for (i = 0; i < volume_height; ++i) {
|
||||||
|
chtype ch;
|
||||||
|
if (i + 1 > bar_height)
|
||||||
|
@@ -505,19 +485,18 @@ static void display_control(unsigned int control_index)
|
||||||
|
}
|
||||||
|
if (control->flags & IS_ACTIVE)
|
||||||
|
wattrset(mixer_widget.window, attr_mixer_active);
|
||||||
|
- value = ((volumes[0] - min) * 100 + (max - min) / 2) / (max - min);
|
||||||
|
if (!(control->flags & HAS_VOLUME_1)) {
|
||||||
|
- sprintf(buf, "%d", value);
|
||||||
|
+ sprintf(buf, "%d", lrint(volumes[0] * 100));
|
||||||
|
display_string_in_field(values_y, frame_left - 2, buf, 8, ALIGN_CENTER);
|
||||||
|
} else {
|
||||||
|
- mvwprintw(mixer_widget.window, values_y, frame_left - 2, "%3d", value);
|
||||||
|
+ mvwprintw(mixer_widget.window, values_y, frame_left - 2,
|
||||||
|
+ "%3d", lrint(volumes[0] * 100));
|
||||||
|
if (control->flags & IS_ACTIVE)
|
||||||
|
wattrset(mixer_widget.window, attr_ctl_frame);
|
||||||
|
waddstr(mixer_widget.window, "<>");
|
||||||
|
if (control->flags & IS_ACTIVE)
|
||||||
|
wattrset(mixer_widget.window, attr_mixer_active);
|
||||||
|
- value = ((volumes[1] - min) * 100 + (max - min) / 2) / (max - min);
|
||||||
|
- wprintw(mixer_widget.window, "%-3d", value);
|
||||||
|
+ wprintw(mixer_widget.window, "%-3d", lrint(volumes[1] * 100));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/alsamixer/mixer_widget.c b/alsamixer/mixer_widget.c
|
||||||
|
index adb4568..fb352d3 100644
|
||||||
|
--- a/alsamixer/mixer_widget.c
|
||||||
|
+++ b/alsamixer/mixer_widget.c
|
||||||
|
@@ -33,6 +33,7 @@
|
||||||
|
#include "textbox.h"
|
||||||
|
#include "proc_files.h"
|
||||||
|
#include "card_select.h"
|
||||||
|
+#include "volume_mapping.h"
|
||||||
|
#include "mixer_controls.h"
|
||||||
|
#include "mixer_display.h"
|
||||||
|
#include "mixer_widget.h"
|
||||||
|
@@ -295,82 +296,57 @@ static void change_enum_relative(struct control *control, int delta)
|
||||||
|
|
||||||
|
static void change_volume_to_percent(struct control *control, int value, unsigned int channels)
|
||||||
|
{
|
||||||
|
- int (*get_range_func)(snd_mixer_elem_t *, long *, long *);
|
||||||
|
- int (*set_func)(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t, long);
|
||||||
|
- long min, max;
|
||||||
|
- int err;
|
||||||
|
+ int (*set_func)(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t, double, int);
|
||||||
|
|
||||||
|
if (!(control->flags & HAS_VOLUME_1))
|
||||||
|
channels = LEFT;
|
||||||
|
- if (control->flags & TYPE_PVOLUME) {
|
||||||
|
- get_range_func = snd_mixer_selem_get_playback_volume_range;
|
||||||
|
- set_func = snd_mixer_selem_set_playback_volume;
|
||||||
|
- } else {
|
||||||
|
- get_range_func = snd_mixer_selem_get_capture_volume_range;
|
||||||
|
- set_func = snd_mixer_selem_set_capture_volume;
|
||||||
|
- }
|
||||||
|
- err = get_range_func(control->elem, &min, &max);
|
||||||
|
- if (err < 0)
|
||||||
|
- return;
|
||||||
|
+ if (control->flags & TYPE_PVOLUME)
|
||||||
|
+ set_func = set_normalized_playback_volume;
|
||||||
|
+ else
|
||||||
|
+ set_func = set_normalized_capture_volume;
|
||||||
|
if (channels & LEFT)
|
||||||
|
- set_func(control->elem, control->volume_channels[0], min + (max - min) * value / 100);
|
||||||
|
+ set_func(control->elem, control->volume_channels[0], value / 100.0, 0);
|
||||||
|
if (channels & RIGHT)
|
||||||
|
- set_func(control->elem, control->volume_channels[1], min + (max - min) * value / 100);
|
||||||
|
+ set_func(control->elem, control->volume_channels[1], value / 100.0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void change_volume_relative(struct control *control, long delta, unsigned int channels)
|
||||||
|
+static double clamp_volume(double v)
|
||||||
|
{
|
||||||
|
- int (*get_range_func)(snd_mixer_elem_t *, long *, long *);
|
||||||
|
- int (*get_func)(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t, long *);
|
||||||
|
- int (*set_func)(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t, long);
|
||||||
|
- long min, max;
|
||||||
|
- long left, right;
|
||||||
|
- long value;
|
||||||
|
- int err;
|
||||||
|
+ if (v < 0)
|
||||||
|
+ return 0;
|
||||||
|
+ if (v > 1)
|
||||||
|
+ return 1;
|
||||||
|
+ return v;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void change_volume_relative(struct control *control, int delta, unsigned int channels)
|
||||||
|
+{
|
||||||
|
+ double (*get_func)(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t);
|
||||||
|
+ int (*set_func)(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t, double, int);
|
||||||
|
+ double left, right;
|
||||||
|
+ int dir;
|
||||||
|
|
||||||
|
if (!(control->flags & HAS_VOLUME_1))
|
||||||
|
channels = LEFT;
|
||||||
|
if (control->flags & TYPE_PVOLUME) {
|
||||||
|
- get_range_func = snd_mixer_selem_get_playback_volume_range;
|
||||||
|
- get_func = snd_mixer_selem_get_playback_volume;
|
||||||
|
- set_func = snd_mixer_selem_set_playback_volume;
|
||||||
|
+ get_func = get_normalized_playback_volume;
|
||||||
|
+ set_func = set_normalized_playback_volume;
|
||||||
|
} else {
|
||||||
|
- get_range_func = snd_mixer_selem_get_capture_volume_range;
|
||||||
|
- get_func = snd_mixer_selem_get_capture_volume;
|
||||||
|
- set_func = snd_mixer_selem_set_capture_volume;
|
||||||
|
+ get_func = get_normalized_capture_volume;
|
||||||
|
+ set_func = set_normalized_capture_volume;
|
||||||
|
}
|
||||||
|
- err = get_range_func(control->elem, &min, &max);
|
||||||
|
- if (err < 0)
|
||||||
|
- return;
|
||||||
|
- if (channels & LEFT) {
|
||||||
|
- err = get_func(control->elem, control->volume_channels[0], &left);
|
||||||
|
- if (err < 0)
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
- if (channels & RIGHT) {
|
||||||
|
- err = get_func(control->elem, control->volume_channels[1], &right);
|
||||||
|
- if (err < 0)
|
||||||
|
- return;
|
||||||
|
- }
|
||||||
|
- if (max - min > 100)
|
||||||
|
- delta = (delta * (max - min) + (delta > 0 ? 99 : -99)) / 100;
|
||||||
|
+ if (channels & LEFT)
|
||||||
|
+ left = get_func(control->elem, control->volume_channels[0]);
|
||||||
|
+ if (channels & RIGHT)
|
||||||
|
+ right = get_func(control->elem, control->volume_channels[1]);
|
||||||
|
+ dir = delta > 0 ? 1 : -1;
|
||||||
|
if (channels & LEFT) {
|
||||||
|
- value = left + delta;
|
||||||
|
- if (value < min)
|
||||||
|
- value = min;
|
||||||
|
- else if (value > max)
|
||||||
|
- value = max;
|
||||||
|
- if (value != left)
|
||||||
|
- set_func(control->elem, control->volume_channels[0], value);
|
||||||
|
+ left = clamp_volume(left + delta / 100.0);
|
||||||
|
+ set_func(control->elem, control->volume_channels[0], left, dir);
|
||||||
|
}
|
||||||
|
if (channels & RIGHT) {
|
||||||
|
- value = right + delta;
|
||||||
|
- if (value < min)
|
||||||
|
- value = min;
|
||||||
|
- else if (value > max)
|
||||||
|
- value = max;
|
||||||
|
- if (value != right)
|
||||||
|
- set_func(control->elem, control->volume_channels[1], value);
|
||||||
|
+ right = clamp_volume(right + delta / 100.0);
|
||||||
|
+ set_func(control->elem, control->volume_channels[1], right, dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -460,34 +436,26 @@ static void toggle_capture(unsigned int channels)
|
||||||
|
static void balance_volumes(void)
|
||||||
|
{
|
||||||
|
struct control *control;
|
||||||
|
- long left, right;
|
||||||
|
+ double left, right;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
control = get_focus_control(TYPE_PVOLUME | TYPE_CVOLUME);
|
||||||
|
if (!control || !(control->flags & HAS_VOLUME_1))
|
||||||
|
return;
|
||||||
|
if (control->flags & TYPE_PVOLUME) {
|
||||||
|
- err = snd_mixer_selem_get_playback_volume(control->elem, control->volume_channels[0], &left);
|
||||||
|
- if (err < 0)
|
||||||
|
- return;
|
||||||
|
- err = snd_mixer_selem_get_playback_volume(control->elem, control->volume_channels[1], &right);
|
||||||
|
- if (err < 0)
|
||||||
|
- return;
|
||||||
|
+ left = get_normalized_playback_volume(control->elem, control->volume_channels[0]);
|
||||||
|
+ right = get_normalized_playback_volume(control->elem, control->volume_channels[1]);
|
||||||
|
} else {
|
||||||
|
- err = snd_mixer_selem_get_capture_volume(control->elem, control->volume_channels[0], &left);
|
||||||
|
- if (err < 0)
|
||||||
|
- return;
|
||||||
|
- err = snd_mixer_selem_get_capture_volume(control->elem, control->volume_channels[1], &right);
|
||||||
|
- if (err < 0)
|
||||||
|
- return;
|
||||||
|
+ left = get_normalized_capture_volume(control->elem, control->volume_channels[0]);
|
||||||
|
+ right = get_normalized_capture_volume(control->elem, control->volume_channels[1]);
|
||||||
|
}
|
||||||
|
left = (left + right) / 2;
|
||||||
|
if (control->flags & TYPE_PVOLUME) {
|
||||||
|
- snd_mixer_selem_set_playback_volume(control->elem, control->volume_channels[0], left);
|
||||||
|
- snd_mixer_selem_set_playback_volume(control->elem, control->volume_channels[1], left);
|
||||||
|
+ set_normalized_playback_volume(control->elem, control->volume_channels[0], left, 0);
|
||||||
|
+ set_normalized_playback_volume(control->elem, control->volume_channels[1], left, 0);
|
||||||
|
} else {
|
||||||
|
- snd_mixer_selem_set_capture_volume(control->elem, control->volume_channels[0], left);
|
||||||
|
- snd_mixer_selem_set_capture_volume(control->elem, control->volume_channels[1], left);
|
||||||
|
+ set_normalized_capture_volume(control->elem, control->volume_channels[0], left, 0);
|
||||||
|
+ set_normalized_capture_volume(control->elem, control->volume_channels[1], left, 0);
|
||||||
|
}
|
||||||
|
display_controls();
|
||||||
|
}
|
||||||
|
diff --git a/alsamixer/volume_mapping.c b/alsamixer/volume_mapping.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..9cacad8
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/alsamixer/volume_mapping.c
|
||||||
|
@@ -0,0 +1,180 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (c) 2010 Clemens Ladisch <clemens@ladisch.de>
|
||||||
|
+ *
|
||||||
|
+ * Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
+ * purpose with or without fee is hereby granted, provided that the above
|
||||||
|
+ * copyright notice and this permission notice appear in all copies.
|
||||||
|
+ *
|
||||||
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * The functions in this file map the value ranges of ALSA mixer controls onto
|
||||||
|
+ * the interval 0..1.
|
||||||
|
+ *
|
||||||
|
+ * The mapping is designed so that the position in the interval is proportional
|
||||||
|
+ * to the volume as a human ear would perceive it (i.e., the position is the
|
||||||
|
+ * cubic root of the linear sample multiplication factor). For controls with
|
||||||
|
+ * a small range (24 dB or less), the mapping is linear in the dB values so
|
||||||
|
+ * that each step has the same size visually. Only for controls without dB
|
||||||
|
+ * information, a linear mapping of the hardware volume register values is used
|
||||||
|
+ * (this is the same algorithm as used in the old alsamixer).
|
||||||
|
+ *
|
||||||
|
+ * When setting the volume, 'dir' is the rounding direction:
|
||||||
|
+ * -1/0/1 = down/nearest/up.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#define _ISOC99_SOURCE /* lrint() */
|
||||||
|
+#define _GNU_SOURCE /* exp10() */
|
||||||
|
+#include "aconfig.h"
|
||||||
|
+#include <math.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+#include "volume_mapping.h"
|
||||||
|
+
|
||||||
|
+#define MAX_LINEAR_DB_SCALE 24
|
||||||
|
+
|
||||||
|
+static inline bool use_linear_dB_scale(long dBmin, long dBmax)
|
||||||
|
+{
|
||||||
|
+ return dBmax - dBmin <= MAX_LINEAR_DB_SCALE * 100;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static long lrint_dir(double x, int dir)
|
||||||
|
+{
|
||||||
|
+ if (dir > 0)
|
||||||
|
+ return lrint(ceil(x));
|
||||||
|
+ else if (dir < 0)
|
||||||
|
+ return lrint(floor(x));
|
||||||
|
+ else
|
||||||
|
+ return lrint(x);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+enum ctl_dir { PLAYBACK, CAPTURE };
|
||||||
|
+
|
||||||
|
+static int (* const get_dB_range[2])(snd_mixer_elem_t *, long *, long *) = {
|
||||||
|
+ snd_mixer_selem_get_playback_dB_range,
|
||||||
|
+ snd_mixer_selem_get_capture_dB_range,
|
||||||
|
+};
|
||||||
|
+static int (* const get_raw_range[2])(snd_mixer_elem_t *, long *, long *) = {
|
||||||
|
+ snd_mixer_selem_get_playback_volume_range,
|
||||||
|
+ snd_mixer_selem_get_capture_volume_range,
|
||||||
|
+};
|
||||||
|
+static int (* const get_dB[2])(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t, long *) = {
|
||||||
|
+ snd_mixer_selem_get_playback_dB,
|
||||||
|
+ snd_mixer_selem_get_capture_dB,
|
||||||
|
+};
|
||||||
|
+static int (* const get_raw[2])(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t, long *) = {
|
||||||
|
+ snd_mixer_selem_get_playback_volume,
|
||||||
|
+ snd_mixer_selem_get_capture_volume,
|
||||||
|
+};
|
||||||
|
+static int (* const set_dB[2])(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t, long, int) = {
|
||||||
|
+ snd_mixer_selem_set_playback_dB,
|
||||||
|
+ snd_mixer_selem_set_capture_dB,
|
||||||
|
+};
|
||||||
|
+static int (* const set_raw[2])(snd_mixer_elem_t *, snd_mixer_selem_channel_id_t, long) = {
|
||||||
|
+ snd_mixer_selem_set_playback_volume,
|
||||||
|
+ snd_mixer_selem_set_capture_volume,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static double get_normalized_volume(snd_mixer_elem_t *elem,
|
||||||
|
+ snd_mixer_selem_channel_id_t channel,
|
||||||
|
+ enum ctl_dir ctl_dir)
|
||||||
|
+{
|
||||||
|
+ long min, max, value;
|
||||||
|
+ double normalized, min_norm;
|
||||||
|
+ int err;
|
||||||
|
+
|
||||||
|
+ err = get_dB_range[ctl_dir](elem, &min, &max);
|
||||||
|
+ if (err < 0 || min >= max) {
|
||||||
|
+ err = get_raw_range[ctl_dir](elem, &min, &max);
|
||||||
|
+ if (err < 0 || min == max)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ err = get_raw[ctl_dir](elem, channel, &value);
|
||||||
|
+ if (err < 0)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ return (value - min) / (double)(max - min);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ err = get_dB[ctl_dir](elem, channel, &value);
|
||||||
|
+ if (err < 0)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ if (use_linear_dB_scale(min, max))
|
||||||
|
+ return (value - min) / (double)(max - min);
|
||||||
|
+
|
||||||
|
+ normalized = exp10((value - max) / 6000.0);
|
||||||
|
+ if (min != SND_CTL_TLV_DB_GAIN_MUTE) {
|
||||||
|
+ min_norm = exp10((min - max) / 6000.0);
|
||||||
|
+ normalized = (normalized - min_norm) / (1 - min_norm);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return normalized;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int set_normalized_volume(snd_mixer_elem_t *elem,
|
||||||
|
+ snd_mixer_selem_channel_id_t channel,
|
||||||
|
+ double volume,
|
||||||
|
+ int dir,
|
||||||
|
+ enum ctl_dir ctl_dir)
|
||||||
|
+{
|
||||||
|
+ long min, max, value;
|
||||||
|
+ double min_norm;
|
||||||
|
+ int err;
|
||||||
|
+
|
||||||
|
+ err = get_dB_range[ctl_dir](elem, &min, &max);
|
||||||
|
+ if (err < 0 || min >= max) {
|
||||||
|
+ err = get_raw_range[ctl_dir](elem, &min, &max);
|
||||||
|
+ if (err < 0)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
+ value = lrint_dir(volume * (max - min), dir) + min;
|
||||||
|
+ return set_raw[ctl_dir](elem, channel, value);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (use_linear_dB_scale(min, max)) {
|
||||||
|
+ value = lrint_dir(volume * (max - min), dir) + min;
|
||||||
|
+ return set_dB[ctl_dir](elem, channel, value, dir);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (min != SND_CTL_TLV_DB_GAIN_MUTE) {
|
||||||
|
+ min_norm = exp10((min - max) / 6000.0);
|
||||||
|
+ volume = volume * (1 - min_norm) + min_norm;
|
||||||
|
+ }
|
||||||
|
+ value = lrint_dir(6000.0 * log10(volume), dir) + max;
|
||||||
|
+ return set_dB[ctl_dir](elem, channel, value, dir);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+double get_normalized_playback_volume(snd_mixer_elem_t *elem,
|
||||||
|
+ snd_mixer_selem_channel_id_t channel)
|
||||||
|
+{
|
||||||
|
+ return get_normalized_volume(elem, channel, PLAYBACK);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+double get_normalized_capture_volume(snd_mixer_elem_t *elem,
|
||||||
|
+ snd_mixer_selem_channel_id_t channel)
|
||||||
|
+{
|
||||||
|
+ return get_normalized_volume(elem, channel, CAPTURE);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int set_normalized_playback_volume(snd_mixer_elem_t *elem,
|
||||||
|
+ snd_mixer_selem_channel_id_t channel,
|
||||||
|
+ double volume,
|
||||||
|
+ int dir)
|
||||||
|
+{
|
||||||
|
+ return set_normalized_volume(elem, channel, volume, dir, PLAYBACK);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int set_normalized_capture_volume(snd_mixer_elem_t *elem,
|
||||||
|
+ snd_mixer_selem_channel_id_t channel,
|
||||||
|
+ double volume,
|
||||||
|
+ int dir)
|
||||||
|
+{
|
||||||
|
+ return set_normalized_volume(elem, channel, volume, dir, CAPTURE);
|
||||||
|
+}
|
||||||
|
diff --git a/alsamixer/volume_mapping.h b/alsamixer/volume_mapping.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..d4251d6
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/alsamixer/volume_mapping.h
|
||||||
|
@@ -0,0 +1,19 @@
|
||||||
|
+#ifndef VOLUME_MAPPING_H_INCLUDED
|
||||||
|
+#define VOLUME_MAPPING_H_INCLUDED
|
||||||
|
+
|
||||||
|
+#include <alsa/asoundlib.h>
|
||||||
|
+
|
||||||
|
+double get_normalized_playback_volume(snd_mixer_elem_t *elem,
|
||||||
|
+ snd_mixer_selem_channel_id_t channel);
|
||||||
|
+double get_normalized_capture_volume(snd_mixer_elem_t *elem,
|
||||||
|
+ snd_mixer_selem_channel_id_t channel);
|
||||||
|
+int set_normalized_playback_volume(snd_mixer_elem_t *elem,
|
||||||
|
+ snd_mixer_selem_channel_id_t channel,
|
||||||
|
+ double volume,
|
||||||
|
+ int dir);
|
||||||
|
+int set_normalized_capture_volume(snd_mixer_elem_t *elem,
|
||||||
|
+ snd_mixer_selem_channel_id_t channel,
|
||||||
|
+ double volume,
|
||||||
|
+ int dir);
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
--
|
||||||
|
1.7.3.1
|
||||||
|
|
@ -1,3 +1,9 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Dec 9 14:03:18 CET 2010 - tiwai@suse.de
|
||||||
|
|
||||||
|
- Use cubic scale for alsamixer volume bars for better usability
|
||||||
|
- Misc fixes from upstream
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Tue Nov 30 08:42:50 CET 2010 - tiwai@suse.de
|
Tue Nov 30 08:42:50 CET 2010 - tiwai@suse.de
|
||||||
|
|
||||||
|
@ -77,6 +77,10 @@ Patch36: 0036-update-German-translations.patch
|
|||||||
Patch37: 0037-alsactl-systemd-and-udev-hookup.patch
|
Patch37: 0037-alsactl-systemd-and-udev-hookup.patch
|
||||||
Patch38: 0038-alsactl-Move-asound.state-location-to-var-lib-alsa.patch
|
Patch38: 0038-alsactl-Move-asound.state-location-to-var-lib-alsa.patch
|
||||||
Patch39: 0039-configure.in-Fix-variable-name.patch
|
Patch39: 0039-configure.in-Fix-variable-name.patch
|
||||||
|
Patch40: 0040-alsactl-Add-a-with-udev-rules-dir-configure-option.patch
|
||||||
|
Patch41: 0041-alsamixer-remove-obsolete-e-mail.patch
|
||||||
|
Patch42: 0042-alsamixer-increase-step-size-for-big-control-value-r.patch
|
||||||
|
Patch43: 0043-alsamixer-use-cubic-scale-for-volume-bars.patch
|
||||||
Patch99: alsa-utils-gettext-version-removal.diff
|
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/
|
Url: http://www.alsa-project.org/
|
||||||
@ -140,6 +144,10 @@ sed -i -e's/EXTRA_DIST= config.rpath /EXTRA_DIST=/' Makefile.am
|
|||||||
%patch37 -p1
|
%patch37 -p1
|
||||||
%patch38 -p1
|
%patch38 -p1
|
||||||
%patch39 -p1
|
%patch39 -p1
|
||||||
|
%patch40 -p1
|
||||||
|
%patch41 -p1
|
||||||
|
%patch42 -p1
|
||||||
|
%patch43 -p1
|
||||||
%if %suse_version < 1020
|
%if %suse_version < 1020
|
||||||
%patch99 -p1
|
%patch99 -p1
|
||||||
%endif
|
%endif
|
||||||
|
Loading…
Reference in New Issue
Block a user