Complete rewrite of the snd_hda(4) volume control.
Previous code was relatively dumb. During CODEC probe it was tracing signals and statically binding amplifier controls to the OSS mixer controls. To set volume it just set all bound amplifier controls proportionally to mixer level, not looking on their hierarchy and amplification levels/offsets. New code is much smarter. It also traces signals during probe, but mostly to find out possible amplification control rages in dB for each specific signal. To set volume it retraces each affected signal again and sets amplifiers controls recursively to reach desired amplification level in dB. It would be nice to export values in dB to user, but unluckily our OSS mixer API is too simple for that. As result of this change: - cascaded amplifiers will work together to reach maximal precision. If some input has 0/+40dB preamplifier with 10dB step and -10/+10dB mixer with 1dB step after it, new code will use both to provide 0/+40dB control with 1dB step! We could even get -10/+50dB range there, but that is intentionally blocked for now. - different channels of multichannel associations on non-uniform CODECs such as VIA VT1708S will have the same volume, not looking that control ranges are different. It was not good when fronts were 12dB louder. - for multiplexed recording, when we can record from only one source at a time, we can now use recording amplifier controls to set different volume levels for different inputs if they have no own controls of they are less precise. If recording source change, amplifiers will be reconfigured. To improve out-of-the-box behavior, ignore default volume levels set by sound(4) and use own, more reasonable: +20dB for mics, -10dB for analog output volume and 0dB for the rest of controls. sound(4) defaults of 75% mean absolutely random things for different controls of different CODECs because of very different control ranges. Together with further planned automatic recording source selection this should allow users to get fine playback and recording without touching mixer first. Note that existing users should delete /var/db/mixer*-state and reboot or trigger CODEC reconfiguration to get new default values. MFC after: 2 months Sponsored by: iXsystems, Inc.
This commit is contained in:
parent
28083eaa4d
commit
3d741b14a7
File diff suppressed because it is too large
Load Diff
@ -74,7 +74,10 @@
|
||||
#define HDAA_AMP_LEFT_MUTED(v) ((v) & (HDAA_AMP_MUTE_LEFT))
|
||||
#define HDAA_AMP_RIGHT_MUTED(v) (((v) & HDAA_AMP_MUTE_RIGHT) >> 1)
|
||||
|
||||
/* Widget in playback receiving signal from recording. */
|
||||
#define HDAA_ADC_MONITOR (1 << 0)
|
||||
/* Input mixer widget needs volume control as destination. */
|
||||
#define HDAA_IMIX_AS_DST (2 << 0)
|
||||
|
||||
#define HDAA_CTL_OUT 1
|
||||
#define HDAA_CTL_IN 2
|
||||
@ -82,6 +85,13 @@
|
||||
#define HDA_MAX_CONNS 32
|
||||
#define HDA_MAX_NAMELEN 32
|
||||
|
||||
struct hdaa_audio_as;
|
||||
struct hdaa_audio_ctl;
|
||||
struct hdaa_chan;
|
||||
struct hdaa_devinfo;
|
||||
struct hdaa_pcm_devinfo;
|
||||
struct hdaa_widget;
|
||||
|
||||
struct hdaa_widget {
|
||||
nid_t nid;
|
||||
int type;
|
||||
@ -129,7 +139,10 @@ struct hdaa_audio_ctl {
|
||||
int mute, step, size, offset;
|
||||
int left, right, forcemute;
|
||||
uint32_t muted;
|
||||
uint32_t ossmask, possmask;
|
||||
uint32_t ossmask; /* OSS devices that may affect control. */
|
||||
int devleft[SOUND_MIXER_NRDEVICES]; /* Left ampl in 1/4dB. */
|
||||
int devright[SOUND_MIXER_NRDEVICES]; /* Right ampl in 1/4dB. */
|
||||
int devmute[SOUND_MIXER_NRDEVICES]; /* Mutes per OSS device. */
|
||||
};
|
||||
|
||||
/* Association is a group of pins bound for some special function. */
|
||||
@ -148,19 +161,25 @@ struct hdaa_audio_as {
|
||||
int chans[2];
|
||||
int location; /* Pins location, if all have the same */
|
||||
int mixed; /* Mixed/multiplexed recording, not multichannel. */
|
||||
struct hdaa_pcm_devinfo *pdevinfo;
|
||||
};
|
||||
|
||||
struct hdaa_pcm_devinfo {
|
||||
device_t dev;
|
||||
struct hdaa_devinfo *devinfo;
|
||||
struct snd_mixer *mixer;
|
||||
int index;
|
||||
int registered;
|
||||
int playas, recas;
|
||||
u_char left[SOUND_MIXER_NRDEVICES];
|
||||
u_char right[SOUND_MIXER_NRDEVICES];
|
||||
int minamp[SOUND_MIXER_NRDEVICES]; /* Minimal amps in 1/4dB. */
|
||||
int maxamp[SOUND_MIXER_NRDEVICES]; /* Maximal amps in 1/4dB. */
|
||||
int chan_size;
|
||||
int chan_blkcnt;
|
||||
u_char digital;
|
||||
uint32_t ossmask; /* Mask of supported OSS devices. */
|
||||
uint32_t recsrc; /* Mask of supported OSS sources. */
|
||||
};
|
||||
|
||||
struct hdaa_devinfo {
|
||||
@ -219,6 +238,22 @@ struct hdaa_chan {
|
||||
uint8_t stripectl; /* stripe to use to all ios. */
|
||||
};
|
||||
|
||||
#define MINQDB(ctl) \
|
||||
((0 - (ctl)->offset) * ((ctl)->size + 1))
|
||||
|
||||
#define MAXQDB(ctl) \
|
||||
(((ctl)->step - (ctl)->offset) * ((ctl)->size + 1))
|
||||
|
||||
#define RANGEQDB(ctl) \
|
||||
((ctl)->step * ((ctl)->size + 1))
|
||||
|
||||
#define VAL2QDB(ctl, val) \
|
||||
(((ctl)->size + 1) * ((int)(val) - (ctl)->offset))
|
||||
|
||||
#define QDB2VAL(ctl, qdb) \
|
||||
imax(imin((((qdb) + (ctl)->size / 2 * ((qdb) > 0 ? 1 : -1)) / \
|
||||
((ctl)->size + 1) + (ctl)->offset), (ctl)->step), 0)
|
||||
|
||||
#define hdaa_codec_id(devinfo) \
|
||||
(((uint32_t)hda_get_vendor_id(devinfo->dev) << 16) + \
|
||||
hda_get_device_id(devinfo->dev))
|
||||
|
Loading…
Reference in New Issue
Block a user