Changeset 82228 in vbox for trunk/src/VBox/Devices/Audio
- Timestamp:
- Nov 26, 2019 8:58:08 PM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 135043
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevHDA.cpp
r81591 r82228 4657 4657 } 4658 4658 4659 4660 /** 4661 * Re-attaches (replaces) a driver with a new driver. 4662 * 4663 * This is only used by to attach the Null driver when it failed to attach the 4664 * one that was configured. 4659 /** 4660 * Replaces a driver with a the NullAudio drivers. 4665 4661 * 4666 4662 * @returns VBox status code. 4667 * @param pThis Device instance to re-attach driver to. 4668 * @param pDrv Driver instance used for attaching to. 4669 * If NULL is specified, a new driver will be created and appended 4670 * to the driver list. 4671 * @param uLUN The logical unit which is being re-detached. 4672 * @param pszDriver New driver name to attach. 4673 */ 4674 static int hdaR3ReattachInternal(PHDASTATE pThis, PHDADRIVER pDrv, uint8_t uLUN, const char *pszDriver) 4675 { 4676 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 4677 AssertPtrReturn(pszDriver, VERR_INVALID_POINTER); 4678 4679 int rc; 4680 4681 if (pDrv) 4682 { 4683 rc = hdaR3DetachInternal(pThis, pDrv, 0 /* fFlags */); 4684 if (RT_SUCCESS(rc)) 4685 rc = PDMDevHlpDriverDetach(pThis->pDevInsR3, PDMIBASE_2_PDMDRV(pDrv->pDrvBase), 0 /* fFlags */); 4686 4687 if (RT_FAILURE(rc)) 4688 return rc; 4689 4690 pDrv = NULL; 4691 } 4692 4693 PVM pVM = PDMDevHlpGetVM(pThis->pDevInsR3); 4694 PCFGMNODE pRoot = CFGMR3GetRoot(pVM); 4695 PCFGMNODE pDev0 = CFGMR3GetChild(pRoot, "Devices/hda/0/"); 4696 4697 /* Remove LUN branch. */ 4698 CFGMR3RemoveNode(CFGMR3GetChildF(pDev0, "LUN#%u/", uLUN)); 4699 4700 #define RC_CHECK() if (RT_FAILURE(rc)) { AssertReleaseRC(rc); break; } 4701 4702 do 4703 { 4704 PCFGMNODE pLunL0; 4705 rc = CFGMR3InsertNodeF(pDev0, &pLunL0, "LUN#%u/", uLUN); RC_CHECK(); 4706 rc = CFGMR3InsertString(pLunL0, "Driver", "AUDIO"); RC_CHECK(); 4707 rc = CFGMR3InsertNode(pLunL0, "Config/", NULL); RC_CHECK(); 4708 4709 PCFGMNODE pLunL1, pLunL2; 4710 rc = CFGMR3InsertNode (pLunL0, "AttachedDriver/", &pLunL1); RC_CHECK(); 4711 rc = CFGMR3InsertNode (pLunL1, "Config/", &pLunL2); RC_CHECK(); 4712 rc = CFGMR3InsertString(pLunL1, "Driver", pszDriver); RC_CHECK(); 4713 4714 rc = CFGMR3InsertString(pLunL2, "AudioDriver", pszDriver); RC_CHECK(); 4715 4716 } while (0); 4717 4663 * @param pThis Device instance. 4664 * @param iLun The logical unit which is being replaced. 4665 */ 4666 static int hdaR3ReconfigLunWithNullAudio(PHDASTATE pThis, unsigned iLun) 4667 { 4668 int rc = PDMDevHlpDriverReconfigure2(pThis->pDevInsR3, iLun, "AUDIO", "NullAudio"); 4718 4669 if (RT_SUCCESS(rc)) 4719 rc = hdaR3AttachInternal(pThis, uLUN, 0 /* fFlags */, NULL /* ppDrv */); 4720 4721 LogFunc(("pThis=%p, uLUN=%u, pszDriver=%s, rc=%Rrc\n", pThis, uLUN, pszDriver, rc)); 4722 4723 #undef RC_CHECK 4724 4670 rc = hdaR3AttachInternal(pThis, iLun, 0 /* fFlags */, NULL /* ppDrv */); 4671 LogFunc(("pThis=%p, iLun=%u, rc=%Rrc\n", pThis, iLun, rc)); 4725 4672 return rc; 4726 4673 } … … 5001 4948 #endif 5002 4949 5003 uint8_t uLUN; 5004 for (uLUN = 0; uLUN < UINT8_MAX; ++uLUN) 5005 { 5006 LogFunc(("Trying to attach driver for LUN #%RU32 ...\n", uLUN)); 5007 rc = hdaR3AttachInternal(pThis, uLUN, 0 /* fFlags */, NULL /* ppDrv */); 5008 if (RT_FAILURE(rc)) 5009 { 5010 if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 5011 rc = VINF_SUCCESS; 5012 else if (rc == VERR_AUDIO_BACKEND_INIT_FAILED) 5013 { 5014 hdaR3ReattachInternal(pThis, NULL /* pDrv */, uLUN, "NullAudio"); 5015 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", 5016 N_("Host audio backend initialization has failed. " 5017 "Selecting the NULL audio backend with the consequence that no sound is audible")); 5018 /* Attaching to the NULL audio backend will never fail. */ 5019 rc = VINF_SUCCESS; 5020 } 5021 else 5022 AssertRCReturn(rc, rc); 4950 /* 4951 * Attach drivers. We ASSUME they are configured consecutively without any 4952 * gaps, so we stop when we hit the first LUN w/o a driver configured. 4953 */ 4954 for (unsigned iLun = 0; ; iLun++) 4955 { 4956 AssertBreak(iLun < UINT8_MAX); 4957 LogFunc(("Trying to attach driver for LUN#%u ...\n", iLun)); 4958 rc = hdaR3AttachInternal(pThis, iLun, 0 /* fFlags */, NULL /* ppDrv */); 4959 if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 4960 { 4961 LogFunc(("cLUNs=%u\n", iLun)); 5023 4962 break; 5024 4963 } 5025 } 5026 5027 LogFunc(("cLUNs=%RU8, rc=%Rrc\n", uLUN, rc)); 5028 4964 if (rc == VERR_AUDIO_BACKEND_INIT_FAILED) 4965 { 4966 hdaR3ReconfigLunWithNullAudio(pThis, iLun); /* Pretend attaching to the NULL audio backend will never fail. */ 4967 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", 4968 N_("Host audio backend initialization has failed. Selecting the NULL audio backend with the consequence that no sound is audible")); 4969 } 4970 else 4971 AssertLogRelMsgReturn(RT_SUCCESS(rc), ("LUN#%u: rc=%Rrc\n", iLun, rc), rc); 4972 } 4973 4974 /* 4975 * Create the mixer. 4976 */ 5029 4977 rc = AudioMixerCreate("HDA Mixer", 0 /* uFlags */, &pThis->pMixer); 5030 4978 AssertRCReturn(rc, rc); … … 5156 5104 { 5157 5105 LogRel(("HDA: Falling back to NULL backend (no sound audible)\n")); 5158 5159 5106 hdaR3Reset(pDevIns); 5160 hdaR3ReattachInternal(pThis, pDrv, pDrv->uLUN, "NullAudio"); 5161 5107 hdaR3ReconfigLunWithNullAudio(pThis, pDrv->uLUN); 5162 5108 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", 5163 5109 N_("No audio devices could be opened. " -
trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
r81591 r82228 451 451 /** Driver flags. */ 452 452 PDMAUDIODRVFLAGS fFlags; 453 uint32_t PaddingFlags;454 453 /** LUN # to which this driver has been assigned. */ 455 454 uint8_t uLUN; 456 455 /** Whether this driver is in an attached state or not. */ 457 456 bool fAttached; 458 uint8_t Padding[4];457 uint8_t abPadding[2]; 459 458 /** Pointer to the description string passed to PDMDevHlpDriverAttach(). */ 460 459 R3PTRTYPE(char *) pszDesc; … … 3901 3900 * @returns VBox status code. 3902 3901 * @param pThis AC'97 state. 3903 * @param uLUNThe logical unit which is being attached.3902 * @param iLun The logical unit which is being attached. 3904 3903 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines. 3905 3904 * @param ppDrv Attached driver instance on success. Optional. 3906 3905 */ 3907 static int ichac97R3AttachInternal(PAC97STATE pThis, unsigned uLUN, uint32_t fFlags, PAC97DRIVER *ppDrv)3906 static int ichac97R3AttachInternal(PAC97STATE pThis, unsigned iLun, uint32_t fFlags, PAC97DRIVER *ppDrv) 3908 3907 { 3909 3908 RT_NOREF(fFlags); … … 3913 3912 */ 3914 3913 char *pszDesc; 3915 if (RTStrAPrintf(&pszDesc, "Audio driver port (AC'97) for LUN #%u", uLUN) <= 0)3914 if (RTStrAPrintf(&pszDesc, "Audio driver port (AC'97) for LUN #%u", iLun) <= 0) 3916 3915 AssertLogRelFailedReturn(VERR_NO_MEMORY); 3917 3916 3918 3917 PPDMIBASE pDrvBase; 3919 int rc = PDMDevHlpDriverAttach(pThis->pDevInsR3, uLUN, 3920 &pThis->IBase, &pDrvBase, pszDesc); 3918 int rc = PDMDevHlpDriverAttach(pThis->pDevInsR3, iLun, &pThis->IBase, &pDrvBase, pszDesc); 3921 3919 if (RT_SUCCESS(rc)) 3922 3920 { … … 3926 3924 pDrv->pDrvBase = pDrvBase; 3927 3925 pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pDrvBase, PDMIAUDIOCONNECTOR); 3928 AssertMsg(pDrv->pConnector != NULL, ("Configuration error: LUN #%u has no host audio interface, rc=%Rrc\n", uLUN, rc));3926 AssertMsg(pDrv->pConnector != NULL, ("Configuration error: LUN #%u has no host audio interface, rc=%Rrc\n", iLun, rc)); 3929 3927 pDrv->pAC97State = pThis; 3930 pDrv->uLUN = uLUN;3928 pDrv->uLUN = iLun; 3931 3929 pDrv->pszDesc = pszDesc; 3932 3930 … … 3935 3933 * host backend. This might change in the future. 3936 3934 */ 3937 if ( pDrv->uLUN== 0)3935 if (iLun == 0) 3938 3936 pDrv->fFlags |= PDMAUDIODRVFLAGS_PRIMARY; 3939 3937 3940 LogFunc(("LUN#% RU8: pCon=%p, drvFlags=0x%x\n", uLUN, pDrv->pConnector, pDrv->fFlags));3938 LogFunc(("LUN#%u: pCon=%p, drvFlags=0x%x\n", iLun, pDrv->pConnector, pDrv->fFlags)); 3941 3939 3942 3940 /* Attach to driver list if not attached yet. */ … … 3954 3952 } 3955 3953 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 3956 LogFunc(("No attached driver for LUN #%u\n", uLUN));3954 LogFunc(("No attached driver for LUN #%u\n", iLun)); 3957 3955 3958 3956 if (RT_FAILURE(rc)) … … 3963 3961 } 3964 3962 3965 LogFunc((" uLUN=%u, fFlags=0x%x, rc=%Rrc\n", uLUN, fFlags, rc));3963 LogFunc(("iLun=%u, fFlags=0x%x, rc=%Rrc\n", iLun, fFlags, rc)); 3966 3964 return rc; 3967 3965 } … … 4026 4024 4027 4025 /** 4028 * @interface_method_impl{PDMDEVREG ,pfnAttach}4029 */ 4030 static DECLCALLBACK(int) ichac97R3Attach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)4026 * @interface_method_impl{PDMDEVREGR3,pfnAttach} 4027 */ 4028 static DECLCALLBACK(int) ichac97R3Attach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags) 4031 4029 { 4032 4030 PAC97STATE pThis = PDMDEVINS_2_DATA(pDevIns, PAC97STATE); 4033 4031 4034 LogFunc((" uLUN=%u, fFlags=0x%x\n", uLUN, fFlags));4032 LogFunc(("iLUN=%u, fFlags=0x%x\n", iLUN, fFlags)); 4035 4033 4036 4034 DEVAC97_LOCK(pThis); 4037 4035 4038 4036 PAC97DRIVER pDrv; 4039 int rc2 = ichac97R3AttachInternal(pThis, uLUN, fFlags, &pDrv);4037 int rc2 = ichac97R3AttachInternal(pThis, iLUN, fFlags, &pDrv); 4040 4038 if (RT_SUCCESS(rc2)) 4041 4039 rc2 = ichac97R3MixerAddDrv(pThis, pDrv); … … 4052 4050 * @interface_method_impl{PDMDEVREG,pfnDetach} 4053 4051 */ 4054 static DECLCALLBACK(void) ichac97R3Detach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)4052 static DECLCALLBACK(void) ichac97R3Detach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags) 4055 4053 { 4056 4054 PAC97STATE pThis = PDMDEVINS_2_DATA(pDevIns, PAC97STATE); 4057 4055 4058 LogFunc((" uLUN=%u, fFlags=0x%x\n", uLUN, fFlags));4056 LogFunc(("iLUN=%u, fFlags=0x%x\n", iLUN, fFlags)); 4059 4057 4060 4058 DEVAC97_LOCK(pThis); … … 4063 4061 RTListForEachSafe(&pThis->lstDrv, pDrv, pDrvNext, AC97DRIVER, Node) 4064 4062 { 4065 if (pDrv->uLUN == uLUN)4063 if (pDrv->uLUN == iLUN) 4066 4064 { 4067 4065 int rc2 = ichac97R3DetachInternal(pThis, pDrv, fFlags); … … 4081 4079 4082 4080 /** 4083 * Re -attaches (replaces) a driver with a new driver.4081 * Replaces a driver with a the NullAudio drivers. 4084 4082 * 4085 4083 * @returns VBox status code. 4086 4084 * @param pThis Device instance. 4087 * @param pDrv Driver instance used for attaching to. 4088 * If NULL is specified, a new driver will be created and appended 4089 * to the driver list. 4090 * @param uLUN The logical unit which is being re-detached. 4091 * @param pszDriver New driver name to attach. 4092 */ 4093 static int ichac97R3ReattachInternal(PAC97STATE pThis, PAC97DRIVER pDrv, uint8_t uLUN, const char *pszDriver) 4094 { 4095 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 4096 AssertPtrReturn(pszDriver, VERR_INVALID_POINTER); 4097 4098 int rc; 4099 4100 if (pDrv) 4101 { 4102 rc = ichac97R3DetachInternal(pThis, pDrv, 0 /* fFlags */); 4103 if (RT_SUCCESS(rc)) 4104 rc = PDMDevHlpDriverDetach(pThis->pDevInsR3, PDMIBASE_2_PDMDRV(pDrv->pDrvBase), 0 /* fFlags */); 4105 4106 if (RT_FAILURE(rc)) 4107 return rc; 4108 4109 RTStrFree(pDrv->pszDesc); 4110 RTMemFree(pDrv); 4111 pDrv = NULL; 4112 } 4113 4114 PVM pVM = PDMDevHlpGetVM(pThis->pDevInsR3); 4115 PCFGMNODE pRoot = CFGMR3GetRoot(pVM); 4116 PCFGMNODE pDev0 = CFGMR3GetChild(pRoot, "Devices/ichac97/0/"); 4117 4118 /* Remove LUN branch. */ 4119 CFGMR3RemoveNode(CFGMR3GetChildF(pDev0, "LUN#%u/", uLUN)); 4120 4121 # define RC_CHECK() if (RT_FAILURE(rc)) { AssertReleaseRC(rc); break; } 4122 4123 do 4124 { 4125 PCFGMNODE pLunL0; 4126 rc = CFGMR3InsertNodeF(pDev0, &pLunL0, "LUN#%u/", uLUN); RC_CHECK(); 4127 rc = CFGMR3InsertString(pLunL0, "Driver", "AUDIO"); RC_CHECK(); 4128 rc = CFGMR3InsertNode(pLunL0, "Config/", NULL); RC_CHECK(); 4129 4130 PCFGMNODE pLunL1, pLunL2; 4131 rc = CFGMR3InsertNode (pLunL0, "AttachedDriver/", &pLunL1); RC_CHECK(); 4132 rc = CFGMR3InsertNode (pLunL1, "Config/", &pLunL2); RC_CHECK(); 4133 rc = CFGMR3InsertString(pLunL1, "Driver", pszDriver); RC_CHECK(); 4134 4135 rc = CFGMR3InsertString(pLunL2, "AudioDriver", pszDriver); RC_CHECK(); 4136 4137 } while (0); 4138 4085 * @param iLun The logical unit which is being replaced. 4086 */ 4087 static int ichac97R3ReconfigLunWithNullAudio(PAC97STATE pThis, unsigned iLun) 4088 { 4089 int rc = PDMDevHlpDriverReconfigure2(pThis->pDevInsR3, iLun, "AUDIO", "NullAudio"); 4139 4090 if (RT_SUCCESS(rc)) 4140 rc = ichac97R3AttachInternal(pThis, uLUN, 0 /* fFlags */, NULL /* ppDrv */); 4141 4142 LogFunc(("pThis=%p, uLUN=%u, pszDriver=%s, rc=%Rrc\n", pThis, uLUN, pszDriver, rc)); 4143 4144 # undef RC_CHECK 4145 4091 rc = ichac97R3AttachInternal(pThis, iLun, 0 /* fFlags */, NULL /* ppDrv */); 4092 LogFunc(("pThis=%p, iLun=%u, rc=%Rrc\n", pThis, iLun, rc)); 4146 4093 return rc; 4147 4094 } … … 4342 4289 4343 4290 /* 4344 * Attach driver. 4291 * Attach drivers. We ASSUME they are configured consecutively without any 4292 * gaps, so we stop when we hit the first LUN w/o a driver configured. 4345 4293 */ 4346 uint8_t uLUN; 4347 for (uLUN = 0; uLUN < UINT8_MAX; ++uLUN) 4348 { 4349 LogFunc(("Trying to attach driver for LUN #%RU8 ...\n", uLUN)); 4350 rc = ichac97R3AttachInternal(pThis, uLUN, 0 /* fFlags */, NULL /* ppDrv */); 4351 if (RT_FAILURE(rc)) 4352 { 4353 if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 4354 rc = VINF_SUCCESS; 4355 else if (rc == VERR_AUDIO_BACKEND_INIT_FAILED) 4294 for (unsigned iLun = 0; ; iLun++) 4295 { 4296 AssertBreak(iLun < UINT8_MAX); 4297 LogFunc(("Trying to attach driver for LUN#%u ...\n", iLun)); 4298 rc = ichac97R3AttachInternal(pThis, iLun, 0 /* fFlags */, NULL /* ppDrv */); 4299 if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 4300 { 4301 LogFunc(("cLUNs=%u\n", iLun)); 4302 break; 4303 } 4304 if (rc == VERR_AUDIO_BACKEND_INIT_FAILED) 4305 { 4306 ichac97R3ReconfigLunWithNullAudio(pThis, iLun); /* Pretend attaching to the NULL audio backend will never fail. */ 4307 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", 4308 N_("Host audio backend initialization has failed. " 4309 "Selecting the NULL audio backend with the consequence that no sound is audible")); 4310 } 4311 else 4312 AssertLogRelMsgReturn(RT_SUCCESS(rc), ("LUN#%u: rc=%Rrc\n", iLun, rc), rc); 4313 } 4314 4315 rc = AudioMixerCreate("AC'97 Mixer", 0 /* uFlags */, &pThis->pMixer); 4316 AssertRCReturn(rc, rc); 4317 rc = AudioMixerCreateSink(pThis->pMixer, "[Recording] Line In", AUDMIXSINKDIR_INPUT, &pThis->pSinkLineIn); 4318 AssertRCReturn(rc, rc); 4319 rc = AudioMixerCreateSink(pThis->pMixer, "[Recording] Microphone In", AUDMIXSINKDIR_INPUT, &pThis->pSinkMicIn); 4320 AssertRCReturn(rc, rc); 4321 rc = AudioMixerCreateSink(pThis->pMixer, "[Playback] PCM Output", AUDMIXSINKDIR_OUTPUT, &pThis->pSinkOut); 4322 AssertRCReturn(rc, rc); 4323 4324 /* 4325 * Create all hardware streams. 4326 */ 4327 for (unsigned i = 0; i < AC97_MAX_STREAMS; i++) 4328 { 4329 int rc2 = ichac97R3StreamCreate(pThis, &pThis->aStreams[i], i /* SD# */); 4330 AssertRC(rc2); 4331 if (RT_SUCCESS(rc)) 4332 rc = rc2; 4333 } 4334 4335 # ifdef VBOX_WITH_AUDIO_AC97_ONETIME_INIT 4336 PAC97DRIVER pDrv; 4337 RTListForEach(&pThis->lstDrv, pDrv, AC97DRIVER, Node) 4338 { 4339 /* 4340 * Only primary drivers are critical for the VM to run. Everything else 4341 * might not worth showing an own error message box in the GUI. 4342 */ 4343 if (!(pDrv->fFlags & PDMAUDIODRVFLAGS_PRIMARY)) 4344 continue; 4345 4346 PPDMIAUDIOCONNECTOR pCon = pDrv->pConnector; 4347 AssertPtr(pCon); 4348 4349 bool fValidLineIn = AudioMixerStreamIsValid(pDrv->LineIn.pMixStrm); 4350 bool fValidMicIn = AudioMixerStreamIsValid(pDrv->MicIn.pMixStrm); 4351 bool fValidOut = AudioMixerStreamIsValid(pDrv->Out.pMixStrm); 4352 4353 if ( !fValidLineIn 4354 && !fValidMicIn 4355 && !fValidOut) 4356 { 4357 LogRel(("AC97: Falling back to NULL backend (no sound audible)\n")); 4358 ichac97R3Reset(pDevIns); 4359 ichac97R3ReconfigLunWithNullAudio(pThis, iLun); 4360 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", 4361 N_("No audio devices could be opened. " 4362 "Selecting the NULL audio backend with the consequence that no sound is audible")); 4363 } 4364 else 4365 { 4366 bool fWarn = false; 4367 4368 PDMAUDIOBACKENDCFG backendCfg; 4369 int rc2 = pCon->pfnGetConfig(pCon, &backendCfg); 4370 if (RT_SUCCESS(rc2)) 4356 4371 { 4357 ichac97R3ReattachInternal(pThis, NULL /* pDrv */, uLUN, "NullAudio"); 4358 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", 4359 N_("Host audio backend initialization has failed. Selecting the NULL audio backend " 4360 "with the consequence that no sound is audible")); 4361 /* Attaching to the NULL audio backend will never fail. */ 4362 rc = VINF_SUCCESS; 4363 } 4364 break; 4365 } 4366 } 4367 4368 LogFunc(("cLUNs=%RU8, rc=%Rrc\n", uLUN, rc)); 4369 4370 if (RT_SUCCESS(rc)) 4371 { 4372 rc = AudioMixerCreate("AC'97 Mixer", 0 /* uFlags */, &pThis->pMixer); 4373 if (RT_SUCCESS(rc)) 4374 { 4375 rc = AudioMixerCreateSink(pThis->pMixer, "[Recording] Line In", AUDMIXSINKDIR_INPUT, &pThis->pSinkLineIn); 4376 AssertRC(rc); 4377 rc = AudioMixerCreateSink(pThis->pMixer, "[Recording] Microphone In", AUDMIXSINKDIR_INPUT, &pThis->pSinkMicIn); 4378 AssertRC(rc); 4379 rc = AudioMixerCreateSink(pThis->pMixer, "[Playback] PCM Output", AUDMIXSINKDIR_OUTPUT, &pThis->pSinkOut); 4380 AssertRC(rc); 4381 } 4382 } 4383 4384 if (RT_SUCCESS(rc)) 4385 { 4386 /* 4387 * Create all hardware streams. 4388 */ 4389 for (unsigned i = 0; i < AC97_MAX_STREAMS; i++) 4390 { 4391 int rc2 = ichac97R3StreamCreate(pThis, &pThis->aStreams[i], i /* SD# */); 4392 AssertRC(rc2); 4393 if (RT_SUCCESS(rc)) 4394 rc = rc2; 4395 } 4396 4397 # ifdef VBOX_WITH_AUDIO_AC97_ONETIME_INIT 4398 PAC97DRIVER pDrv; 4399 RTListForEach(&pThis->lstDrv, pDrv, AC97DRIVER, Node) 4400 { 4401 /* 4402 * Only primary drivers are critical for the VM to run. Everything else 4403 * might not worth showing an own error message box in the GUI. 4404 */ 4405 if (!(pDrv->fFlags & PDMAUDIODRVFLAGS_PRIMARY)) 4406 continue; 4407 4408 PPDMIAUDIOCONNECTOR pCon = pDrv->pConnector; 4409 AssertPtr(pCon); 4410 4411 bool fValidLineIn = AudioMixerStreamIsValid(pDrv->LineIn.pMixStrm); 4412 bool fValidMicIn = AudioMixerStreamIsValid(pDrv->MicIn.pMixStrm); 4413 bool fValidOut = AudioMixerStreamIsValid(pDrv->Out.pMixStrm); 4414 4415 if ( !fValidLineIn 4416 && !fValidMicIn 4417 && !fValidOut) 4418 { 4419 LogRel(("AC97: Falling back to NULL backend (no sound audible)\n")); 4420 4421 ichac97R3Reset(pDevIns); 4422 ichac97R3ReattachInternal(pThis, pDrv, pDrv->uLUN, "NullAudio"); 4423 4424 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", 4425 N_("No audio devices could be opened. Selecting the NULL audio backend " 4426 "with the consequence that no sound is audible")); 4372 if (backendCfg.cMaxStreamsIn) 4373 { 4374 /* If the audio backend supports two or more input streams at once, 4375 * warn if one of our two inputs (microphone-in and line-in) failed to initialize. */ 4376 if (backendCfg.cMaxStreamsIn >= 2) 4377 fWarn = !fValidLineIn || !fValidMicIn; 4378 /* If the audio backend only supports one input stream at once (e.g. pure ALSA, and 4379 * *not* ALSA via PulseAudio plugin!), only warn if both of our inputs failed to initialize. 4380 * One of the two simply is not in use then. */ 4381 else if (backendCfg.cMaxStreamsIn == 1) 4382 fWarn = !fValidLineIn && !fValidMicIn; 4383 /* Don't warn if our backend is not able of supporting any input streams at all. */ 4384 } 4385 4386 if ( !fWarn 4387 && backendCfg.cMaxStreamsOut) 4388 { 4389 fWarn = !fValidOut; 4390 } 4427 4391 } 4428 4392 else 4429 4393 { 4430 bool fWarn = false; 4431 4432 PDMAUDIOBACKENDCFG backendCfg; 4433 int rc2 = pCon->pfnGetConfig(pCon, &backendCfg); 4434 if (RT_SUCCESS(rc2)) 4394 LogRel(("AC97: Unable to retrieve audio backend configuration for LUN #%RU8, rc=%Rrc\n", pDrv->uLUN, rc2)); 4395 fWarn = true; 4396 } 4397 4398 if (fWarn) 4399 { 4400 char szMissingStreams[255] = ""; 4401 size_t len = 0; 4402 if (!fValidLineIn) 4435 4403 { 4436 if (backendCfg.cMaxStreamsIn) 4437 { 4438 /* If the audio backend supports two or more input streams at once, 4439 * warn if one of our two inputs (microphone-in and line-in) failed to initialize. */ 4440 if (backendCfg.cMaxStreamsIn >= 2) 4441 fWarn = !fValidLineIn || !fValidMicIn; 4442 /* If the audio backend only supports one input stream at once (e.g. pure ALSA, and 4443 * *not* ALSA via PulseAudio plugin!), only warn if both of our inputs failed to initialize. 4444 * One of the two simply is not in use then. */ 4445 else if (backendCfg.cMaxStreamsIn == 1) 4446 fWarn = !fValidLineIn && !fValidMicIn; 4447 /* Don't warn if our backend is not able of supporting any input streams at all. */ 4448 } 4449 4450 if ( !fWarn 4451 && backendCfg.cMaxStreamsOut) 4452 { 4453 fWarn = !fValidOut; 4454 } 4404 LogRel(("AC97: WARNING: Unable to open PCM line input for LUN #%RU8!\n", pDrv->uLUN)); 4405 len = RTStrPrintf(szMissingStreams, sizeof(szMissingStreams), "PCM Input"); 4455 4406 } 4456 else4407 if (!fValidMicIn) 4457 4408 { 4458 LogRel(("AC97: Unable to retrieve audio backend configuration for LUN #%RU8, rc=%Rrc\n", pDrv->uLUN, rc2)); 4459 fWarn = true; 4409 LogRel(("AC97: WARNING: Unable to open PCM microphone input for LUN #%RU8!\n", pDrv->uLUN)); 4410 len += RTStrPrintf(szMissingStreams + len, 4411 sizeof(szMissingStreams) - len, len ? ", PCM Microphone" : "PCM Microphone"); 4460 4412 } 4461 4462 if (fWarn) 4413 if (!fValidOut) 4463 4414 { 4464 char szMissingStreams[255] = ""; 4465 size_t len = 0; 4466 if (!fValidLineIn) 4467 { 4468 LogRel(("AC97: WARNING: Unable to open PCM line input for LUN #%RU8!\n", pDrv->uLUN)); 4469 len = RTStrPrintf(szMissingStreams, sizeof(szMissingStreams), "PCM Input"); 4470 } 4471 if (!fValidMicIn) 4472 { 4473 LogRel(("AC97: WARNING: Unable to open PCM microphone input for LUN #%RU8!\n", pDrv->uLUN)); 4474 len += RTStrPrintf(szMissingStreams + len, 4475 sizeof(szMissingStreams) - len, len ? ", PCM Microphone" : "PCM Microphone"); 4476 } 4477 if (!fValidOut) 4478 { 4479 LogRel(("AC97: WARNING: Unable to open PCM output for LUN #%RU8!\n", pDrv->uLUN)); 4480 len += RTStrPrintf(szMissingStreams + len, 4481 sizeof(szMissingStreams) - len, len ? ", PCM Output" : "PCM Output"); 4482 } 4483 4484 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", 4485 N_("Some AC'97 audio streams (%s) could not be opened. Guest applications generating audio " 4486 "output or depending on audio input may hang. Make sure your host audio device " 4487 "is working properly. Check the logfile for error messages of the audio " 4488 "subsystem"), szMissingStreams); 4415 LogRel(("AC97: WARNING: Unable to open PCM output for LUN #%RU8!\n", pDrv->uLUN)); 4416 len += RTStrPrintf(szMissingStreams + len, 4417 sizeof(szMissingStreams) - len, len ? ", PCM Output" : "PCM Output"); 4489 4418 } 4419 4420 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", 4421 N_("Some AC'97 audio streams (%s) could not be opened. Guest applications generating audio " 4422 "output or depending on audio input may hang. Make sure your host audio device " 4423 "is working properly. Check the logfile for error messages of the audio " 4424 "subsystem"), szMissingStreams); 4490 4425 } 4491 4426 } 4427 } 4492 4428 # endif /* VBOX_WITH_AUDIO_AC97_ONETIME_INIT */ 4493 } 4494 4495 if (RT_SUCCESS(rc)) 4496 ichac97R3Reset(pDevIns); 4497 4498 if (RT_SUCCESS(rc)) 4499 { 4500 static const char * const s_apszNames[] = 4501 { 4502 "AC97 PI", "AC97 PO", "AC97 MC" 4503 }; 4504 AssertCompile(RT_ELEMENTS(s_apszNames) == AC97_MAX_STREAMS); 4505 4506 for (unsigned i = 0; i < AC97_MAX_STREAMS; i++) 4507 { 4508 /* Create the emulation timer (per stream). 4509 * 4510 * Note: Use TMCLOCK_VIRTUAL_SYNC here, as the guest's AC'97 driver 4511 * relies on exact (virtual) DMA timing and uses DMA Position Buffers 4512 * instead of the LPIB registers. 4513 */ 4514 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, ichac97R3Timer, &pThis->aStreams[i], 4515 TMTIMER_FLAGS_NO_CRIT_SECT, s_apszNames[i], &pThis->pTimerR3[i]); 4516 AssertRCReturn(rc, rc); 4517 pThis->pTimerR0[i] = TMTimerR0Ptr(pThis->pTimerR3[i]); 4518 pThis->pTimerRC[i] = TMTimerRCPtr(pThis->pTimerR3[i]); 4519 4520 /* Use our own critcal section for the device timer. 4521 * That way we can control more fine-grained when to lock what. */ 4522 rc = TMR3TimerSetCritSect(pThis->pTimerR3[i], &pThis->CritSect); 4523 AssertRCReturn(rc, rc); 4524 } 4525 } 4526 4429 4430 ichac97R3Reset(pDevIns); 4431 4432 static const char * const s_apszNames[] = 4433 { 4434 "AC97 PI", "AC97 PO", "AC97 MC" 4435 }; 4436 AssertCompile(RT_ELEMENTS(s_apszNames) == AC97_MAX_STREAMS); 4437 4438 for (unsigned i = 0; i < AC97_MAX_STREAMS; i++) 4439 { 4440 /* Create the emulation timer (per stream). 4441 * 4442 * Note: Use TMCLOCK_VIRTUAL_SYNC here, as the guest's AC'97 driver 4443 * relies on exact (virtual) DMA timing and uses DMA Position Buffers 4444 * instead of the LPIB registers. 4445 */ 4446 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, ichac97R3Timer, &pThis->aStreams[i], 4447 TMTIMER_FLAGS_NO_CRIT_SECT, s_apszNames[i], &pThis->pTimerR3[i]); 4448 AssertRCReturn(rc, rc); 4449 pThis->pTimerR0[i] = TMTimerR0Ptr(pThis->pTimerR3[i]); 4450 pThis->pTimerRC[i] = TMTimerRCPtr(pThis->pTimerR3[i]); 4451 4452 /* Use our own critcal section for the device timer. 4453 * That way we can control more fine-grained when to lock what. */ 4454 rc = TMR3TimerSetCritSect(pThis->pTimerR3[i], &pThis->CritSect); 4455 AssertRCReturn(rc, rc); 4456 } 4457 4458 /* 4459 * Register statistics. 4460 */ 4527 4461 # ifdef VBOX_WITH_STATISTICS 4528 if (RT_SUCCESS(rc)) 4529 { 4530 /* 4531 * Register statistics. 4532 */ 4533 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatTimer, STAMTYPE_PROFILE, "/Devices/AC97/Timer", STAMUNIT_TICKS_PER_CALL, "Profiling ichac97Timer."); 4534 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatIn, STAMTYPE_PROFILE, "/Devices/AC97/Input", STAMUNIT_TICKS_PER_CALL, "Profiling input."); 4535 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatOut, STAMTYPE_PROFILE, "/Devices/AC97/Output", STAMUNIT_TICKS_PER_CALL, "Profiling output."); 4536 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatBytesRead, STAMTYPE_COUNTER, "/Devices/AC97/BytesRead" , STAMUNIT_BYTES, "Bytes read from AC97 emulation."); 4537 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatBytesWritten, STAMTYPE_COUNTER, "/Devices/AC97/BytesWritten", STAMUNIT_BYTES, "Bytes written to AC97 emulation."); 4538 } 4462 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatTimer, STAMTYPE_PROFILE, "Timer", STAMUNIT_TICKS_PER_CALL, "Profiling ichac97Timer."); 4463 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatIn, STAMTYPE_PROFILE, "Input", STAMUNIT_TICKS_PER_CALL, "Profiling input."); 4464 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatOut, STAMTYPE_PROFILE, "Output", STAMUNIT_TICKS_PER_CALL, "Profiling output."); 4465 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatBytesRead, STAMTYPE_COUNTER, "BytesRead" , STAMUNIT_BYTES, "Bytes read from AC97 emulation."); 4466 PDMDevHlpSTAMRegister(pDevIns, &pThis->StatBytesWritten, STAMTYPE_COUNTER, "BytesWritten", STAMUNIT_BYTES, "Bytes written to AC97 emulation."); 4539 4467 # endif 4540 4468 4541 LogFlowFuncLeaveRC( rc);4542 return rc;4469 LogFlowFuncLeaveRC(VINF_SUCCESS); 4470 return VINF_SUCCESS; 4543 4471 } 4544 4472 -
trunk/src/VBox/Devices/Audio/DevSB16.cpp
r82225 r82228 107 107 /** Driver flags. */ 108 108 PDMAUDIODRVFLAGS fFlags; 109 uint32_t PaddingFlags;110 109 /** LUN # to which this driver has been assigned. */ 111 110 uint8_t uLUN; 112 111 /** Whether this driver is in an attached state or not. */ 113 112 bool fAttached; 114 uint8_t Padding[ 4];113 uint8_t Padding[2]; 115 114 /** Pointer to attached driver base interface. */ 116 115 R3PTRTYPE(PPDMIBASE) pDrvBase; … … 2164 2163 pDrv->fFlags |= PDMAUDIODRVFLAGS_PRIMARY; 2165 2164 2166 LogFunc(("LUN#% RU8: pCon=%p, drvFlags=0x%x\n", uLUN, pDrv->pConnector, pDrv->fFlags));2165 LogFunc(("LUN#%u: pCon=%p, drvFlags=0x%x\n", uLUN, pDrv->pConnector, pDrv->fFlags)); 2167 2166 2168 2167 /* Attach to driver list if not attached yet. */ … … 2219 2218 * @interface_method_impl{PDMDEVREG,pfnAttach} 2220 2219 */ 2221 static DECLCALLBACK(int) sb16Attach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)2220 static DECLCALLBACK(int) sb16Attach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags) 2222 2221 { 2223 2222 PSB16STATE pThis = PDMDEVINS_2_DATA(pDevIns, PSB16STATE); 2224 2223 2225 LogFunc((" uLUN=%u, fFlags=0x%x\n", uLUN, fFlags));2224 LogFunc(("iLUN=%u, fFlags=0x%x\n", iLUN, fFlags)); 2226 2225 2227 2226 PSB16DRIVER pDrv; 2228 int rc2 = sb16AttachInternal(pThis, uLUN, fFlags, &pDrv);2227 int rc2 = sb16AttachInternal(pThis, iLUN, fFlags, &pDrv); 2229 2228 if (RT_SUCCESS(rc2)) 2230 2229 rc2 = sb16CreateDrvStream(pThis, &pThis->Out.Cfg, pDrv); … … 2236 2235 * @interface_method_impl{PDMDEVREG,pfnDetach} 2237 2236 */ 2238 static DECLCALLBACK(void) sb16Detach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags)2237 static DECLCALLBACK(void) sb16Detach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags) 2239 2238 { 2240 2239 PSB16STATE pThis = PDMDEVINS_2_DATA(pDevIns, PSB16STATE); 2241 2240 2242 LogFunc((" uLUN=%u, fFlags=0x%x\n", uLUN, fFlags));2241 LogFunc(("iLUN=%u, fFlags=0x%x\n", iLUN, fFlags)); 2243 2242 2244 2243 PSB16DRIVER pDrv, pDrvNext; 2245 2244 RTListForEachSafe(&pThis->lstDrv, pDrv, pDrvNext, SB16DRIVER, Node) 2246 2245 { 2247 if (pDrv->uLUN == uLUN)2246 if (pDrv->uLUN == iLUN) 2248 2247 { 2249 2248 int rc2 = sb16DetachInternal(pThis, pDrv, fFlags); … … 2253 2252 pDrv = NULL; 2254 2253 } 2255 2256 2254 break; 2257 2255 } … … 2260 2258 2261 2259 /** 2262 * Re -attaches (replaces) a driver with a new driver.2260 * Replaces a driver with a the NullAudio drivers. 2263 2261 * 2264 2262 * @returns VBox status code. 2265 2263 * @param pThis Device instance. 2266 * @param uLUN The logical unit which is being re-detached. 2267 * @param pszDriver New driver name to attach. 2268 */ 2269 static int sb16Reattach(PSB16STATE pThis, uint8_t uLUN, const char *pszDriver) 2270 { 2271 AssertPtr(pThis); 2272 2273 int rc = PDMDevHlpDriverReconfigure2(pThis->pDevInsR3, uLUN, "AUDIO", pszDriver); 2264 * @param iLun The logical unit which is being replaced. 2265 */ 2266 static int sb16ReconfigLunWithNullAudio(PSB16STATE pThis, unsigned iLun) 2267 { 2268 int rc = PDMDevHlpDriverReconfigure2(pThis->pDevInsR3, iLun, "AUDIO", "NullAudio"); 2274 2269 if (RT_SUCCESS(rc)) 2275 rc = sb16AttachInternal(pThis, uLUN, 0 /* fFlags */, NULL /* ppDrv */); 2276 2277 LogFunc(("pThis=%p, uLUN=%u, pszDriver=%s, rc=%Rrc\n", pThis, uLUN, pszDriver, rc)); 2278 2270 rc = sb16AttachInternal(pThis, iLun, 0 /* fFlags */, NULL /* ppDrv */); 2271 LogFunc(("pThis=%p, iLun=%u, rc=%Rrc\n", pThis, iLun, rc)); 2279 2272 return rc; 2280 2273 } … … 2423 2416 2424 2417 /* 2425 * Create timer (s), register & attach stuff.2418 * Create timers. 2426 2419 */ 2427 2420 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, sb16TimerIRQ, pThis, 2428 2421 TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "SB16 IRQ timer", &pThis->pTimerIRQ); 2429 if (RT_FAILURE(rc)) 2430 AssertMsgFailedReturn(("Error creating IRQ timer, rc=%Rrc\n", rc), rc); 2431 2422 AssertRCReturn(rc, rc); 2423 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, sb16TimerIO, pThis, 2424 TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "SB16 IO timer", &pThis->pTimerIO); 2425 AssertRCReturn(rc, rc); 2426 pThis->cTimerTicksIO = TMTimerGetFreq(pThis->pTimerIO) / uTimerHz; 2427 pThis->uTimerTSIO = TMTimerGet(pThis->pTimerIO); 2428 LogFunc(("Timer ticks=%RU64 (%RU16 Hz)\n", pThis->cTimerTicksIO, uTimerHz)); 2429 2430 /* 2431 * Register I/O and DMA. 2432 */ 2432 2433 rc = PDMDevHlpIOPortRegister(pDevIns, pThis->port + 0x04, 2, pThis, mixer_write, mixer_read, NULL, NULL, "SB16"); 2433 if (RT_FAILURE(rc)) 2434 return rc; 2434 AssertRCReturn(rc, rc); 2435 2435 rc = PDMDevHlpIOPortRegister(pDevIns, pThis->port + 0x06, 10, pThis, dsp_write, dsp_read, NULL, NULL, "SB16"); 2436 if (RT_FAILURE(rc)) 2437 return rc; 2436 AssertRCReturn(rc, rc); 2438 2437 2439 2438 rc = PDMDevHlpDMARegister(pDevIns, pThis->hdma, sb16DMARead, pThis); 2440 if (RT_FAILURE(rc)) 2441 return rc; 2439 AssertRCReturn(rc, rc); 2442 2440 rc = PDMDevHlpDMARegister(pDevIns, pThis->dma, sb16DMARead, pThis); 2443 if (RT_FAILURE(rc)) 2444 return rc; 2441 AssertRCReturn(rc, rc); 2445 2442 2446 2443 pThis->can_write = 1; 2447 2444 2445 /* 2446 * Register Saved state. 2447 */ 2448 2448 rc = PDMDevHlpSSMRegister3(pDevIns, SB16_SAVE_STATE_VERSION, sizeof(SB16STATE), sb16LiveExec, sb16SaveExec, sb16LoadExec); 2449 if (RT_FAILURE(rc)) 2450 return rc; 2449 AssertRCReturn(rc, rc); 2451 2450 2452 2451 /* 2453 * Attach driver. 2452 * Attach drivers. We ASSUME they are configured consecutively without any 2453 * gaps, so we stop when we hit the first LUN w/o a driver configured. 2454 2454 */ 2455 uint8_t uLUN;2456 for (uLUN = 0; uLUN < UINT8_MAX; ++uLUN)2457 {2458 LogFunc(("Trying to attach driver for LUN #%RU8 ...\n", uLUN));2459 rc = sb16AttachInternal(pThis, uLUN, 0 /* fFlags */, NULL /* ppDrv */);2460 if ( RT_FAILURE(rc))2455 for (unsigned iLun = 0; ; iLun++) 2456 { 2457 AssertBreak(iLun < UINT8_MAX); 2458 LogFunc(("Trying to attach driver for LUN#%u ...\n", iLun)); 2459 rc = sb16AttachInternal(pThis, iLun, 0 /* fFlags */, NULL /* ppDrv */); 2460 if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 2461 2461 { 2462 if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 2463 rc = VINF_SUCCESS; 2464 else if (rc == VERR_AUDIO_BACKEND_INIT_FAILED) 2465 { 2466 sb16Reattach(pThis, uLUN, "NullAudio"); 2467 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", 2468 N_("Host audio backend initialization has failed. Selecting the NULL audio backend with the consequence that no sound is audible")); 2469 /* Attaching to the NULL audio backend will never fail. */ 2470 rc = VINF_SUCCESS; 2471 } 2462 LogFunc(("cLUNs=%u\n", iLun)); 2472 2463 break; 2473 2464 } 2474 } 2475 2476 LogFunc(("cLUNs=%RU8, rc=%Rrc\n", uLUN, rc)); 2465 if (rc == VERR_AUDIO_BACKEND_INIT_FAILED) 2466 { 2467 sb16ReconfigLunWithNullAudio(pThis, iLun); /* Pretend attaching to the NULL audio backend will never fail. */ 2468 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", 2469 N_("Host audio backend initialization has failed. " 2470 "Selecting the NULL audio backend with the consequence that no sound is audible")); 2471 } 2472 else 2473 AssertLogRelMsgReturn(RT_SUCCESS(rc), ("LUN#%u: rc=%Rrc\n", iLun, rc), rc); 2474 } 2477 2475 2478 2476 sb16CmdResetLegacy(pThis); … … 2489 2487 continue; 2490 2488 2489 /** @todo No input streams available for SB16 yet. */ 2490 if (!pDrv->Out.pStream) 2491 continue; 2492 2491 2493 PPDMIAUDIOCONNECTOR pCon = pDrv->pConnector; 2492 2494 AssertPtr(pCon); 2493 2494 /** @todo No input streams available for SB16 yet. */ 2495 2496 if (!pDrv->Out.pStream) 2497 continue; 2498 2499 bool fValidOut = pCon->pfnStreamGetStatus(pCon, pDrv->Out.pStream) & PDMAUDIOSTREAMSTS_FLAG_INITIALIZED; 2500 if (!fValidOut) 2495 if ( pCon == NULL /* paranoia */ 2496 || !(pCon->pfnStreamGetStatus(pCon, pDrv->Out.pStream) & PDMAUDIOSTREAMSTS_FLAG_INITIALIZED)) 2501 2497 { 2502 2498 LogRel(("SB16: Falling back to NULL backend (no sound audible)\n")); 2503 2499 2504 2500 sb16CmdResetLegacy(pThis); 2505 sb16Re attach(pThis, pDrv->uLUN, "NullAudio");2501 sb16ReconfigLunWithNullAudio(pThis, pDrv->uLUN); 2506 2502 pDrv = NULL; /* no longer valid */ 2507 2503 2508 2504 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", 2509 N_("No audio devices could be opened. Selecting the NULL audio backend with the consequence that no sound is audible")); 2505 N_("No audio devices could be opened. " 2506 "Selecting the NULL audio backend with the consequence that no sound is audible")); 2510 2507 } 2511 2508 } 2512 2509 #endif 2513 2510 2514 if (RT_SUCCESS(rc)) 2515 { 2516 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, sb16TimerIO, pThis, 2517 TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "SB16 IO timer", &pThis->pTimerIO); 2518 if (RT_SUCCESS(rc)) 2519 { 2520 pThis->cTimerTicksIO = TMTimerGetFreq(pThis->pTimerIO) / uTimerHz; 2521 pThis->uTimerTSIO = TMTimerGet(pThis->pTimerIO); 2522 LogFunc(("Timer ticks=%RU64 (%RU16 Hz)\n", pThis->cTimerTicksIO, uTimerHz)); 2523 } 2524 else 2525 AssertMsgFailedReturn(("Error creating I/O timer, rc=%Rrc\n", rc), rc); 2526 } 2527 2511 /* 2512 * Delete debug file. 2513 */ 2528 2514 #ifdef VBOX_AUDIO_DEBUG_DUMP_PCM_DATA 2529 2515 RTFileDelete(VBOX_AUDIO_DEBUG_DUMP_PCM_DATA_PATH "sb16WriteAudio.pcm");
Note:
See TracChangeset
for help on using the changeset viewer.