Fractional multiplication with the maximal value 2^31-1 causes some tiny distortion. Instead, we want to multiply with the full 2^31. The catch is of course that this cannot be represented in the DSP's signed 32 bit registers. One way to deal with this is to encode 1.0 as a negative number and special-case it. As a matter of fact, the SbLive! code path already contained such code, though the controls never actually exercised it. A more efficient approach is to use negative values, which actually extend to -2^31. Accordingly, for all the volume adjustments we now use the MAC1 instruction which negates the X operand. The range of the controls in highres mode is extended downwards, so -1 is the new zero/mute. At maximal excursion, real zero is not mute any more, but I don't think anyone will notice this behavior change. ;-) That also required making the min/max/values in the control structs signed. This technically changes the user space interface, but it seems implausible that someone would notice - the numbers were actually treated as if they were signed anyway (and in the actual mixer iface they _are_). And without this change, the min value didn't even make sense in the first place (and no-one noticed, because it was always 0).
Showing the changes to include/uapi (1 of 3 files). Show all
Unified · Split
| @@ -308,6 +308,8 @@ struct snd_emu10k1_fx8010_info { · 307 unmodified lines | ||
| 308 | 308 | #define EMU10K1_GPR_TRANSLATION_BASS 2 |
| 309 | 309 | #define EMU10K1_GPR_TRANSLATION_TREBLE 3 |
| 310 | 310 | #define EMU10K1_GPR_TRANSLATION_ONOFF 4 |
| 311 | +#define EMU10K1_GPR_TRANSLATION_NEGATE 5 | |
| 312 | +#define EMU10K1_GPR_TRANSLATION_NEG_TABLE100 6 | |
| 311 | 313 | |
| 312 | 314 | enum emu10k1_ctl_elem_iface { |
| 313 | 315 | EMU10K1_CTL_ELEM_IFACE_MIXER = 2, /* virtual mixer device */ |
| @@ -328,9 +330,9 @@ struct snd_emu10k1_fx8010_control_gpr { · 14 unmodified lines | ||
| 328 | 330 | unsigned int vcount; /* visible count */ |
| 329 | 331 | unsigned int count; /* count of GPR (1..16) */ |
| 330 | 332 | unsigned short gpr[32]; /* GPR number(s) */ |
| 331 | − unsigned int value[32]; /* initial values */ | |
| 332 | − unsigned int min; /* minimum range */ | |
| 333 | − unsigned int max; /* maximum range */ | |
| 333 | + int value[32]; /* initial values */ | |
| 334 | + int min; /* minimum range */ | |
| 335 | + int max; /* maximum range */ | |
| 334 | 336 | unsigned int translation; /* translation type (EMU10K1_GPR_TRANSLATION*) */ |
| 335 | 337 | const unsigned int *tlv; |
| 336 | 338 | }; |