VirtualBox

Changeset 62250 in vbox for trunk/src/VBox/Devices/Audio


Ignore:
Timestamp:
Jul 14, 2016 1:17:34 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
108765
Message:

AC97: Get volume control back to more or less normal.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/DevIchAc97.cpp

    r62142 r62250  
    138138#define AC97_BARS_VOL_STEPS             31     /**< Volume steps for the Baseline Audio Register Set (5.7.2). */
    139139#define AC97_BARS_VOL_MUTE_SHIFT        15     /**< Mute bit shift for the Baseline Audio Register Set (5.7.2). */
    140 
    141 #define AC97_BARS_VOL_MASTER_MASK       0x3f   /**< Master volume mask for the Baseline Audio Register Set (5.7.2). */
    142 #define AC97_BARS_VOL_MASTER_STEPS      63     /**< Master volume steps for the Baseline Audio Register Set (5.7.2). */
    143 #define AC97_BARS_VOL_MASTER_MUTE_SHIFT 15     /**< Master Mute bit shift for the Baseline Audio Register Set (5.7.2). */
    144 
    145 #define AC97_VOL_MAX_STEPS              63
    146140/** @} */
     141
     142/* AC'97 uses 1.5dB steps, we use 0.375dB steps: 1 AC'97 step equals 4 PDM steps. */
     143#define AC97_DB_FACTOR                  4
    147144
    148145#define AC97_REC_MASK 7
     
    965962static int ichac97MixerSetVolume(PAC97STATE pThis, int index, PDMAUDIOMIXERCTL enmMixerCtl, uint32_t uVal)
    966963{
    967 #ifdef DEBUG
    968     uint32_t uValMaster = ichac97MixerGet(pThis, AC97_Master_Volume_Mute);
    969 
    970     bool    fMasterMuted = (uValMaster >> AC97_BARS_VOL_MASTER_MUTE_SHIFT) & 1;
    971     uint8_t lMasterAtt   = (uValMaster >> 8) & AC97_BARS_VOL_MASTER_MASK;
    972     uint8_t rMasterAtt   = uValMaster & AC97_BARS_VOL_MASTER_MASK;
    973 
    974     Assert(lMasterAtt <= AC97_VOL_MAX_STEPS);
    975     Assert(rMasterAtt <= AC97_VOL_MAX_STEPS);
    976 
    977     LogFlowFunc(("lMasterAtt=%RU8, rMasterAtt=%RU8, fMasterMuted=%RTbool\n", lMasterAtt, rMasterAtt, fMasterMuted));
    978 #endif
    979 
    980964    bool    fCntlMuted;
    981965    uint8_t lCntlAtt, rCntlAtt;
    982 
    983     uint8_t uSteps;
    984966
    985967    /*
     
    992974     * Linux ALSA depends on this behavior.
    993975     */
     976    //@todo: Does this apply to anything other than the master volume control?
    994977    if (uVal & RT_BIT(5))
    995978        uVal |= RT_BIT(4) | RT_BIT(3) | RT_BIT(2) | RT_BIT(1) | RT_BIT(0);
     
    997980        uVal |= RT_BIT(12) | RT_BIT(11) | RT_BIT(10) | RT_BIT(9) | RT_BIT(8);
    998981
    999     /* For the master volume, 0 corresponds to 0dB attenuation, each step
    1000      * corresponds to -1.5dB. */
    1001     if (index == AC97_Master_Volume_Mute)
    1002     {
    1003         fCntlMuted = (uVal >> AC97_BARS_VOL_MASTER_MUTE_SHIFT) & 1;
    1004         lCntlAtt   = (uVal >> 8) & AC97_BARS_VOL_MASTER_MASK;
    1005         rCntlAtt   = uVal & AC97_BARS_VOL_MASTER_MASK;
    1006 
    1007         uSteps = PDMAUDIO_VOLUME_MAX / AC97_BARS_VOL_MASTER_STEPS;
    1008     }
    1009     /* For other volume controls:
    1010      * - 0 - 7 corresponds to +12dB, in 1.5dB steps.
    1011      * - 8     corresponds to 0dB gain (unchanged).
    1012      * - 9 - X corresponds to -1.5dB steps. */
    1013     else
    1014     {
    1015         fCntlMuted = (uVal >> AC97_BARS_VOL_MUTE_SHIFT) & 1;
    1016         lCntlAtt   = (uVal >> 8) & AC97_BARS_VOL_MASK;
    1017         rCntlAtt   = uVal & AC97_BARS_VOL_MASK;
    1018 
    1019         Assert(lCntlAtt <= AC97_VOL_MAX_STEPS);
    1020         Assert(rCntlAtt <= AC97_VOL_MAX_STEPS);
    1021 
     982    fCntlMuted = (uVal >> AC97_BARS_VOL_MUTE_SHIFT) & 1;
     983    lCntlAtt   = (uVal >> 8) & AC97_BARS_VOL_MASK;
     984    rCntlAtt   = uVal & AC97_BARS_VOL_MASK;
     985
     986    /* For the master volume, 0 corresponds to 0dB attenuation. For the other volume
     987     * controls, 0 means 12dB gain and 8 means unity gain.
     988     */
     989    if (index != AC97_Master_Volume_Mute)
     990    {
    1022991#ifndef VBOX_WITH_AC97_GAIN_SUPPORT
    1023992        /* NB: Currently there is no gain support, only attenuation. */
    1024         lCntlAtt = lCntlAtt <= 8 ? 0 : lCntlAtt - 8;
    1025         rCntlAtt = rCntlAtt <= 8 ? 0 : rCntlAtt - 8;
     993        lCntlAtt = lCntlAtt < 8 ? 0 : lCntlAtt - 8;
     994        rCntlAtt = rCntlAtt < 8 ? 0 : rCntlAtt - 8;
    1026995#endif
    1027         uSteps = PDMAUDIO_VOLUME_MAX / AC97_BARS_VOL_STEPS;
    1028     }
     996    }
     997    Assert(lCntlAtt <= 255 / AC97_DB_FACTOR);
     998    Assert(rCntlAtt <= 255 / AC97_DB_FACTOR);
    1029999
    10301000    LogFunc(("index=0x%x, uVal=%RU32, enmMixerCtl=%RU32\n", index, uVal, enmMixerCtl));
    1031 
    10321001    LogFunc(("lAtt=%RU8, rAtt=%RU8 ", lCntlAtt, rCntlAtt));
    10331002
    10341003    /*
    1035      * AC'97 volume controls have 31 steps, each -1.5dB => -40,5dB attenuation total.
    1036      *
    1037      * In contrast, we're internally using 255 (PDMAUDIO_VOLUME_MAX) steps, each -0.375dB,
    1038      * where 0 corresponds to -96dB and 255 corresponds to 0dB (unchanged).
     1004     * For AC'97 volume controls, each additional step means -1.5dB attenuation with
     1005     * zero being maximum. In contrast, we're internally using 255 (PDMAUDIO_VOLUME_MAX)
     1006     * steps, each -0.375dB, where 0 corresponds to -96dB and 255 corresponds to 0dB.
    10391007     */
    1040     uint8_t lVol = PDMAUDIO_VOLUME_MAX - RT_MIN((lCntlAtt * 4 /* dB resolution */ * uSteps /* steps */), PDMAUDIO_VOLUME_MAX);
    1041     uint8_t rVol = PDMAUDIO_VOLUME_MAX - RT_MIN((rCntlAtt * 4 /* dB resolution */ * uSteps /* steps */), PDMAUDIO_VOLUME_MAX);
     1008    uint8_t lVol = PDMAUDIO_VOLUME_MAX - lCntlAtt * AC97_DB_FACTOR;
     1009    uint8_t rVol = PDMAUDIO_VOLUME_MAX - rCntlAtt * AC97_DB_FACTOR;
    10421010
    10431011    Log(("-> fMuted=%RTbool, lVol=%RU8, rVol=%RU8\n", fCntlMuted, lVol, rVol));
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette