VirtualBox

Changeset 55394 in vbox


Ignore:
Timestamp:
Apr 22, 2015 10:26:00 PM (10 years ago)
Author:
vboxsync
Message:

Audio: Volume handling rework (see #5964).

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

Legend:

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

    r55387 r55394  
    5757# endif
    5858#endif
     59
     60
     61/*
     62 *   Soft Volume Control
     63 *
     64 * The external code supplies an 8-bit volume (attenuation) value in the
     65 * 0 .. 255 range. This represents 0 to -96dB attenuation where an input
     66 * value of 0 corresponds to -96dB and 255 corresponds to 0dB (unchanged).
     67 *
     68 * Each step thus correspons to 96 / 256 or 0.375dB. Every 6dB (16 steps)
     69 * represents doubling the sample value.
     70 *
     71 * For internal use, the volume control needs to be converted to a 16-bit
     72 * (sort of) exponential value between 1 and 65536. This is used with fixed
     73 * point arithmetic such that 65536 means 1.0 and 1 means 1/65536.
     74 *
     75 * For actual volume calculation, 33.31 fixed point is used. Maximum (or
     76 * unattenuated) volume is represented as 0x80000000; conveniently, this
     77 * value fits into a uint32_t.
     78 */
     79
     80
     81/**   Logarithmic/exponential volume conversion table. */
     82uint32_t aVolumeConv[256] = {
     83        1,     1,     1,     1,     1,     1,     1,     1, /*   7 */
     84        1,     2,     2,     2,     2,     2,     2,     2, /*  15 */
     85        2,     2,     2,     2,     2,     3,     3,     3, /*  23 */
     86        3,     3,     3,     3,     4,     4,     4,     4, /*  31 */
     87        4,     4,     5,     5,     5,     5,     5,     6, /*  39 */
     88        6,     6,     6,     7,     7,     7,     8,     8, /*  47 */
     89        8,     9,     9,    10,    10,    10,    11,    11, /*  55 */
     90       12,    12,    13,    13,    14,    15,    15,    16, /*  63 */
     91       17,    17,    18,    19,    20,    21,    22,    23, /*  71 */
     92       24,    25,    26,    27,    28,    29,    31,    32, /*  79 */
     93       33,    35,    36,    38,    40,    41,    43,    45, /*  87 */
     94       47,    49,    52,    54,    56,    59,    61,    64, /*  95 */
     95       67,    70,    73,    76,    79,    83,    87,    91, /* 103 */
     96       95,    99,   103,   108,   112,   117,   123,   128, /* 111 */
     97      134,   140,   146,   152,   159,   166,   173,   181, /* 119 */
     98      189,   197,   206,   215,   225,   235,   245,   256, /* 127 */
     99      267,   279,   292,   304,   318,   332,   347,   362, /* 135 */
     100      378,   395,   412,   431,   450,   470,   490,   512, /* 143 */
     101      535,   558,   583,   609,   636,   664,   693,   724, /* 151 */
     102      756,   790,   825,   861,   899,   939,   981,  1024, /* 159 */
     103     1069,  1117,  1166,  1218,  1272,  1328,  1387,  1448, /* 167 */
     104     1512,  1579,  1649,  1722,  1798,  1878,  1961,  2048, /* 175 */
     105     2139,  2233,  2332,  2435,  2543,  2656,  2774,  2896, /* 183 */
     106     3025,  3158,  3298,  3444,  3597,  3756,  3922,  4096, /* 191 */
     107     4277,  4467,  4664,  4871,  5087,  5312,  5547,  5793, /* 199 */
     108     6049,  6317,  6597,  6889,  7194,  7512,  7845,  8192, /* 207 */
     109     8555,  8933,  9329,  9742, 10173, 10624, 11094, 11585, /* 215 */
     110    12098, 12634, 13193, 13777, 14387, 15024, 15689, 16384, /* 223 */
     111    17109, 17867, 18658, 19484, 20347, 21247, 22188, 23170, /* 231 */
     112    24196, 25268, 26386, 27554, 28774, 30048, 31379, 32768, /* 239 */
     113    34219, 35734, 37316, 38968, 40693, 42495, 44376, 46341, /* 247 */
     114    48393, 50535, 52773, 55109, 57549, 60097, 62757, 65536, /* 255 */
     115};
    59116
    60117/**
     
    11411198    pMixBuf->Volume.uLeft  = (UINT64_C(0x80000000) * pVol->uLeft) / 255;
    11421199    pMixBuf->Volume.uRight = (UINT64_C(0x80000000) * pVol->uRight) / 255;
     1200    //@todo: Ensure that the input is in the correct range/initialized!
     1201    pMixBuf->Volume.uLeft  = aVolumeConv[pVol->uLeft  & 0xFF] * UINT64_C(0x8000);
     1202    pMixBuf->Volume.uRight = aVolumeConv[pVol->uRight & 0xFF] * UINT64_C(0x8000);
    11431203
    11441204    LogFlowFunc(("\t-> lVol=%RU32, rVol=%RU32\n", pMixBuf->Volume.uLeft, pMixBuf->Volume.uRight));
  • trunk/src/VBox/Devices/Audio/DevIchAc97.cpp

    r55335 r55394  
    844844{
    845845    int mute = (val >> MUTE_SHIFT) & 1;
    846     uint8_t rvol = VOL_MASK - (val & VOL_MASK);
    847     uint8_t lvol = VOL_MASK - ((val >> 8) & VOL_MASK);
    848     rvol = 255 * rvol / VOL_MASK;
    849     lvol = 255 * lvol / VOL_MASK;
    850 
    851     LogFunc(("mt=%ld, val=%RU32, mute=%RTbool\n", mt, val, RT_BOOL(mute)));
     846    uint8_t rvol = val & VOL_MASK;
     847    uint8_t lvol = (val >> 8) & VOL_MASK;
     848    /* AC'97 has 1.5dB steps; we use 0.375dB steps. */
     849    rvol = 255 - rvol * 4;
     850    lvol = 255 - lvol * 4;
     851
     852    LogFunc(("mt=%ld, val=%RX32, mute=%RTbool\n", mt, val, RT_BOOL(mute)));
    852853
    853854#ifdef SOFT_VOLUME
  • trunk/src/VBox/Devices/Audio/DevIchHdaCodec.cpp

    r55388 r55394  
    12051205
    12061206    /* The STAC9220 volume controls have 0 to -96dB attenuation range in 128 steps.
    1207      * We have 0 to -48dB range in 256 steps. HDA volume setting of 127 must map
    1208      * to 255 internally (0dB), while HDA volume setting of 63 (-48dB) and below
    1209      * should map  to 1 (rather than zero) internally.
     1207     * We have 0 to -96dB range in 256 steps. HDA volume setting of 127 must map
     1208     * to 255 internally (0dB), while HDA volume setting of 0 (-96dB) should map
     1209     * to 1 (rather than zero) internally.
    12101210     */
    1211     if (lVol > 63)
    1212         lVol = (lVol - 63) * (4 * 255) / 256;
    1213     else
    1214         lVol = 1;   /* Not quite zero. */
    1215 
    1216     if (rVol > 63)
    1217         rVol = (rVol - 63) * (4 * 255) / 256;
    1218     else
    1219         rVol = 1;   /* Not quite zero. */
     1211    lVol = (lVol + 1) * (2 * 255) / 256;
     1212    rVol = (rVol + 1) * (2 * 255) / 256;
    12201213
    12211214#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
  • trunk/src/VBox/Devices/Audio/DevSB16.cpp

    r55355 r55394  
    10571057}
    10581058
     1059static uint8_t sb16MixRegToVol(PSB16STATE pThis, int reg)
     1060{
     1061    /* The SB16 mixer has a 0 to -62dB range in 32 levels (2dB each step).
     1062     * We use a 0 to -96dB range in 256 levels (0.375dB each step).
     1063     * Only the top 5 bits of a mixer register are used.
     1064     */
     1065    uint8_t steps = 31 - (pThis->mixer_regs[reg] >> 3);
     1066    uint8_t vol   = 255 - steps * 16 / 3;   /* (2dB*8) / (0.375dB*8) */
     1067    return vol;
     1068}
     1069
     1070static void sb16SetMasterVolume(PSB16STATE pThis)
     1071{
     1072    int     mute = 0; /** @todo Handle (un)muting. */
     1073#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1074    uint8_t lvol = sb16MixRegToVol(pThis, 0x30);
     1075    uint8_t rvol = sb16MixRegToVol(pThis, 0x31);
     1076    PDMAUDIOVOLUME vol = { RT_BOOL(mute), lvol, rvol };
     1077    audioMixerSetMasterVolume(pThis->pMixer, &vol);
     1078#else
     1079    uint8_t lvol = pThis->mixer_regs[0x30];
     1080    uint8_t rvol = pThis->mixer_regs[0x31];
     1081
     1082    AUD_set_volume(AUD_MIXER_VOLUME, &mute, &lvol, &rvol);
     1083#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     1084}
     1085
     1086static void sb16SetPcmOutVolume(PSB16STATE pThis)
     1087{
     1088    int     mute = 0; /** @todo Handle (un)muting. */
     1089#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     1090    uint8_t lvol = sb16MixRegToVol(pThis, 0x32);
     1091    uint8_t rvol = sb16MixRegToVol(pThis, 0x33);
     1092    PDMAUDIOVOLUME vol = { RT_BOOL(mute), lvol, rvol };
     1093    audioMixerSetSinkVolume(pThis->pSinkOutput, &vol);
     1094#else
     1095    uint8_t lvol = pThis->mixer_regs[0x32];
     1096    uint8_t rvol = pThis->mixer_regs[0x33];
     1097
     1098    AUD_set_volume(AUD_MIXER_PCM, &mute, &lvol, &rvol);
     1099#endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
     1100}
     1101
    10591102static void sb16ResetLegacy(PSB16STATE pThis)
    10601103{
     
    13231366
    13241367    /* voice volume L d5,d7, R d1,d3 */
    1325     pThis->mixer_regs[0x04] = (4 << 5) | (4 << 1);
     1368    pThis->mixer_regs[0x04] = (12 << 4) | 12;
    13261369    /* master ... */
    1327     pThis->mixer_regs[0x22] = (4 << 5) | (4 << 1);
     1370    pThis->mixer_regs[0x22] = (12 << 4) | 12;
    13281371    /* MIDI ... */
    1329     pThis->mixer_regs[0x26] = (4 << 5) | (4 << 1);
    1330 
    1331     for (int i = 0x30; i < 0x48; i++)
    1332         pThis->mixer_regs[i] = 0x20;
     1372    pThis->mixer_regs[0x26] = (12 << 4) | 12;
     1373
     1374    /* master/voice/MIDI L/R volume */
     1375    for (int i = 0x30; i < 0x36; i++)
     1376        pThis->mixer_regs[i] = 24 << 3; /* -14 dB */
     1377
     1378    /* treble/bass */
     1379    for (int i = 0x44; i < 0x48; i++)
     1380        pThis->mixer_regs[i] = 0x80;
    13331381
    13341382#ifdef VBOX_WITH_PDM_AUDIO_DRIVER
     
    13521400    }
    13531401#endif
     1402
     1403    /* Update the master (mixer) and PCM out volumes. */
     1404    sb16SetMasterVolume(pThis);
     1405    sb16SetPcmOutVolume(pThis);
    13541406}
    13551407
     
    14751527    /* Update the master (mixer) volume. */
    14761528    if (fUpdateMaster)
    1477     {
    1478         int     mute = 0; /** @todo Handle (un)muting. */
    1479         uint8_t lvol = pThis->mixer_regs[0x30];
    1480         uint8_t rvol = pThis->mixer_regs[0x31];
    1481 
    1482 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1483         PDMAUDIOVOLUME vol = { RT_BOOL(mute), lvol, rvol };
    1484         audioMixerSetMasterVolume(pThis->pMixer, &vol);
    1485 #else
    1486         AUD_set_volume(AUD_MIXER_VOLUME, &mute, &lvol, &rvol);
    1487 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    1488     }
     1529        sb16SetMasterVolume(pThis);
    14891530
    14901531    /* Update the stream (PCM) volume. */
    14911532    if (fUpdateStream)
    1492     {
    1493         int     mute = 0; /** @todo Handle (un)muting. */
    1494         uint8_t lvol = pThis->mixer_regs[0x32];
    1495         uint8_t rvol = pThis->mixer_regs[0x33];
    1496 
    1497 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER
    1498         PDMAUDIOVOLUME vol = { RT_BOOL(mute), lvol, rvol };
    1499         audioMixerSetSinkVolume(pThis->pSinkOutput, &vol);
    1500 #else
    1501         AUD_set_volume(AUD_MIXER_PCM, &mute, &lvol, &rvol);
    1502 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */
    1503     }
     1533        sb16SetPcmOutVolume(pThis);
    15041534
    15051535    return VINF_SUCCESS;
     
    20472077        uLUN++;
    20482078    }
     2079    /* Ensure volume gets propagated. */
     2080    audioMixerInvalidate(pThis->pMixer);
    20492081
    20502082    return rc;
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