VirtualBox

Changeset 82231 in vbox for trunk/src


Ignore:
Timestamp:
Nov 27, 2019 12:10:19 AM (5 years ago)
Author:
vboxsync
Message:

DevSB16: Function re-ordering. bugref:9218

File:
1 edited

Legend:

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

    r82230 r82231  
    229229*   Internal Functions                                                                                                           *
    230230*********************************************************************************************************************************/
    231 static int sb16CheckAndReOpenOut(PPDMDEVINS pDevIns, PSB16STATE pThis);
    232 static int sb16OpenOut(PPDMDEVINS pDevIns, PSB16STATE pThis, PPDMAUDIOSTREAMCFG pCfg);
     231static int  sb16CheckAndReOpenOut(PPDMDEVINS pDevIns, PSB16STATE pThis);
     232static int  sb16OpenOut(PPDMDEVINS pDevIns, PSB16STATE pThis, PPDMAUDIOSTREAMCFG pCfg);
    233233static void sb16CloseOut(PSB16STATE pThis);
    234234static void sb16TimerMaybeStart(PPDMDEVINS pDevIns, PSB16STATE pThis);
    235235static void sb16TimerMaybeStop(PSB16STATE pThis);
    236236
    237 
    238 
    239 static int magic_of_irq(int irq)
    240 {
    241     switch (irq)
    242     {
    243         case 5:
    244             return 2;
    245         case 7:
    246             return 4;
    247         case 9:
    248             return 1;
    249         case 10:
    250             return 8;
    251         default:
    252             break;
    253     }
    254 
    255     LogFlowFunc(("bad irq %d\n", irq));
    256     return 2;
    257 }
    258 
    259 static int irq_of_magic(int magic)
    260 {
    261     switch (magic)
    262     {
    263         case 1:
    264             return 9;
    265         case 2:
    266             return 5;
    267         case 4:
    268             return 7;
    269         case 8:
    270             return 10;
    271         default:
    272             break;
    273     }
    274 
    275     LogFlowFunc(("bad irq magic %d\n", magic));
    276     return -1;
    277 }
    278237
    279238#if 0 // unused // def DEBUG
     
    927886    pThis->cmd = -1;
    928887    return;
    929 }
    930 
    931 static uint8_t sb16MixRegToVol(PSB16STATE pThis, int reg)
    932 {
    933     /* The SB16 mixer has a 0 to -62dB range in 32 levels (2dB each step).
    934      * We use a 0 to -96dB range in 256 levels (0.375dB each step).
    935      * Only the top 5 bits of a mixer register are used.
    936      */
    937     uint8_t steps = 31 - (pThis->mixer_regs[reg] >> 3);
    938     uint8_t vol   = 255 - steps * 16 / 3;   /* (2dB*8) / (0.375dB*8) */
    939     return vol;
    940 }
    941 
    942 /**
    943  * Returns the device's current master volume.
    944  *
    945  * @param   pThis               SB16 state.
    946  * @param   pVol                Where to store the master volume information.
    947  */
    948 static void sb16GetMasterVolume(PSB16STATE pThis, PPDMAUDIOVOLUME pVol)
    949 {
    950     /* There's no mute switch, only volume controls. */
    951     uint8_t lvol = sb16MixRegToVol(pThis, 0x30);
    952     uint8_t rvol = sb16MixRegToVol(pThis, 0x31);
    953 
    954     pVol->fMuted = false;
    955     pVol->uLeft  = lvol;
    956     pVol->uRight = rvol;
    957 }
    958 
    959 /**
    960  * Returns the device's current output stream volume.
    961  *
    962  * @param   pThis               SB16 state.
    963  * @param   pVol                Where to store the output stream volume information.
    964  */
    965 static void sb16GetPcmOutVolume(PSB16STATE pThis, PPDMAUDIOVOLUME pVol)
    966 {
    967     /* There's no mute switch, only volume controls. */
    968     uint8_t lvol = sb16MixRegToVol(pThis, 0x32);
    969     uint8_t rvol = sb16MixRegToVol(pThis, 0x33);
    970 
    971     pVol->fMuted = false;
    972     pVol->uLeft  = lvol;
    973     pVol->uRight = rvol;
    974 }
    975 
    976 static void sb16UpdateVolume(PSB16STATE pThis)
    977 {
    978     PDMAUDIOVOLUME VolMaster;
    979     sb16GetMasterVolume(pThis, &VolMaster);
    980 
    981     PDMAUDIOVOLUME VolOut;
    982     sb16GetPcmOutVolume(pThis, &VolOut);
    983 
    984     /* Combine the master + output stream volume. */
    985     PDMAUDIOVOLUME VolCombined;
    986     RT_ZERO(VolCombined);
    987 
    988     VolCombined.fMuted = VolMaster.fMuted || VolOut.fMuted;
    989     if (!VolCombined.fMuted)
    990     {
    991         VolCombined.uLeft  = (   (VolOut.uLeft    ? VolOut.uLeft     : 1)
    992                                * (VolMaster.uLeft ? VolMaster.uLeft  : 1)) / PDMAUDIO_VOLUME_MAX;
    993 
    994         VolCombined.uRight = (  (VolOut.uRight    ? VolOut.uRight    : 1)
    995                               * (VolMaster.uRight ? VolMaster.uRight : 1)) / PDMAUDIO_VOLUME_MAX;
    996     }
    997 
    998     PSB16DRIVER pDrv;
    999     RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
    1000     {
    1001         PPDMAUDIOSTREAM pStream = pDrv->Out.pStream;
    1002         if (pStream)
    1003         {
    1004             int rc2 = pDrv->pConnector->pfnStreamSetVolume(pDrv->pConnector, pStream, &VolCombined);
    1005             AssertRC(rc2);
    1006         }
    1007     }
    1008888}
    1009889
     
    12441124}
    12451125
     1126
     1127/* -=-=-=-=-=- Mixer -=-=-=-=-=- */
     1128
     1129static uint8_t sb16MixRegToVol(PSB16STATE pThis, int reg)
     1130{
     1131    /* The SB16 mixer has a 0 to -62dB range in 32 levels (2dB each step).
     1132     * We use a 0 to -96dB range in 256 levels (0.375dB each step).
     1133     * Only the top 5 bits of a mixer register are used.
     1134     */
     1135    uint8_t steps = 31 - (pThis->mixer_regs[reg] >> 3);
     1136    uint8_t vol   = 255 - steps * 16 / 3;   /* (2dB*8) / (0.375dB*8) */
     1137    return vol;
     1138}
     1139
     1140/**
     1141 * Returns the device's current master volume.
     1142 *
     1143 * @param   pThis               SB16 state.
     1144 * @param   pVol                Where to store the master volume information.
     1145 */
     1146static void sb16GetMasterVolume(PSB16STATE pThis, PPDMAUDIOVOLUME pVol)
     1147{
     1148    /* There's no mute switch, only volume controls. */
     1149    uint8_t lvol = sb16MixRegToVol(pThis, 0x30);
     1150    uint8_t rvol = sb16MixRegToVol(pThis, 0x31);
     1151
     1152    pVol->fMuted = false;
     1153    pVol->uLeft  = lvol;
     1154    pVol->uRight = rvol;
     1155}
     1156
     1157/**
     1158 * Returns the device's current output stream volume.
     1159 *
     1160 * @param   pThis               SB16 state.
     1161 * @param   pVol                Where to store the output stream volume information.
     1162 */
     1163static void sb16GetPcmOutVolume(PSB16STATE pThis, PPDMAUDIOVOLUME pVol)
     1164{
     1165    /* There's no mute switch, only volume controls. */
     1166    uint8_t lvol = sb16MixRegToVol(pThis, 0x32);
     1167    uint8_t rvol = sb16MixRegToVol(pThis, 0x33);
     1168
     1169    pVol->fMuted = false;
     1170    pVol->uLeft  = lvol;
     1171    pVol->uRight = rvol;
     1172}
     1173
     1174static void sb16UpdateVolume(PSB16STATE pThis)
     1175{
     1176    PDMAUDIOVOLUME VolMaster;
     1177    sb16GetMasterVolume(pThis, &VolMaster);
     1178
     1179    PDMAUDIOVOLUME VolOut;
     1180    sb16GetPcmOutVolume(pThis, &VolOut);
     1181
     1182    /* Combine the master + output stream volume. */
     1183    PDMAUDIOVOLUME VolCombined;
     1184    RT_ZERO(VolCombined);
     1185
     1186    VolCombined.fMuted = VolMaster.fMuted || VolOut.fMuted;
     1187    if (!VolCombined.fMuted)
     1188    {
     1189        VolCombined.uLeft  = (   (VolOut.uLeft    ? VolOut.uLeft     : 1)
     1190                               * (VolMaster.uLeft ? VolMaster.uLeft  : 1)) / PDMAUDIO_VOLUME_MAX;
     1191
     1192        VolCombined.uRight = (  (VolOut.uRight    ? VolOut.uRight    : 1)
     1193                              * (VolMaster.uRight ? VolMaster.uRight : 1)) / PDMAUDIO_VOLUME_MAX;
     1194    }
     1195
     1196    PSB16DRIVER pDrv;
     1197    RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
     1198    {
     1199        PPDMAUDIOSTREAM pStream = pDrv->Out.pStream;
     1200        if (pStream)
     1201        {
     1202            int rc2 = pDrv->pConnector->pfnStreamSetVolume(pDrv->pConnector, pStream, &VolCombined);
     1203            AssertRC(rc2);
     1204        }
     1205    }
     1206}
     1207
    12461208static void sb16MixerReset(PSB16STATE pThis)
    12471209{
     
    12771239    /* Update the master (mixer) and PCM out volumes. */
    12781240    sb16UpdateVolume(pThis);
     1241}
     1242
     1243static int magic_of_irq(int irq)
     1244{
     1245    switch (irq)
     1246    {
     1247        case 5:
     1248            return 2;
     1249        case 7:
     1250            return 4;
     1251        case 9:
     1252            return 1;
     1253        case 10:
     1254            return 8;
     1255        default:
     1256            break;
     1257    }
     1258
     1259    LogFlowFunc(("bad irq %d\n", irq));
     1260    return 2;
     1261}
     1262
     1263static int irq_of_magic(int magic)
     1264{
     1265    switch (magic)
     1266    {
     1267        case 1:
     1268            return 9;
     1269        case 2:
     1270            return 5;
     1271        case 4:
     1272            return 7;
     1273        case 8:
     1274            return 10;
     1275        default:
     1276            break;
     1277    }
     1278
     1279    LogFlowFunc(("bad irq magic %d\n", magic));
     1280    return -1;
    12791281}
    12801282
     
    15091511}
    15101512
    1511 /**
    1512  * Called by sb16DMARead.
     1513
     1514/* -=-=-=-=-=- DMA -=-=-=-=-=- */
     1515
     1516/**
     1517 * Worker for sb16DMARead.
    15131518 */
    15141519static int sb16WriteAudio(PSB16STATE pThis, int nchan, uint32_t dma_pos, uint32_t dma_len, int len)
     
    15791584 *      Worker callback for both DMA channels.}
    15801585 */
    1581 static DECLCALLBACK(uint32_t) sb16DMARead(PPDMDEVINS pDevIns, void *opaque, unsigned nchan, uint32_t dma_pos, uint32_t dma_len)
     1586static DECLCALLBACK(uint32_t) sb16DMARead(PPDMDEVINS pDevIns, void *pvUser, unsigned uChannel, uint32_t off, uint32_t cb)
     1587
    15821588{
    15831589    RT_NOREF(pDevIns);
    1584     PSB16STATE pThis = (PSB16STATE)opaque;
     1590    PSB16STATE pThis = (PSB16STATE)pvUser;
    15851591    int till, copy, written, free;
    15861592
    15871593    if (pThis->block_size <= 0)
    15881594    {
    1589         LogFlowFunc(("invalid block size=%d nchan=%d dma_pos=%d dma_len=%d\n",
    1590                      pThis->block_size, nchan, dma_pos, dma_len));
    1591         return dma_pos;
     1595        LogFlowFunc(("invalid block size=%d uChannel=%d off=%d cb=%d\n", pThis->block_size, uChannel, off, cb));
     1596        return off;
    15921597    }
    15931598
     
    15951600        pThis->left_till_irq = pThis->block_size;
    15961601
    1597     free = dma_len;
     1602    free = cb;
    15981603
    15991604    copy = free;
     
    16011606
    16021607#ifdef DEBUG_SB16_MOST
    1603     LogFlowFunc(("pos:%06d %d till:%d len:%d\n", dma_pos, free, till, dma_len));
     1608    LogFlowFunc(("pos:%06d %d till:%d len:%d\n", off, free, till, cb));
    16041609#endif
    16051610
     
    16171622    }
    16181623
    1619     written = sb16WriteAudio(pThis, nchan, dma_pos, dma_len, copy);
    1620     dma_pos = (dma_pos + written) % dma_len;
     1624    written = sb16WriteAudio(pThis, uChannel, off, cb, copy);
     1625    off = (off + written) % cb;
    16211626    pThis->left_till_irq -= written;
    16221627
    16231628    if (pThis->left_till_irq <= 0)
    16241629    {
    1625         pThis->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
     1630        pThis->mixer_regs[0x82] |= (uChannel & 4) ? 2 : 1;
    16261631        PDMDevHlpISASetIrq(pThis->pDevInsR3, pThis->irq, 1);
    16271632        if (0 == pThis->dma_auto)
     
    16331638
    16341639    Log3Func(("pos %d/%d free %5d till %5d copy %5d written %5d block_size %5d\n",
    1635                dma_pos, dma_len, free, pThis->left_till_irq, copy, written, pThis->block_size));
     1640              off, cb, free, pThis->left_till_irq, copy, written, pThis->block_size));
    16361641
    16371642    while (pThis->left_till_irq <= 0)
    16381643        pThis->left_till_irq += pThis->block_size;
    16391644
    1640     return dma_pos;
    1641 }
     1645    return off;
     1646}
     1647
     1648
     1649/* -=-=-=-=-=- I/O timer -=-=-=-=-=- */
    16421650
    16431651static void sb16TimerMaybeStart(PPDMDEVINS pDevIns, PSB16STATE pThis)
     
    17411749    }
    17421750}
     1751
     1752
     1753/* -=-=-=-=-=- Streams? -=-=-=-=-=- */
     1754
     1755/**
     1756 * Creates a PDM audio stream for a specific driver.
     1757 *
     1758 * @returns IPRT status code.
     1759 * @param   pCfg                Stream configuration to use.
     1760 * @param   pDrv                Driver stream to create PDM stream for.
     1761 */
     1762static int sb16CreateDrvStream(PPDMAUDIOSTREAMCFG pCfg, PSB16DRIVER pDrv)
     1763{
     1764    AssertReturn(pCfg->enmDir == PDMAUDIODIR_OUT, VERR_INVALID_PARAMETER);
     1765    Assert(DrvAudioHlpStreamCfgIsValid(pCfg));
     1766
     1767    PPDMAUDIOSTREAMCFG pCfgHost = DrvAudioHlpStreamCfgDup(pCfg);
     1768    if (!pCfgHost)
     1769        return VERR_NO_MEMORY;
     1770
     1771    LogFunc(("[LUN#%RU8] %s\n", pDrv->uLUN, pCfgHost->szName));
     1772
     1773    AssertMsg(pDrv->Out.pStream == NULL, ("[LUN#%RU8] Driver stream already present when it must not\n", pDrv->uLUN));
     1774
     1775    /* Disable pre-buffering for SB16; not needed for that bit of data. */
     1776    pCfgHost->Backend.cfPreBuf = 0;
     1777
     1778    int rc = pDrv->pConnector->pfnStreamCreate(pDrv->pConnector, pCfgHost, pCfg /* pCfgGuest */, &pDrv->Out.pStream);
     1779    if (RT_SUCCESS(rc))
     1780    {
     1781        pDrv->pConnector->pfnStreamRetain(pDrv->pConnector, pDrv->Out.pStream);
     1782        LogFlowFunc(("LUN#%RU8: Created output \"%s\", rc=%Rrc\n", pDrv->uLUN, pCfg->szName, rc));
     1783    }
     1784
     1785    DrvAudioHlpStreamCfgFree(pCfgHost);
     1786
     1787    return rc;
     1788}
     1789
     1790/**
     1791 * Destroys a PDM audio stream of a specific driver.
     1792 *
     1793 * @param   pThis               SB16 state.
     1794 * @param   pDrv                Driver stream to destroy PDM stream for.
     1795 */
     1796static void sb16DestroyDrvStream(PSB16STATE pThis, PSB16DRIVER pDrv)
     1797{
     1798    AssertPtr(pThis);
     1799    AssertPtr(pDrv);
     1800
     1801    if (pDrv->Out.pStream)
     1802    {
     1803        pDrv->pConnector->pfnStreamRelease(pDrv->pConnector, pDrv->Out.pStream);
     1804
     1805        int rc2 = pDrv->pConnector->pfnStreamControl(pDrv->pConnector, pDrv->Out.pStream, PDMAUDIOSTREAMCMD_DISABLE);
     1806        AssertRC(rc2);
     1807
     1808        rc2 = pDrv->pConnector->pfnStreamDestroy(pDrv->pConnector, pDrv->Out.pStream);
     1809        AssertRC(rc2);
     1810
     1811        pDrv->Out.pStream = NULL;
     1812    }
     1813}
     1814
     1815/**
     1816 * Checks if the output stream needs to be (re-)created and does so if needed.
     1817 *
     1818 * @return  VBox status code.
     1819 * @param   pDevIns         The device instance.
     1820 * @param   pThis           SB16 state.
     1821 */
     1822static int sb16CheckAndReOpenOut(PPDMDEVINS pDevIns, PSB16STATE pThis)
     1823{
     1824    AssertPtr(pThis);
     1825
     1826    int rc = VINF_SUCCESS;
     1827
     1828    if (pThis->freq > 0)
     1829    {
     1830        /* At the moment we only have one stream, the output stream. */
     1831        PDMAUDIOSTREAMCFG Cfg;
     1832        RT_ZERO(Cfg);
     1833
     1834        Cfg.Props.uHz       = pThis->freq;
     1835        Cfg.Props.cChannels = 1 << pThis->fmt_stereo;
     1836        Cfg.Props.cBytes    = pThis->fmt_bits / 8;
     1837        Cfg.Props.fSigned   = RT_BOOL(pThis->fmt_signed);
     1838        Cfg.Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(Cfg.Props.cBytes, Cfg.Props.cChannels);
     1839
     1840        if (!DrvAudioHlpPCMPropsAreEqual(&Cfg.Props, &pThis->Out.Cfg.Props))
     1841        {
     1842            Cfg.enmDir          = PDMAUDIODIR_OUT;
     1843            Cfg.DestSource.Dest = PDMAUDIOPLAYBACKDEST_FRONT;
     1844            Cfg.enmLayout       = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
     1845
     1846            strcpy(Cfg.szName, "Output");
     1847
     1848            sb16CloseOut(pThis);
     1849
     1850            rc = sb16OpenOut(pDevIns, pThis, &Cfg);
     1851            AssertRC(rc);
     1852        }
     1853    }
     1854    else
     1855        sb16CloseOut(pThis);
     1856
     1857    LogFlowFuncLeaveRC(rc);
     1858    return rc;
     1859}
     1860
     1861static int sb16OpenOut(PPDMDEVINS pDevIns, PSB16STATE pThis, PPDMAUDIOSTREAMCFG pCfg)
     1862{
     1863    LogFlowFuncEnter();
     1864    AssertPtr(pThis);
     1865    AssertPtr(pCfg);
     1866
     1867    if (!DrvAudioHlpStreamCfgIsValid(pCfg))
     1868        return VERR_INVALID_PARAMETER;
     1869
     1870    int rc = DrvAudioHlpStreamCfgCopy(&pThis->Out.Cfg, pCfg);
     1871    if (RT_SUCCESS(rc))
     1872    {
     1873        /* Set scheduling hint (if available). */
     1874        if (pThis->cTicksTimerIOInterval)
     1875            pThis->Out.Cfg.Device.uSchedulingHintMs = 1000 /* ms */
     1876                                                    / (  PDMDevHlpTimerGetFreq(pDevIns, pThis->hTimerIO)
     1877                                                       / RT_MIN(pThis->cTicksTimerIOInterval, 1));
     1878
     1879        PSB16DRIVER pDrv;
     1880        RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
     1881        {
     1882            int rc2 = sb16CreateDrvStream(&pThis->Out.Cfg, pDrv);
     1883            if (RT_FAILURE(rc2))
     1884                LogFunc(("Attaching stream failed with %Rrc\n", rc2));
     1885
     1886            /* Do not pass failure to rc here, as there might be drivers which aren't
     1887             * configured / ready yet. */
     1888        }
     1889
     1890        sb16UpdateVolume(pThis);
     1891    }
     1892
     1893    LogFlowFuncLeaveRC(rc);
     1894    return rc;
     1895}
     1896
     1897static void sb16CloseOut(PSB16STATE pThis)
     1898{
     1899    LogFlowFuncEnter();
     1900    AssertPtr(pThis);
     1901
     1902    PSB16DRIVER pDrv;
     1903    RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
     1904    {
     1905        sb16DestroyDrvStream(pThis, pDrv);
     1906    }
     1907
     1908    LogFlowFuncLeave();
     1909}
     1910
     1911
     1912/* -=-=-=-=-=- Saved state -=-=-=-=-=- */
    17431913
    17441914/**
     
    19492119}
    19502120
    1951 /**
    1952  * Creates a PDM audio stream for a specific driver.
    1953  *
    1954  * @returns IPRT status code.
    1955  * @param   pCfg                Stream configuration to use.
    1956  * @param   pDrv                Driver stream to create PDM stream for.
    1957  */
    1958 static int sb16CreateDrvStream(PPDMAUDIOSTREAMCFG pCfg, PSB16DRIVER pDrv)
    1959 {
    1960     AssertReturn(pCfg->enmDir == PDMAUDIODIR_OUT, VERR_INVALID_PARAMETER);
    1961     Assert(DrvAudioHlpStreamCfgIsValid(pCfg));
    1962 
    1963     PPDMAUDIOSTREAMCFG pCfgHost = DrvAudioHlpStreamCfgDup(pCfg);
    1964     if (!pCfgHost)
    1965         return VERR_NO_MEMORY;
    1966 
    1967     LogFunc(("[LUN#%RU8] %s\n", pDrv->uLUN, pCfgHost->szName));
    1968 
    1969     AssertMsg(pDrv->Out.pStream == NULL, ("[LUN#%RU8] Driver stream already present when it must not\n", pDrv->uLUN));
    1970 
    1971     /* Disable pre-buffering for SB16; not needed for that bit of data. */
    1972     pCfgHost->Backend.cfPreBuf = 0;
    1973 
    1974     int rc = pDrv->pConnector->pfnStreamCreate(pDrv->pConnector, pCfgHost, pCfg /* pCfgGuest */, &pDrv->Out.pStream);
    1975     if (RT_SUCCESS(rc))
    1976     {
    1977         pDrv->pConnector->pfnStreamRetain(pDrv->pConnector, pDrv->Out.pStream);
    1978         LogFlowFunc(("LUN#%RU8: Created output \"%s\", rc=%Rrc\n", pDrv->uLUN, pCfg->szName, rc));
    1979     }
    1980 
    1981     DrvAudioHlpStreamCfgFree(pCfgHost);
    1982 
    1983     return rc;
    1984 }
    1985 
    1986 /**
    1987  * Destroys a PDM audio stream of a specific driver.
    1988  *
    1989  * @param   pThis               SB16 state.
    1990  * @param   pDrv                Driver stream to destroy PDM stream for.
    1991  */
    1992 static void sb16DestroyDrvStream(PSB16STATE pThis, PSB16DRIVER pDrv)
    1993 {
    1994     AssertPtr(pThis);
    1995     AssertPtr(pDrv);
    1996 
    1997     if (pDrv->Out.pStream)
    1998     {
    1999         pDrv->pConnector->pfnStreamRelease(pDrv->pConnector, pDrv->Out.pStream);
    2000 
    2001         int rc2 = pDrv->pConnector->pfnStreamControl(pDrv->pConnector, pDrv->Out.pStream, PDMAUDIOSTREAMCMD_DISABLE);
    2002         AssertRC(rc2);
    2003 
    2004         rc2 = pDrv->pConnector->pfnStreamDestroy(pDrv->pConnector, pDrv->Out.pStream);
    2005         AssertRC(rc2);
    2006 
    2007         pDrv->Out.pStream = NULL;
    2008     }
    2009 }
    2010 
    2011 /**
    2012  * Checks if the output stream needs to be (re-)created and does so if needed.
    2013  *
    2014  * @return  VBox status code.
    2015  * @param   pDevIns         The device instance.
    2016  * @param   pThis           SB16 state.
    2017  */
    2018 static int sb16CheckAndReOpenOut(PPDMDEVINS pDevIns, PSB16STATE pThis)
    2019 {
    2020     AssertPtr(pThis);
    2021 
    2022     int rc = VINF_SUCCESS;
    2023 
    2024     if (pThis->freq > 0)
    2025     {
    2026         /* At the moment we only have one stream, the output stream. */
    2027         PDMAUDIOSTREAMCFG Cfg;
    2028         RT_ZERO(Cfg);
    2029 
    2030         Cfg.Props.uHz       = pThis->freq;
    2031         Cfg.Props.cChannels = 1 << pThis->fmt_stereo;
    2032         Cfg.Props.cBytes    = pThis->fmt_bits / 8;
    2033         Cfg.Props.fSigned   = RT_BOOL(pThis->fmt_signed);
    2034         Cfg.Props.cShift    = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(Cfg.Props.cBytes, Cfg.Props.cChannels);
    2035 
    2036         if (!DrvAudioHlpPCMPropsAreEqual(&Cfg.Props, &pThis->Out.Cfg.Props))
    2037         {
    2038             Cfg.enmDir          = PDMAUDIODIR_OUT;
    2039             Cfg.DestSource.Dest = PDMAUDIOPLAYBACKDEST_FRONT;
    2040             Cfg.enmLayout       = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
    2041 
    2042             strcpy(Cfg.szName, "Output");
    2043 
    2044             sb16CloseOut(pThis);
    2045 
    2046             rc = sb16OpenOut(pDevIns, pThis, &Cfg);
    2047             AssertRC(rc);
    2048         }
    2049     }
    2050     else
    2051         sb16CloseOut(pThis);
    2052 
    2053     LogFlowFuncLeaveRC(rc);
    2054     return rc;
    2055 }
    2056 
    2057 static int sb16OpenOut(PPDMDEVINS pDevIns, PSB16STATE pThis, PPDMAUDIOSTREAMCFG pCfg)
    2058 {
    2059     LogFlowFuncEnter();
    2060     AssertPtr(pThis);
    2061     AssertPtr(pCfg);
    2062 
    2063     if (!DrvAudioHlpStreamCfgIsValid(pCfg))
    2064         return VERR_INVALID_PARAMETER;
    2065 
    2066     int rc = DrvAudioHlpStreamCfgCopy(&pThis->Out.Cfg, pCfg);
    2067     if (RT_SUCCESS(rc))
    2068     {
    2069         /* Set scheduling hint (if available). */
    2070         if (pThis->cTicksTimerIOInterval)
    2071             pThis->Out.Cfg.Device.uSchedulingHintMs = 1000 /* ms */
    2072                                                     / (  PDMDevHlpTimerGetFreq(pDevIns, pThis->hTimerIO)
    2073                                                        / RT_MIN(pThis->cTicksTimerIOInterval, 1));
    2074 
    2075         PSB16DRIVER pDrv;
    2076         RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
    2077         {
    2078             int rc2 = sb16CreateDrvStream(&pThis->Out.Cfg, pDrv);
    2079             if (RT_FAILURE(rc2))
    2080                 LogFunc(("Attaching stream failed with %Rrc\n", rc2));
    2081 
    2082             /* Do not pass failure to rc here, as there might be drivers which aren't
    2083              * configured / ready yet. */
    2084         }
    2085 
    2086         sb16UpdateVolume(pThis);
    2087     }
    2088 
    2089     LogFlowFuncLeaveRC(rc);
    2090     return rc;
    2091 }
    2092 
    2093 static void sb16CloseOut(PSB16STATE pThis)
    2094 {
    2095     LogFlowFuncEnter();
    2096     AssertPtr(pThis);
    2097 
    2098     PSB16DRIVER pDrv;
    2099     RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node)
    2100     {
    2101         sb16DestroyDrvStream(pThis, pDrv);
    2102     }
    2103 
    2104     LogFlowFuncLeave();
    2105 }
    2106 
     2121
     2122/* -=-=-=-=-=- IBase -=-=-=-=-=- */
    21072123
    21082124/**
     
    21182134}
    21192135
     2136
     2137/* -=-=-=-=-=- Device -=-=-=-=-=- */
    21202138
    21212139/**
     
    24222440    AssertRCReturn(rc, rc);
    24232441    pThis->cTicksTimerIOInterval = PDMDevHlpTimerGetFreq(pDevIns, pThis->hTimerIO) / uTimerHz;
    2424     pThis->tsTimerIO            = PDMDevHlpTimerGet(pDevIns, pThis->hTimerIO);
     2442    pThis->tsTimerIO             = PDMDevHlpTimerGet(pDevIns, pThis->hTimerIO);
    24252443    LogFunc(("Timer ticks=%RU64 (%RU16 Hz)\n", pThis->cTicksTimerIOInterval, uTimerHz));
    24262444
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