ALSA: Add new TLV types for dBwith min/max
Add new types for TLV dB scale specified with min/max values instead of min/step since the resolution can't match always with the one a device provides. For example, usb audio devices give 1/256 dB resolution while ALSA TLV is based on 1/100 dB resolution. The new min/max types have less problems because the possible rounding error happens only at min/max. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
07a2039b8e
commit
085f306541
@ -35,6 +35,8 @@
|
|||||||
#define SNDRV_CTL_TLVT_DB_SCALE 1 /* dB scale */
|
#define SNDRV_CTL_TLVT_DB_SCALE 1 /* dB scale */
|
||||||
#define SNDRV_CTL_TLVT_DB_LINEAR 2 /* linear volume */
|
#define SNDRV_CTL_TLVT_DB_LINEAR 2 /* linear volume */
|
||||||
#define SNDRV_CTL_TLVT_DB_RANGE 3 /* dB range container */
|
#define SNDRV_CTL_TLVT_DB_RANGE 3 /* dB range container */
|
||||||
|
#define SNDRV_CTL_TLVT_DB_MINMAX 4 /* dB scale with min/max */
|
||||||
|
#define SNDRV_CTL_TLVT_DB_MINMAX_MUTE 5 /* dB scale with min/max with mute */
|
||||||
|
|
||||||
#define TLV_DB_SCALE_ITEM(min, step, mute) \
|
#define TLV_DB_SCALE_ITEM(min, step, mute) \
|
||||||
SNDRV_CTL_TLVT_DB_SCALE, 2 * sizeof(unsigned int), \
|
SNDRV_CTL_TLVT_DB_SCALE, 2 * sizeof(unsigned int), \
|
||||||
@ -42,6 +44,18 @@
|
|||||||
#define DECLARE_TLV_DB_SCALE(name, min, step, mute) \
|
#define DECLARE_TLV_DB_SCALE(name, min, step, mute) \
|
||||||
unsigned int name[] = { TLV_DB_SCALE_ITEM(min, step, mute) }
|
unsigned int name[] = { TLV_DB_SCALE_ITEM(min, step, mute) }
|
||||||
|
|
||||||
|
/* dB scale specified with min/max values instead of step */
|
||||||
|
#define TLV_DB_MINMAX_ITEM(min_dB, max_dB) \
|
||||||
|
SNDRV_CTL_TLVT_DB_MINMAX, 2 * sizeof(unsigned int), \
|
||||||
|
(min_dB), (max_dB)
|
||||||
|
#define TLV_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) \
|
||||||
|
SNDRV_CTL_TLVT_DB_MINMAX_MUTE, 2 * sizeof(unsigned int), \
|
||||||
|
(min_dB), (max_dB)
|
||||||
|
#define DECLARE_TLV_DB_MINMAX(name, min_dB, max_dB) \
|
||||||
|
unsigned int name[] = { TLV_DB_MINMAX_ITEM(min_dB, max_dB) }
|
||||||
|
#define DECLARE_TLV_DB_MINMAX_MUTE(name, min_dB, max_dB) \
|
||||||
|
unsigned int name[] = { TLV_DB_MINMAX_MUTE_ITEM(min_dB, max_dB) }
|
||||||
|
|
||||||
/* linear volume between min_dB and max_dB (.01dB unit) */
|
/* linear volume between min_dB and max_dB (.01dB unit) */
|
||||||
#define TLV_DB_LINEAR_ITEM(min_dB, max_dB) \
|
#define TLV_DB_LINEAR_ITEM(min_dB, max_dB) \
|
||||||
SNDRV_CTL_TLVT_DB_LINEAR, 2 * sizeof(unsigned int), \
|
SNDRV_CTL_TLVT_DB_LINEAR, 2 * sizeof(unsigned int), \
|
||||||
|
@ -353,7 +353,8 @@ static void master_free(struct snd_kcontrol *kcontrol)
|
|||||||
*
|
*
|
||||||
* The optional argument @tlv can be used to specify the TLV information
|
* The optional argument @tlv can be used to specify the TLV information
|
||||||
* for dB scale of the master control. It should be a single element
|
* for dB scale of the master control. It should be a single element
|
||||||
* with #SNDRV_CTL_TLVT_DB_SCALE type, and should be the max 0dB.
|
* with #SNDRV_CTL_TLVT_DB_SCALE, #SNDRV_CTL_TLV_DB_MINMAX or
|
||||||
|
* #SNDRV_CTL_TLVT_DB_MINMAX_MUTE type, and should be the max 0dB.
|
||||||
*/
|
*/
|
||||||
struct snd_kcontrol *snd_ctl_make_virtual_master(char *name,
|
struct snd_kcontrol *snd_ctl_make_virtual_master(char *name,
|
||||||
const unsigned int *tlv)
|
const unsigned int *tlv)
|
||||||
@ -384,7 +385,10 @@ struct snd_kcontrol *snd_ctl_make_virtual_master(char *name,
|
|||||||
kctl->private_free = master_free;
|
kctl->private_free = master_free;
|
||||||
|
|
||||||
/* additional (constant) TLV read */
|
/* additional (constant) TLV read */
|
||||||
if (tlv && tlv[0] == SNDRV_CTL_TLVT_DB_SCALE) {
|
if (tlv &&
|
||||||
|
(tlv[0] == SNDRV_CTL_TLVT_DB_SCALE ||
|
||||||
|
tlv[0] == SNDRV_CTL_TLVT_DB_MINMAX ||
|
||||||
|
tlv[0] == SNDRV_CTL_TLVT_DB_MINMAX_MUTE)) {
|
||||||
kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
|
kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
|
||||||
memcpy(master->tlv, tlv, sizeof(master->tlv));
|
memcpy(master->tlv, tlv, sizeof(master->tlv));
|
||||||
kctl->tlv.p = master->tlv;
|
kctl->tlv.p = master->tlv;
|
||||||
|
Loading…
Reference in New Issue
Block a user