VirtualBox

Changeset 74067 in vbox for trunk


Ignore:
Timestamp:
Sep 4, 2018 1:22:49 PM (6 years ago)
Author:
vboxsync
Message:

Audio/HDA: Implemented hdaR3MixerAddDrv() / hdaR3MixerRemoveDrv() and added the ability to (re-)set the recording source automatically when a driver get detached at runtime.

File:
1 edited

Legend:

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

    r74004 r74067  
    211211typedef struct HDADRIVERSTREAM
    212212{
    213     union
    214     {
    215         /** Desired playback destination (for an output stream). */
    216         PDMAUDIOPLAYBACKDEST           Dest;
    217         /** Desired recording source (for an input stream). */
    218         PDMAUDIORECSOURCE              Source;
    219     } DestSource;
    220     uint8_t                            Padding1[4];
    221213    /** Associated mixer handle. */
    222214    R3PTRTYPE(PAUDMIXSTREAM)           pMixStrm;
     
    362354static int                        hdaR3AddStream(PHDASTATE pThis, PPDMAUDIOSTREAMCFG pCfg);
    363355static int                        hdaR3RemoveStream(PHDASTATE pThis, PPDMAUDIOSTREAMCFG pCfg);
    364 static int                        hdaR3UpdateStream(PHDASTATE pThis, PPDMAUDIOSTREAMCFG pCfg);
    365356# ifdef HDA_USE_DMA_ACCESS_HANDLER
    366357static DECLCALLBACK(VBOXSTRICTRC) hdaR3DMAAccessHandler(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, void *pvPhys,
     
    369360# endif
    370361#endif /* IN_RING3 */
     362/** @} */
     363
     364/** @name HDA mixer functions.
     365 * @{
     366 */
     367#ifdef IN_RING3
     368static int hdaR3MixerAddDrvStream(PHDASTATE pThis, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PHDADRIVER pDrv);
     369#endif
    371370/** @} */
    372371
     
    20202019    return rc;
    20212020}
    2022 
    2023 /**
    2024  * Updates an audio device stream with the given configuration.
    2025  *
    2026  * @returns IPRT status code.
    2027  * @param   pThis               HDA state.
    2028  * @param   pCfg                Stream configuration to apply.
    2029  */
    2030 static int hdaR3UpdateStream(PHDASTATE pThis, PPDMAUDIOSTREAMCFG pCfg)
    2031 {
    2032     /* Remove the old stream from the device setup. */
    2033     hdaR3RemoveStream(pThis, pCfg);
    2034 
    2035     /* Add the stream to the device setup. */
    2036     return hdaR3AddStream(pThis, pCfg);
    2037 }
    20382021#endif /* IN_RING3 */
    20392022
     
    23562339
    23572340/**
     2341 * Adds a specific HDA driver to the driver chain.
     2342 *
     2343 * @return IPRT status code.
     2344 * @param  pThis                HDA state.
     2345 * @param  pDrv                 HDA driver to add.
     2346 */
     2347static int hdaR3MixerAddDrv(PHDASTATE pThis, PHDADRIVER pDrv)
     2348{
     2349    int rc = VINF_SUCCESS;
     2350
     2351    PHDASTREAM pStream = hdaR3GetStreamFromSink(pThis, &pThis->SinkLineIn);
     2352    if (   pStream
     2353        && DrvAudioHlpStreamCfgIsValid(&pStream->State.Cfg))
     2354    {
     2355        int rc2 = hdaR3MixerAddDrvStream(pThis, pThis->SinkLineIn.pMixSink, &pStream->State.Cfg, pDrv);
     2356        if (RT_SUCCESS(rc))
     2357            rc = rc2;
     2358    }
     2359
     2360# ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
     2361    pStream = hdaR3GetStreamFromSink(pThis, &pThis->SinkMicIn);
     2362    if (   pStream
     2363        && DrvAudioHlpStreamCfgIsValid(&pStream->State.Cfg))
     2364    {
     2365        int rc2 = hdaR3MixerAddDrvStream(pThis, pThis->SinkMicIn.pMixSink, &pStream->State.Cfg, pDrv);
     2366        if (RT_SUCCESS(rc))
     2367            rc = rc2;
     2368    }
     2369# endif
     2370
     2371    pStream = hdaR3GetStreamFromSink(pThis, &pThis->SinkFront);
     2372    if (   pStream
     2373        && DrvAudioHlpStreamCfgIsValid(&pStream->State.Cfg))
     2374    {
     2375        int rc2 = hdaR3MixerAddDrvStream(pThis, pThis->SinkFront.pMixSink, &pStream->State.Cfg, pDrv);
     2376        if (RT_SUCCESS(rc))
     2377            rc = rc2;
     2378    }
     2379
     2380# ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
     2381    pStream = hdaR3GetStreamFromSink(pThis, &pThis->SinkCenterLFE);
     2382    if (   pStream
     2383        && DrvAudioHlpStreamCfgIsValid(&pStream->State.Cfg))
     2384    {
     2385        int rc2 = hdaR3MixerAddDrvStream(pThis, pThis->SinkCenterLFE.pMixSink, &pStream->State.Cfg, pDrv);
     2386        if (RT_SUCCESS(rc))
     2387            rc = rc2;
     2388    }
     2389
     2390    pStream = hdaR3GetStreamFromSink(pThis, &pThis->SinkRear);
     2391    if (   pStream
     2392        && DrvAudioHlpStreamCfgIsValid(&pStream->State.Cfg))
     2393    {
     2394        int rc2 = hdaR3MixerAddDrvStream(pThis, pThis->SinkRear.pMixSink, &pStream->State.Cfg, pDrv);
     2395        if (RT_SUCCESS(rc))
     2396            rc = rc2;
     2397    }
     2398# endif
     2399
     2400    return rc;
     2401}
     2402
     2403/**
     2404 * Removes a specific HDA driver from the driver chain and destroys its
     2405 * associated streams.
     2406 *
     2407 * @param pThis                 HDA state.
     2408 * @param pDrv                  HDA driver to remove.
     2409 */
     2410static void hdaR3MixerRemoveDrv(PHDASTATE pThis, PHDADRIVER pDrv)
     2411{
     2412    AssertPtrReturnVoid(pThis);
     2413    AssertPtrReturnVoid(pDrv);
     2414
     2415    if (pDrv->LineIn.pMixStrm)
     2416    {
     2417        if (AudioMixerSinkGetRecordingSource(pThis->SinkLineIn.pMixSink) == pDrv->LineIn.pMixStrm)
     2418            AudioMixerSinkSetRecordingSource(pThis->SinkLineIn.pMixSink, NULL);
     2419
     2420        AudioMixerSinkRemoveStream(pThis->SinkLineIn.pMixSink, pDrv->LineIn.pMixStrm);
     2421        AudioMixerStreamDestroy(pDrv->LineIn.pMixStrm);
     2422        pDrv->LineIn.pMixStrm = NULL;
     2423    }
     2424
     2425# ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
     2426    if (pDrv->MicIn.pMixStrm)
     2427    {
     2428        if (AudioMixerSinkGetRecordingSource(pThis->SinkMicIn.pMixSink) == pDrv->MicIn.pMixStrm)
     2429            AudioMixerSinkSetRecordingSource(&pThis->SinkMicIn.pMixSink, NULL);
     2430
     2431        AudioMixerSinkRemoveStream(pThis->SinkMicIn.pMixSink, pDrv->MicIn.pMixStrm);
     2432        AudioMixerStreamDestroy(pDrv->MicIn.pMixStrm);
     2433        pDrv->MicIn.pMixStrm = NULL;
     2434    }
     2435# endif
     2436
     2437    if (pDrv->Front.pMixStrm)
     2438    {
     2439        AudioMixerSinkRemoveStream(pThis->SinkFront.pMixSink, pDrv->Front.pMixStrm);
     2440        AudioMixerStreamDestroy(pDrv->Front.pMixStrm);
     2441        pDrv->Front.pMixStrm = NULL;
     2442    }
     2443
     2444# ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
     2445    if (pDrv->CenterLFE.pMixStrm)
     2446    {
     2447        AudioMixerSinkRemoveStream(pThis->SinkCenterLFE.pMixSink, pDrv->CenterLFE.pMixStrm);
     2448        AudioMixerStreamDestroy(pDrv->CenterLFE.pMixStrm);
     2449        pDrv->CenterLFE.pMixStrm = NULL;
     2450    }
     2451
     2452    if (pDrv->Rear.pMixStrm)
     2453    {
     2454        AudioMixerSinkRemoveStream(pThis->SinkRear.pMixSink, pDrv->Rear.pMixStrm);
     2455        AudioMixerStreamDestroy(pDrv->Rear.pMixStrm);
     2456        pDrv->Rear.pMixStrm = NULL;
     2457    }
     2458# endif
     2459
     2460    RTListNodeRemove(&pDrv->Node);
     2461}
     2462
     2463/**
    23582464 * Adds a driver stream to a specific mixer sink.
    23592465 *
     
    24742580    }
    24752581
    2476     RTMemFree(pStreamCfg);
     2582    if (pStreamCfg)
     2583    {
     2584        RTMemFree(pStreamCfg);
     2585        pStreamCfg = NULL;
     2586    }
    24772587
    24782588    LogFlowFuncLeaveRC(rc);
     
    44964606 * @returns VBox status code.
    44974607 * @param   pThis       HDA state.
    4498  * @param   pDrv        Driver to detach device from.
     4608 * @param   pDrv        Driver to detach from device.
    44994609 * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
    45004610 */
     
    45034613    RT_NOREF(fFlags);
    45044614
    4505     AudioMixerSinkRemoveStream(pThis->SinkFront.pMixSink,     pDrv->Front.pMixStrm);
    4506     AudioMixerStreamDestroy(pDrv->Front.pMixStrm);
    4507     pDrv->Front.pMixStrm = NULL;
    4508 
    4509 #ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
    4510     AudioMixerSinkRemoveStream(pThis->SinkCenterLFE.pMixSink, pDrv->CenterLFE.pMixStrm);
    4511     AudioMixerStreamDestroy(pDrv->CenterLFE.pMixStrm);
    4512     pDrv->CenterLFE.pMixStrm = NULL;
    4513 
    4514     AudioMixerSinkRemoveStream(pThis->SinkRear.pMixSink,      pDrv->Rear.pMixStrm);
    4515     AudioMixerStreamDestroy(pDrv->Rear.pMixStrm);
    4516     pDrv->Rear.pMixStrm = NULL;
    4517 #endif
    4518 
    4519     AudioMixerSinkRemoveStream(pThis->SinkLineIn.pMixSink,    pDrv->LineIn.pMixStrm);
    4520     AudioMixerStreamDestroy(pDrv->LineIn.pMixStrm);
    4521     pDrv->LineIn.pMixStrm = NULL;
    4522 
    4523 #ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    4524     AudioMixerSinkRemoveStream(pThis->SinkMicIn.pMixSink,     pDrv->MicIn.pMixStrm);
    4525     AudioMixerStreamDestroy(pDrv->MicIn.pMixStrm);
    4526     pDrv->MicIn.pMixStrm = NULL;
    4527 #endif
    4528 
    4529     RTListNodeRemove(&pDrv->Node);
     4615    /* First, remove the driver from our list and destory it's associated streams.
     4616     * This also will un-set the driver as a recording source (if associated). */
     4617    hdaR3MixerRemoveDrv(pThis, pDrv);
     4618
     4619    /* Next, search backwards for a capable (attached) driver which now will be the
     4620     * new recording source. */
     4621    PHDADRIVER pDrvCur;
     4622    RTListForEachReverse(&pThis->lstDrv, pDrvCur, HDADRIVER, Node)
     4623    {
     4624        if (!pDrvCur->pConnector)
     4625            continue;
     4626
     4627        PDMAUDIOBACKENDCFG Cfg;
     4628        int rc2 = pDrvCur->pConnector->pfnGetConfig(pDrvCur->pConnector, &Cfg);
     4629        if (RT_FAILURE(rc2))
     4630            continue;
     4631
     4632        PHDADRIVERSTREAM pDrvStrm;
     4633# ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
     4634        pDrvStrm = &pDrvCur->MicIn;
     4635        if (   pDrvStrm
     4636            && pDrvStrm->pMixStrm)
     4637        {
     4638            rc2 = AudioMixerSinkSetRecordingSource(pThis->SinkMicIn.pMixSink, pDrvStrm->pMixStrm);
     4639            if (RT_SUCCESS(rc2))
     4640                LogRel2(("HDA: Set new recording source for 'Mic In' to '%s'\n", Cfg.szName));
     4641        }
     4642# endif
     4643        pDrvStrm = &pDrvCur->LineIn;
     4644        if (   pDrvStrm
     4645            && pDrvStrm->pMixStrm)
     4646        {
     4647            rc2 = AudioMixerSinkSetRecordingSource(pThis->SinkLineIn.pMixSink, pDrvStrm->pMixStrm);
     4648            if (RT_SUCCESS(rc2))
     4649                LogRel2(("HDA: Set new recording source for 'Line In' to '%s'\n", Cfg.szName));
     4650        }
     4651    }
    45304652
    45314653    LogFunc(("uLUN=%u, fFlags=0x%x\n", pDrv->uLUN, fFlags));
     
    45474669    int rc2 = hdaR3AttachInternal(pThis, uLUN, fFlags, &pDrv);
    45484670    if (RT_SUCCESS(rc2))
    4549     {
    4550         PHDASTREAM pStream = hdaR3GetStreamFromSink(pThis, &pThis->SinkFront);
    4551         if (DrvAudioHlpStreamCfgIsValid(&pStream->State.Cfg))
    4552         {
    4553             rc2 = hdaR3UpdateStream(pThis, &pStream->State.Cfg);
    4554             AssertRC(rc2);
    4555         }
    4556 #ifdef VBOX_WITH_AUDIO_HDA_51_SURROUND
    4557         pStream = hdaR3GetStreamFromSink(pThis, &pThis->SinkCenterLFE);
    4558         if (DrvAudioHlpStreamCfgIsValid(&pStream->State.Cfg))
    4559         {
    4560             rc2 = hdaR3UpdateStream(pThis, &pStream->State.Cfg);
    4561             AssertRC(rc2);
    4562         }
    4563 
    4564         pStream = hdaR3GetStreamFromSink(pThis, &pThis->SinkRear);
    4565         if (DrvAudioHlpStreamCfgIsValid(&pStream->State.Cfg))
    4566         {
    4567             rc2 = hdaR3UpdateStream(pThis, &pStream->State.Cfg);
    4568             AssertRC(rc2);
    4569         }
    4570 #endif
    4571         pStream = hdaR3GetStreamFromSink(pThis, &pThis->SinkLineIn);
    4572         if (DrvAudioHlpStreamCfgIsValid(&pStream->State.Cfg))
    4573         {
    4574             rc2 = hdaR3UpdateStream(pThis, &pStream->State.Cfg);
    4575             AssertRC(rc2);
    4576         }
    4577 
    4578 #ifdef VBOX_WITH_AUDIO_HDA_MIC_IN
    4579         pStream = hdaR3GetStreamFromSink(pThis, &pThis->SinkMicIn);
    4580         if (DrvAudioHlpStreamCfgIsValid(&pStream->State.Cfg))
    4581         {
    4582             rc2 = hdaR3UpdateStream(pThis, &pStream->State.Cfg);
    4583             AssertRC(rc2);
    4584         }
    4585 #endif
    4586     }
     4671        rc2 = hdaR3MixerAddDrv(pThis, pDrv);
     4672
     4673    if (RT_FAILURE(rc2))
     4674        LogFunc(("Failed with %Rrc\n", rc2));
    45874675
    45884676    DEVHDA_UNLOCK(pThis);
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