- Timestamp:
- Sep 4, 2018 1:22:49 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevHDA.cpp
r74004 r74067 211 211 typedef struct HDADRIVERSTREAM 212 212 { 213 union214 {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];221 213 /** Associated mixer handle. */ 222 214 R3PTRTYPE(PAUDMIXSTREAM) pMixStrm; … … 362 354 static int hdaR3AddStream(PHDASTATE pThis, PPDMAUDIOSTREAMCFG pCfg); 363 355 static int hdaR3RemoveStream(PHDASTATE pThis, PPDMAUDIOSTREAMCFG pCfg); 364 static int hdaR3UpdateStream(PHDASTATE pThis, PPDMAUDIOSTREAMCFG pCfg);365 356 # ifdef HDA_USE_DMA_ACCESS_HANDLER 366 357 static DECLCALLBACK(VBOXSTRICTRC) hdaR3DMAAccessHandler(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, void *pvPhys, … … 369 360 # endif 370 361 #endif /* IN_RING3 */ 362 /** @} */ 363 364 /** @name HDA mixer functions. 365 * @{ 366 */ 367 #ifdef IN_RING3 368 static int hdaR3MixerAddDrvStream(PHDASTATE pThis, PAUDMIXSINK pMixSink, PPDMAUDIOSTREAMCFG pCfg, PHDADRIVER pDrv); 369 #endif 371 370 /** @} */ 372 371 … … 2020 2019 return rc; 2021 2020 } 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 }2038 2021 #endif /* IN_RING3 */ 2039 2022 … … 2356 2339 2357 2340 /** 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 */ 2347 static 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 */ 2410 static 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 /** 2358 2464 * Adds a driver stream to a specific mixer sink. 2359 2465 * … … 2474 2580 } 2475 2581 2476 RTMemFree(pStreamCfg); 2582 if (pStreamCfg) 2583 { 2584 RTMemFree(pStreamCfg); 2585 pStreamCfg = NULL; 2586 } 2477 2587 2478 2588 LogFlowFuncLeaveRC(rc); … … 4496 4606 * @returns VBox status code. 4497 4607 * @param pThis HDA state. 4498 * @param pDrv Driver to detach device from.4608 * @param pDrv Driver to detach from device. 4499 4609 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines. 4500 4610 */ … … 4503 4613 RT_NOREF(fFlags); 4504 4614 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 } 4530 4652 4531 4653 LogFunc(("uLUN=%u, fFlags=0x%x\n", pDrv->uLUN, fFlags)); … … 4547 4669 int rc2 = hdaR3AttachInternal(pThis, uLUN, fFlags, &pDrv); 4548 4670 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)); 4587 4675 4588 4676 DEVHDA_UNLOCK(pThis);
Note:
See TracChangeset
for help on using the changeset viewer.