VirtualBox

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


Ignore:
Timestamp:
Aug 9, 2010 4:03:28 AM (14 years ago)
Author:
vboxsync
Message:

Audio/HDA: fixed volume control.

Location:
trunk/src/VBox/Devices/Audio
Files:
2 edited

Legend:

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

    r31357 r31459  
    5151#define CODEC_VERB_CMD16(cmd) (CODEC_VERB_CMD((cmd), CODEC_VERB_16BIT_CMD, 16))
    5252
    53 #define CODEC_VERB_B_DIRECTION  RT_BIT(15)
    54 #define CODEC_VERB_B_SIDE       RT_BIT(13)
    55 #define CODEC_VERB_B_INDEX      0x7
    56 
    57 #define CODEC_B_DIRECTION(cmd)  (((cmd) & CODEC_VERB_B_DIRECTION) >> 15)
    58 #define CODEC_B_SIDE(cmd)       (((cmd) & CODEC_VERB_B_SIDE) >> 13)
    59 #define CODEC_B_INDEX(cmd)      ((cmd) & CODEC_VERB_B_INDEX)
     53#define CODEC_VERB_GET_AMP_DIRECTION  RT_BIT(15)
     54#define CODEC_VERB_GET_AMP_SIDE       RT_BIT(13)
     55#define CODEC_VERB_GET_AMP_INDEX      0x7
     56
     57/* HDA spec 7.3.3.7 NoteA */
     58#define CODEC_GET_AMP_DIRECTION(cmd)  (((cmd) & CODEC_VERB_GET_AMP_DIRECTION) >> 15)
     59#define CODEC_GET_AMP_SIDE(cmd)       (((cmd) & CODEC_VERB_GET_AMP_SIDE) >> 13)
     60#define CODEC_GET_AMP_INDEX(cmd)      (CODEC_GET_AMP_DIRECTION(cmd) ? 0 : ((cmd) & CODEC_VERB_GET_AMP_INDEX))
     61
     62/* HDA spec 7.3.3.7 NoteC */
     63#define CODEC_VERB_SET_AMP_OUT_DIRECTION  RT_BIT(15)
     64#define CODEC_VERB_SET_AMP_IN_DIRECTION   RT_BIT(14)
     65#define CODEC_VERB_SET_AMP_LEFT_SIDE      RT_BIT(13)
     66#define CODEC_VERB_SET_AMP_RIGHT_SIDE     RT_BIT(12)
     67#define CODEC_VERB_SET_AMP_INDEX          (0x7 << 8)
     68
     69#define CODEC_SET_AMP_IS_OUT_DIRECTION(cmd)  (((cmd) & CODEC_VERB_SET_AMP_OUT_DIRECTION) != 0)
     70#define CODEC_SET_AMP_IS_IN_DIRECTION(cmd)   (((cmd) & CODEC_VERB_SET_AMP_IN_DIRECTION) != 0)
     71#define CODEC_SET_AMP_IS_LEFT_SIDE(cmd)      (((cmd) & CODEC_VERB_SET_AMP_LEFT_SIDE) != 0)
     72#define CODEC_SET_AMP_IS_RIGHT_SIDE(cmd)     (((cmd) & CODEC_VERB_SET_AMP_RIGHT_SIDE) != 0)
     73#define CODEC_SET_AMP_INDEX(cmd)             (((cmd) & CODEC_VERB_SET_AMP_INDEX) >> 7)
    6074
    6175
     
    109123
    110124static int stac9220ResetNode(struct CODECState *pState, uint8_t nodenum, PCODECNODE pNode);
     125static int codecToAudVolume(struct CODECState *pState);
     126
     127static inline void codecSetRegister(uint32_t *pu32Reg, uint32_t u32Cmd)
     128{
     129        *pu32Reg = (*pu32Reg) & ~CODEC_VERB_8BIT_DATA;
     130        *pu32Reg = (*pu32Reg) | (u32Cmd & CODEC_VERB_8BIT_DATA);
     131}
    111132
    112133
     
    137158    }
    138159    *pResp = 0;
     160    /* HDA spec 7.3.3.7 Note A */
     161    /* @todo: if index out of range response should be 0 */
     162    uint8_t u8Index = CODEC_GET_AMP_DIRECTION(cmd) == AMPLIFIER_OUT? 0 : CODEC_GET_AMP_INDEX(cmd);
     163
    139164    PCODECNODE pNode = &pState->pNodes[CODEC_NID(cmd)];
    140165    if (STAC9220_IS_DAC_CMD(cmd))
    141166        *pResp = AMPLIFIER_REGISTER(pNode->dac.B_params,
    142                             CODEC_B_DIRECTION(cmd),
    143                             CODEC_B_SIDE(cmd),
    144                             CODEC_B_INDEX(cmd));
     167                            CODEC_GET_AMP_DIRECTION(cmd),
     168                            CODEC_GET_AMP_SIDE(cmd),
     169                            u8Index);
    145170    else if (STAC9220_IS_ADCVOL_CMD(cmd))
    146171        *pResp = AMPLIFIER_REGISTER(pNode->adcvol.B_params,
    147                             CODEC_B_DIRECTION(cmd),
    148                             CODEC_B_SIDE(cmd),
    149                             CODEC_B_INDEX(cmd));
     172                            CODEC_GET_AMP_DIRECTION(cmd),
     173                            CODEC_GET_AMP_SIDE(cmd),
     174                            u8Index);
    150175    else if (STAC9220_IS_ADCMUX_CMD(cmd))
    151176        *pResp = AMPLIFIER_REGISTER(pNode->adcmux.B_params,
    152                             CODEC_B_DIRECTION(cmd),
    153                             CODEC_B_SIDE(cmd),
    154                             CODEC_B_INDEX(cmd));
     177                            CODEC_GET_AMP_DIRECTION(cmd),
     178                            CODEC_GET_AMP_SIDE(cmd),
     179                            u8Index);
    155180    else if (STAC9220_IS_PCBEEP_CMD(cmd))
    156181        *pResp = AMPLIFIER_REGISTER(pNode->pcbeep.B_params,
    157                             CODEC_B_DIRECTION(cmd),
    158                             CODEC_B_SIDE(cmd),
    159                             CODEC_B_INDEX(cmd));
     182                            CODEC_GET_AMP_DIRECTION(cmd),
     183                            CODEC_GET_AMP_SIDE(cmd),
     184                            u8Index);
    160185    else{
    161186        AssertMsgReturn(0, ("access to fields of %x need to be implemented\n", CODEC_NID(cmd)), VINF_SUCCESS);
     
    166191static int codecSetAmplifier(struct CODECState *pState, uint32_t cmd, uint64_t *pResp)
    167192{
    168     uint32_t *pu32Bparam = NULL;
    169     Assert((CODEC_CAD(cmd) == pState->id));
    170     if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
    171     {
    172         Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
    173         return VINF_SUCCESS;
    174     }
    175     *pResp = 0;
     193    AMPLIFIER *pAmplifier = NULL;
     194    bool fIsLeft = false;
     195    bool fIsRight = false;
     196    bool fIsOut = false;
     197    bool fIsIn = false;
     198    uint8_t u8Index = 0;
     199    Assert((CODEC_CAD(cmd) == pState->id));
     200    if (CODEC_NID(cmd) >= STAC9220_NODE_COUNT)
     201    {
     202        Log(("HDAcodec: invalid node address %d\n", CODEC_NID(cmd)));
     203        return VINF_SUCCESS;
     204    }
     205    *pResp = 0;
     206    fIsOut = CODEC_SET_AMP_IS_OUT_DIRECTION(cmd);
     207    fIsIn = CODEC_SET_AMP_IS_IN_DIRECTION(cmd);
     208    fIsRight = CODEC_SET_AMP_IS_RIGHT_SIDE(cmd);
     209    fIsLeft = CODEC_SET_AMP_IS_LEFT_SIDE(cmd);
     210    u8Index = CODEC_SET_AMP_INDEX(cmd);
    176211    PCODECNODE pNode = &pState->pNodes[CODEC_NID(cmd)];
    177212    if (STAC9220_IS_DAC_CMD(cmd))
    178         pu32Bparam = &AMPLIFIER_REGISTER(pNode->dac.B_params,
    179             CODEC_B_DIRECTION(cmd),
    180             CODEC_B_SIDE(cmd),
    181             CODEC_B_INDEX(cmd));
     213        pAmplifier = &pNode->dac.B_params;
    182214    else if (STAC9220_IS_ADCVOL_CMD(cmd))
    183         pu32Bparam = &AMPLIFIER_REGISTER(pNode->adcvol.B_params,
    184             CODEC_B_DIRECTION(cmd),
    185             CODEC_B_SIDE(cmd),
    186             CODEC_B_INDEX(cmd));
     215        pAmplifier = &pNode->adcvol.B_params;
    187216    else if (STAC9220_IS_ADCMUX_CMD(cmd))
    188         pu32Bparam = &AMPLIFIER_REGISTER(pNode->adcmux.B_params,
    189             CODEC_B_DIRECTION(cmd),
    190             CODEC_B_SIDE(cmd),
    191             CODEC_B_INDEX(cmd));
     217        pAmplifier = &pNode->adcmux.B_params;
    192218    else if (STAC9220_IS_PCBEEP_CMD(cmd))
    193         pu32Bparam = &AMPLIFIER_REGISTER(pNode->pcbeep.B_params,
    194             CODEC_B_DIRECTION(cmd),
    195             CODEC_B_SIDE(cmd),
    196             CODEC_B_INDEX(cmd));
    197     Assert(pu32Bparam);
    198     if (pu32Bparam)
    199     {
    200         *pu32Bparam = (*pu32Bparam) & ~CODEC_VERB_8BIT_DATA;
    201         *pu32Bparam = (*pu32Bparam) | (cmd & CODEC_VERB_8BIT_DATA);
     219        pAmplifier = &pNode->pcbeep.B_params;
     220    if (   (!fIsLeft && !fIsRight)
     221        || (!fIsOut && !fIsIn))
     222        return VINF_SUCCESS;
     223    Assert(pAmplifier);
     224    if (pAmplifier)
     225    {
     226        if (fIsIn)
     227        {
     228            if (fIsLeft)
     229                codecSetRegister(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_LEFT, u8Index), cmd);
     230            if (fIsRight)
     231                codecSetRegister(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_IN, AMPLIFIER_RIGHT, u8Index), cmd);
     232        }
     233        if (fIsOut)
     234        {
     235            if (fIsLeft)
     236                codecSetRegister(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_OUT, AMPLIFIER_LEFT, u8Index), cmd);
     237            if (fIsRight)
     238                codecSetRegister(&AMPLIFIER_REGISTER(*pAmplifier, AMPLIFIER_OUT, AMPLIFIER_RIGHT, u8Index), cmd);
     239        }
     240        if (CODEC_NID(cmd) == 2)
     241            codecToAudVolume(pState);
    202242    }
    203243    return VINF_SUCCESS;
     
    11091149}
    11101150
     1151static int codecToAudVolume(struct CODECState *pState)
     1152{
     1153    PCODECNODE pNode = &pState->pNodes[2];
     1154    int mute = AMPLIFIER_REGISTER(pNode->dac.B_params, AMPLIFIER_OUT, AMPLIFIER_LEFT, 0) & RT_BIT(7);
     1155    mute |= AMPLIFIER_REGISTER(pNode->dac.B_params, AMPLIFIER_OUT, AMPLIFIER_RIGHT, 0) & RT_BIT(7);
     1156    mute >>=7;
     1157    mute &= 0x1;
     1158    uint8_t lVol = AMPLIFIER_REGISTER(pNode->dac.B_params, AMPLIFIER_OUT, AMPLIFIER_LEFT, 0) & 0x7f;
     1159    uint8_t rVol = AMPLIFIER_REGISTER(pNode->dac.B_params, AMPLIFIER_OUT, AMPLIFIER_RIGHT, 0) & 0x7f;
     1160    AUD_set_volume(AUD_MIXER_VOLUME, &mute, &lVol, &rVol);
     1161    return VINF_SUCCESS;
     1162}
     1163
    11111164static CODECVERB STAC9220VERB[] =
    11121165{
     
    12331286    if (!pState->voice_po)
    12341287        LogRel (("HDAcodec: WARNING: Unable to open PCM OUT!\n"));
    1235     int mute = 0;
    1236     uint8_t lvol = 0x7f;
    1237     uint8_t rvol = 0x7f;
    1238     AUD_set_volume_out(pState->voice_po, mute, lvol, rvol);
     1288    codecToAudVolume(pState);
    12391289    return VINF_SUCCESS;
    12401290}
  • trunk/src/VBox/Devices/Audio/DevIchIntelHDA.cpp

    r31439 r31459  
    581581{
    582582    bool fIrq = false;
    583    /* @todo add state change */
    584583    if(   INTCTL_CIE(pState)
    585584       && (   RIRBSTS_RINTFL(pState)
Note: See TracChangeset for help on using the changeset viewer.

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