Changeset 75975 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Dec 5, 2018 3:28:59 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
r75606 r75975 128 128 * @{ */ 129 129 #define AC97_BARS_VOL_MASK 0x1f /**< Volume mask for the Baseline Audio Register Set (5.7.2). */ 130 #define AC97_BARS_ VOL_STEPS 31 /**< Volume steps for the Baseline Audio Register Set (5.7.2). */130 #define AC97_BARS_GAIN_MASK 0x0f /**< Gain mask for the Baseline Audio Register Set. */ 131 131 #define AC97_BARS_VOL_MUTE_SHIFT 15 /**< Mute bit shift for the Baseline Audio Register Set (5.7.2). */ 132 132 /** @} */ … … 2105 2105 * these bits are set to 1." 2106 2106 * 2107 * Linux ALSA depends on this behavior. 2107 * Linux ALSA depends on this behavior to detect that only 5 bits are used for volume 2108 * control and the optional 6th bit is not used. Note that this logic only applies to the 2109 * master volume controls. 2108 2110 */ 2109 /// @todo Does this apply to anything other than the master volume control? 2110 if (uVal & RT_BIT(5)) /* D5 bit set? */ 2111 uVal |= RT_BIT(4) | RT_BIT(3) | RT_BIT(2) | RT_BIT(1) | RT_BIT(0); 2112 if (uVal & RT_BIT(13)) /* D13 bit set? */ 2113 uVal |= RT_BIT(12) | RT_BIT(11) | RT_BIT(10) | RT_BIT(9) | RT_BIT(8); 2111 if ((index == AC97_Master_Volume_Mute) || (index == AC97_Headphone_Volume_Mute) || (index == AC97_Master_Volume_Mono_Mute)) 2112 { 2113 if (uVal & RT_BIT(5)) /* D5 bit set? */ 2114 uVal |= RT_BIT(4) | RT_BIT(3) | RT_BIT(2) | RT_BIT(1) | RT_BIT(0); 2115 if (uVal & RT_BIT(13)) /* D13 bit set? */ 2116 uVal |= RT_BIT(12) | RT_BIT(11) | RT_BIT(10) | RT_BIT(9) | RT_BIT(8); 2117 } 2114 2118 2115 2119 const bool fCtlMuted = (uVal >> AC97_BARS_VOL_MUTE_SHIFT) & 1; … … 2162 2166 2163 2167 case PDMAUDIOMIXERCTL_MIC_IN: 2164 pSink = pThis->pSinkMicIn;2165 break;2166 2167 2168 case PDMAUDIOMIXERCTL_LINE_IN: 2168 pSink = pThis->pSinkLineIn;2169 /* These are recognized but do nothing. */ 2169 2170 break; 2170 2171 … … 2177 2178 if (pSink) 2178 2179 rc = AudioMixerSinkSetVolume(pSink, &Vol); 2180 } 2181 2182 ichac97MixerSet(pThis, index, uVal); 2183 2184 if (RT_FAILURE(rc)) 2185 LogFlowFunc(("Failed with %Rrc\n", rc)); 2186 2187 return rc; 2188 } 2189 2190 /** 2191 * Sets the gain of a specific AC'97 recording control. 2192 * 2193 * NB: gain support is currently not implemented in PDM audio. 2194 * 2195 * @returns IPRT status code. 2196 * @param pThis AC'97 state. 2197 * @param index AC'97 mixer index to set volume for. 2198 * @param enmMixerCtl Corresponding audio mixer sink. 2199 * @param uVal Volume value to set. 2200 */ 2201 static int ichac97R3MixerSetGain(PAC97STATE pThis, int index, PDMAUDIOMIXERCTL enmMixerCtl, uint32_t uVal) 2202 { 2203 /* 2204 * For AC'97 recording controls, each additional step means +1.5dB gain with 2205 * zero being 0dB gain and 15 being +22.5dB gain. 2206 */ 2207 const bool fCtlMuted = (uVal >> AC97_BARS_VOL_MUTE_SHIFT) & 1; 2208 uint8_t uCtlGainLeft = (uVal >> 8) & AC97_BARS_GAIN_MASK; 2209 uint8_t uCtlGainRight = uVal & AC97_BARS_GAIN_MASK; 2210 2211 Assert(uCtlGainLeft <= 255 / AC97_DB_FACTOR); 2212 Assert(uCtlGainRight <= 255 / AC97_DB_FACTOR); 2213 2214 LogFunc(("index=0x%x, uVal=%RU32, enmMixerCtl=%RU32\n", index, uVal, enmMixerCtl)); 2215 LogFunc(("uCtlGainLeft=%RU8, uCtlGainRight=%RU8 ", uCtlGainLeft, uCtlGainRight)); 2216 2217 uint8_t lVol = PDMAUDIO_VOLUME_MAX + uCtlGainLeft * AC97_DB_FACTOR; 2218 uint8_t rVol = PDMAUDIO_VOLUME_MAX + uCtlGainRight * AC97_DB_FACTOR; 2219 2220 /* We do not currently support gain. Since AC'97 does not support attenuation 2221 * for the recording input, the best we can do is set the maximum volume. 2222 */ 2223 # ifndef VBOX_WITH_AC97_GAIN_SUPPORT 2224 /* NB: Currently there is no gain support, only attenuation. Since AC'97 does not 2225 * support attenuation for the recording inputs, the best we can do is set the 2226 * maximum volume. 2227 */ 2228 lVol = rVol = PDMAUDIO_VOLUME_MAX; 2229 # endif 2230 2231 Log(("-> fMuted=%RTbool, lVol=%RU8, rVol=%RU8\n", fCtlMuted, lVol, rVol)); 2232 2233 int rc = VINF_SUCCESS; 2234 2235 if (pThis->pMixer) /* Device can be in reset state, so no mixer available. */ 2236 { 2237 PDMAUDIOVOLUME Vol = { fCtlMuted, lVol, rVol }; 2238 PAUDMIXSINK pSink = NULL; 2239 2240 switch (enmMixerCtl) 2241 { 2242 case PDMAUDIOMIXERCTL_MIC_IN: 2243 pSink = pThis->pSinkMicIn; 2244 break; 2245 2246 case PDMAUDIOMIXERCTL_LINE_IN: 2247 pSink = pThis->pSinkLineIn; 2248 break; 2249 2250 default: 2251 AssertFailed(); 2252 rc = VERR_NOT_SUPPORTED; 2253 break; 2254 } 2255 2256 if (pSink) { 2257 rc = AudioMixerSinkSetVolume(pSink, &Vol); 2258 /* There is only one AC'97 recording gain control. If line in 2259 * is changed, also update the microphone. If the optional dedicated 2260 * microphone is changed, only change that. 2261 * NB: The codecs we support do not have the dedicated microphone control. 2262 */ 2263 if ((pSink == pThis->pSinkLineIn) && pThis->pSinkMicIn) 2264 rc = AudioMixerSinkSetVolume(pSink, &Vol); 2265 } 2179 2266 } 2180 2267 … … 2358 2445 ichac97R3MixerSetVolume(pThis, AC97_PCM_Out_Volume_Mute, PDMAUDIOMIXERCTL_FRONT, 0x8808); 2359 2446 ichac97R3MixerSetVolume(pThis, AC97_Line_In_Volume_Mute, PDMAUDIOMIXERCTL_LINE_IN, 0x8808); 2360 ichac97R3MixerSetVolume(pThis, AC97_Mic_Volume_Mute, PDMAUDIOMIXERCTL_MIC_IN, 0x8808); 2447 ichac97R3MixerSetVolume(pThis, AC97_Mic_Volume_Mute, PDMAUDIOMIXERCTL_MIC_IN, 0x8008); 2448 2449 /* The default for record controls is 0 dB gain with mute on. */ 2450 ichac97R3MixerSetGain(pThis, AC97_Record_Gain_Mute, PDMAUDIOMIXERCTL_LINE_IN, 0x8000); 2451 ichac97R3MixerSetGain(pThis, AC97_Record_Gain_Mic_Mute, PDMAUDIOMIXERCTL_MIC_IN, 0x8000); 2361 2452 2362 2453 return VINF_SUCCESS; … … 3334 3425 /* Newer Ubuntu guests rely on that when controlling gain and muting 3335 3426 * the recording (capturing) levels. */ 3336 ichac97R3MixerSet Volume(pThis, uPortIdx, PDMAUDIOMIXERCTL_LINE_IN, u32Val);3427 ichac97R3MixerSetGain(pThis, uPortIdx, PDMAUDIOMIXERCTL_LINE_IN, u32Val); 3337 3428 #else 3338 3429 rc = VINF_IOM_R3_IOPORT_WRITE; … … 3342 3433 #ifdef IN_RING3 3343 3434 /* Ditto; see note above. */ 3344 ichac97R3MixerSet Volume(pThis, uPortIdx, PDMAUDIOMIXERCTL_MIC_IN, u32Val);3435 ichac97R3MixerSetGain(pThis, uPortIdx, PDMAUDIOMIXERCTL_MIC_IN, u32Val); 3345 3436 #else 3346 3437 rc = VINF_IOM_R3_IOPORT_WRITE; … … 3624 3715 3625 3716 ichac97R3MixerRecordSelect(pThis, ichac97MixerGet(pThis, AC97_Record_Select)); 3626 # define V_(a, b) ichac97R3MixerSetVolume(pThis, a, b, ichac97MixerGet(pThis, a)) 3627 V_(AC97_Master_Volume_Mute, PDMAUDIOMIXERCTL_VOLUME_MASTER);3628 V_(AC97_PCM_Out_Volume_Mute, PDMAUDIOMIXERCTL_FRONT);3629 V_(AC97_Line_In_Volume_Mute, PDMAUDIOMIXERCTL_LINE_IN);3630 V_(AC97_Mic_Volume_Mute, PDMAUDIOMIXERCTL_MIC_IN);3631 # undef V_ 3717 ichac97R3MixerSetVolume(pThis, AC97_Master_Volume_Mute, PDMAUDIOMIXERCTL_VOLUME_MASTER, ichac97MixerGet(pThis, AC97_Master_Volume_Mute)); 3718 ichac97R3MixerSetVolume(pThis, AC97_PCM_Out_Volume_Mute, PDMAUDIOMIXERCTL_FRONT, ichac97MixerGet(pThis, AC97_PCM_Out_Volume_Mute)); 3719 ichac97R3MixerSetVolume(pThis, AC97_Line_In_Volume_Mute, PDMAUDIOMIXERCTL_LINE_IN, ichac97MixerGet(pThis, AC97_Line_In_Volume_Mute)); 3720 ichac97R3MixerSetVolume(pThis, AC97_Mic_Volume_Mute, PDMAUDIOMIXERCTL_MIC_IN, ichac97MixerGet(pThis, AC97_Mic_Volume_Mute)); 3721 ichac97R3MixerSetGain(pThis, AC97_Record_Gain_Mic_Mute, PDMAUDIOMIXERCTL_MIC_IN, ichac97MixerGet(pThis, AC97_Record_Gain_Mic_Mute)); 3722 ichac97R3MixerSetGain(pThis, AC97_Record_Gain_Mute, PDMAUDIOMIXERCTL_LINE_IN, ichac97MixerGet(pThis, AC97_Record_Gain_Mute)); 3632 3723 if (pThis->uCodecModel == AC97_CODEC_AD1980) 3633 3724 if (ichac97MixerGet(pThis, AC97_AD_Misc) & AC97_AD_MISC_HPSEL)
Note:
See TracChangeset
for help on using the changeset viewer.