diff --git a/0040-alsactl-Add-a-with-udev-rules-dir-configure-option.patch b/0040-alsactl-Add-a-with-udev-rules-dir-configure-option.patch new file mode 100644 index 0000000..ee01851 --- /dev/null +++ b/0040-alsactl-Add-a-with-udev-rules-dir-configure-option.patch @@ -0,0 +1,53 @@ +From a97bcd19dcea98be86f15c6af0b5e0a8d234d190 Mon Sep 17 00:00:00 2001 +From: Colin Guthrie +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 +Signed-off-by: Jaroslav Kysela +--- + 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 + diff --git a/0041-alsamixer-remove-obsolete-e-mail.patch b/0041-alsamixer-remove-obsolete-e-mail.patch new file mode 100644 index 0000000..799189f --- /dev/null +++ b/0041-alsamixer-remove-obsolete-e-mail.patch @@ -0,0 +1,28 @@ +From e57f619c82e2fec20c20c30f56d3fa4db22a8353 Mon Sep 17 00:00:00 2001 +From: Clemens Ladisch +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 +--- + 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 and ++has been written by Tim Janik and + been further improved by Jaroslav Kysela + and Clemens Ladisch . + +-- +1.7.3.1 + diff --git a/0042-alsamixer-increase-step-size-for-big-control-value-r.patch b/0042-alsamixer-increase-step-size-for-big-control-value-r.patch new file mode 100644 index 0000000..e16696d --- /dev/null +++ b/0042-alsamixer-increase-step-size-for-big-control-value-r.patch @@ -0,0 +1,40 @@ +From 70a01748d594ef57a1962e4cb012927faf6d852f Mon Sep 17 00:00:00 2001 +From: Clemens Ladisch +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 +--- + 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 + diff --git a/0043-alsamixer-use-cubic-scale-for-volume-bars.patch b/0043-alsamixer-use-cubic-scale-for-volume-bars.patch new file mode 100644 index 0000000..1d1359e --- /dev/null +++ b/0043-alsamixer-use-cubic-scale-for-volume-bars.patch @@ -0,0 +1,538 @@ +From 34bb514b5fd1d6f91ba9a7b3a70b0ea0c6014250 Mon Sep 17 00:00:00 2001 +From: Clemens Ladisch +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 +--- + 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 . + */ + ++#define _C99_SOURCE /* lrint() */ + #include "aconfig.h" + #include + #include + #include ++#include + #include CURSESINC + #include + #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 ++ * ++ * 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 ++#include ++#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 ++ ++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 + diff --git a/alsa-utils.changes b/alsa-utils.changes index b720856..2f97efa 100644 --- a/alsa-utils.changes +++ b/alsa-utils.changes @@ -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 diff --git a/alsa-utils.spec b/alsa-utils.spec index 57428e7..fc4df4e 100644 --- a/alsa-utils.spec +++ b/alsa-utils.spec @@ -77,6 +77,10 @@ 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 +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 Patch100: alsa-utils-po-pre-patch.diff Url: http://www.alsa-project.org/ @@ -140,6 +144,10 @@ sed -i -e's/EXTRA_DIST= config.rpath /EXTRA_DIST=/' Makefile.am %patch37 -p1 %patch38 -p1 %patch39 -p1 +%patch40 -p1 +%patch41 -p1 +%patch42 -p1 +%patch43 -p1 %if %suse_version < 1020 %patch99 -p1 %endif