alsa-lib: Grabbed the softvol-mute patch from the git repo.
[gentoo-diskmaster-overlay.git] / media-libs / alsa-lib / files / alsa-lib-1.0.17-softvol-mute.patch
blob7d655727ef35da8c9046fc87a249479f7f55fa10
1 From: Takashi Iwai <tiwai@suse.de>
2 Date: Wed, 16 Jul 2008 10:37:51 +0000 (+0200)
3 Subject: Add boolean (mute) functionality to softvol plugin
4 X-Git-Url: http://git.alsa-project.org/?p=alsa-lib.git;a=commitdiff_plain;h=f78af4ab0412052aabb74c9122a8d8f3ab6d45e6
6 Add boolean (mute) functionality to softvol plugin
8 When the resolution is set to 2, a boolean control is created as a
9 mute switch instead of a volume control.
10 Also, fixed the possible zero-division error.
12 Signed-off-by: Takashi Iwai <tiwai@suse.de>
13 ---
15 diff --git a/src/pcm/pcm_softvol.c b/src/pcm/pcm_softvol.c
16 index 7af7f40..eee6424 100644
17 --- a/src/pcm/pcm_softvol.c
18 +++ b/src/pcm/pcm_softvol.c
19 @@ -275,9 +275,15 @@ static void softvol_convert_stereo_vol(snd_pcm_softvol_t *svol,
20 return;
23 - vol[0] = svol->dB_value[svol->cur_vol[0]];
24 - vol[1] = svol->dB_value[svol->cur_vol[1]];
25 - vol_c = svol->dB_value[(svol->cur_vol[0] + svol->cur_vol[1]) / 2];
26 + if (svol->max_val == 1) {
27 + vol[0] = svol->cur_vol[0] ? 0xffff : 0;
28 + vol[1] = svol->cur_vol[1] ? 0xffff : 0;
29 + vol_c = vol[0] | vol[1];
30 + } else {
31 + vol[0] = svol->dB_value[svol->cur_vol[0]];
32 + vol[1] = svol->dB_value[svol->cur_vol[1]];
33 + vol_c = svol->dB_value[(svol->cur_vol[0] + svol->cur_vol[1]) / 2];
34 + }
35 switch (svol->sformat) {
36 case SND_PCM_FORMAT_S16_LE:
37 case SND_PCM_FORMAT_S16_BE:
38 @@ -325,7 +331,10 @@ static void softvol_convert_mono_vol(snd_pcm_softvol_t *svol,
39 return;
42 - vol_scale = svol->dB_value[svol->cur_vol[0]];
43 + if (svol->max_val == 1)
44 + vol_scale = svol->cur_vol[0] ? 0xffff : 0;
45 + else
46 + vol_scale = svol->dB_value[svol->cur_vol[0]];
47 switch (svol->sformat) {
48 case SND_PCM_FORMAT_S16_LE:
49 case SND_PCM_FORMAT_S16_BE:
50 @@ -569,9 +578,13 @@ static void snd_pcm_softvol_dump(snd_pcm_t *pcm, snd_output_t *out)
51 snd_pcm_softvol_t *svol = pcm->private_data;
52 snd_output_printf(out, "Soft volume PCM\n");
53 snd_output_printf(out, "Control: %s\n", svol->elem.id.name);
54 - snd_output_printf(out, "min_dB: %g\n", svol->min_dB);
55 - snd_output_printf(out, "max_dB: %g\n", svol->max_dB);
56 - snd_output_printf(out, "resolution: %d\n", svol->max_val + 1);
57 + if (svol->max_val == 1)
58 + snd_output_printf(out, "boolean\n");
59 + else {
60 + snd_output_printf(out, "min_dB: %g\n", svol->min_dB);
61 + snd_output_printf(out, "max_dB: %g\n", svol->max_dB);
62 + snd_output_printf(out, "resolution: %d\n", svol->max_val + 1);
63 + }
64 if (pcm->setup) {
65 snd_output_printf(out, "Its setup is:\n");
66 snd_pcm_dump_setup(pcm, out);
67 @@ -596,13 +609,21 @@ static int add_user_ctl(snd_pcm_softvol_t *svol, snd_ctl_elem_info_t *cinfo, int
68 int i;
69 unsigned int def_val;
71 - err = snd_ctl_elem_add_integer(svol->ctl, &cinfo->id, count, 0, svol->max_val, 0);
72 + if (svol->max_val == 1)
73 + err = snd_ctl_elem_add_boolean(svol->ctl, &cinfo->id, count);
74 + else
75 + err = snd_ctl_elem_add_integer(svol->ctl, &cinfo->id, count,
76 + 0, svol->max_val, 0);
77 if (err < 0)
78 return err;
79 - add_tlv_info(svol, cinfo);
80 - /* set zero dB value as default, or max_val if
81 - there is no 0 dB setting */
82 - def_val = svol->zero_dB_val ? svol->zero_dB_val : svol->max_val;
83 + if (svol->max_val == 1)
84 + def_val = 1;
85 + else {
86 + add_tlv_info(svol, cinfo);
87 + /* set zero dB value as default, or max_val if
88 + there is no 0 dB setting */
89 + def_val = svol->zero_dB_val ? svol->zero_dB_val : svol->max_val;
90 + }
91 for (i = 0; i < count; i++)
92 svol->elem.value.integer.value[i] = def_val;
93 return snd_ctl_elem_write(svol->ctl, &svol->elem);
94 @@ -647,7 +668,7 @@ static int softvol_load_control(snd_pcm_t *pcm, snd_pcm_softvol_t *svol,
95 svol->max_val = resolution - 1;
96 svol->min_dB = min_dB;
97 svol->max_dB = max_dB;
98 - if (svol->max_dB == ZERO_DB)
99 + if (svol->max_val == 1 || svol->max_dB == ZERO_DB)
100 svol->zero_dB_val = svol->max_val;
101 else if (svol->max_dB < 0)
102 svol->zero_dB_val = 0; /* there is no 0 dB setting */
103 @@ -671,7 +692,8 @@ static int softvol_load_control(snd_pcm_t *pcm, snd_pcm_softvol_t *svol,
104 /* hardware control exists */
105 return 1; /* notify */
107 - } else if (cinfo->type != SND_CTL_ELEM_TYPE_INTEGER ||
108 + } else if ((cinfo->type != SND_CTL_ELEM_TYPE_INTEGER &&
109 + cinfo->type != SND_CTL_ELEM_TYPE_BOOLEAN) ||
110 cinfo->count != (unsigned int)cchannels ||
111 cinfo->value.integer.min != 0 ||
112 cinfo->value.integer.max != resolution - 1) {
113 @@ -684,7 +706,7 @@ static int softvol_load_control(snd_pcm_t *pcm, snd_pcm_softvol_t *svol,
114 SNDERR("Cannot add a control");
115 return err;
117 - } else {
118 + } else if (svol->max_val > 1) {
119 /* check TLV availability */
120 unsigned int tlv[4];
121 err = snd_ctl_elem_tlv_read(svol->ctl, &cinfo->id, tlv, sizeof(tlv));
122 @@ -693,6 +715,10 @@ static int softvol_load_control(snd_pcm_t *pcm, snd_pcm_softvol_t *svol,
126 + if (svol->max_val == 1)
127 + return 0;
129 + /* set up dB table */
130 if (min_dB == PRESET_MIN_DB && max_dB == ZERO_DB && resolution == PRESET_RESOLUTION)
131 svol->dB_value = preset_dB_value;
132 else {
133 @@ -863,6 +889,7 @@ pcm.name {
134 [min_dB REAL] # minimal dB value (default: -51.0)
135 [max_dB REAL] # maximal dB value (default: 0.0)
136 [resolution INT] # resolution (default: 256)
137 + # resolution = 2 means a mute switch
139 \endcode
141 @@ -965,7 +992,7 @@ int _snd_pcm_softvol_open(snd_pcm_t **pcmp, const char *name,
142 MAX_DB_UPPER_LIMIT);
143 return -EINVAL;
145 - if (resolution < 0 || resolution > 1024) {
146 + if (resolution <= 1 || resolution > 1024) {
147 SNDERR("Invalid resolution value %d", resolution);
148 return -EINVAL;