- Timestamp:
- Dec 4, 2014 1:49:43 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 10 added
- 1 deleted
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
trunk/src/VBox
-
trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
r50708 r53442 5 5 6 6 /* 7 * Copyright (C) 2006-201 3Oracle Corporation7 * Copyright (C) 2006-2014 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 19 19 * Header Files * 20 20 *******************************************************************************/ 21 #include <VBox/vmm/pdmdev.h> 22 #include <VBox/vmm/pdmaudioifs.h> 23 24 #include <iprt/assert.h> 25 #include <iprt/mem.h> 26 #include <iprt/string.h> 27 #include <iprt/uuid.h> 28 29 #include "VBoxDD.h" 30 31 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 32 # include "AudioMixer.h" 33 #else 34 extern "C" { 35 #include "audio.h" 36 } 37 #endif 38 39 /* 40 #ifdef LOG_GROUP 41 #undef LOG_GROUP 42 #endif 21 43 #define LOG_GROUP LOG_GROUP_DEV_AUDIO 22 #include <VBox/vmm/pdmdev.h> 23 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 24 #include <VBox/vmm/pdmaudioifs.h> 25 #endif 26 #include <iprt/assert.h> 27 #include <iprt/uuid.h> 28 #include <iprt/string.h> 29 30 #include "VBoxDD.h" 31 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER 32 extern "C" { 33 #include "audio.h" 34 } 35 #endif 36 44 #include <VBox/log.h> 45 */ 37 46 38 47 /******************************************************************************* … … 44 53 #else 45 54 # define USE_MIXER 55 #endif 56 57 //#define DEBUG_LUN 58 #ifdef DEBUG_LUN 59 # define DEBUG_LUN_NUM 1 46 60 #endif 47 61 … … 171 185 * Structures and Typedefs * 172 186 *******************************************************************************/ 187 /** 188 * Buffer descriptor. 189 */ 173 190 typedef struct BD 174 191 { … … 187 204 uint8_t cr; /**< rw 0, control register */ 188 205 int bd_valid; /**< initialized? */ 189 BD bd; 206 BD bd; /**< buffer descriptor */ 190 207 } AC97BusMasterRegs; 191 208 /** Pointer to a AC97 bus master register. */ 192 209 typedef AC97BusMasterRegs *PAC97BMREG; 193 210 211 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 212 /** 213 * Struct for maintaining a host backend driver. 214 */ 215 typedef struct AC97STATE *PAC97STATE; 216 typedef struct AC97DRIVER 217 { 218 /** Pointer to AC97 controller (state). */ 219 PAC97STATE pAC97State; 220 /** LUN # to which this driver has been assigned. */ 221 uint8_t uLUN; 222 /** Audio connector interface to the underlying 223 * host backend. */ 224 R3PTRTYPE(PPDMIAUDIOCONNECTOR) pConnector; 225 /** PCM input stream. */ 226 R3PTRTYPE(PPDMAUDIOGSTSTRMIN) pStrmIn; 227 /** Mixer handle for input stream. */ 228 R3PTRTYPE(PAUDMIXSTREAM) phStrmIn; 229 /** PCM output stream. */ 230 R3PTRTYPE(PPDMAUDIOGSTSTRMOUT) pStrmOut; 231 /** PCM microphone input stream. */ 232 R3PTRTYPE(PPDMAUDIOGSTSTRMIN) pStrmMic; 233 /** Mixer handle for output stream. */ 234 R3PTRTYPE(PAUDMIXSTREAM) phStrmMic; 235 } AC97DRIVER; 236 /** Pointer to a AC97 driver. */ 237 typedef AC97DRIVER *PAC97DRIVER; 238 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 239 194 240 typedef struct AC97STATE 195 241 { … … 197 243 PCIDevice PciDev; 198 244 199 /** Audio stuff. */ 200 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER 201 QEMUSoundCard card; 202 #endif 245 /** Audio stuff. */ 203 246 /** Global Control (Bus Master Control Register) */ 204 247 uint32_t glob_cnt; … … 212 255 uint8_t mixer_data[256]; 213 256 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 214 /** PCM in */ 215 PPDMGSTVOICEIN voice_pi[2]; 216 /** PCM out */ 217 PPDMGSTVOICEOUT voice_po[2]; 218 /** Mic in */ 219 PPDMGSTVOICEIN voice_mc[2]; 220 #else 257 /** Number of active + allocated LUNs. Each 258 * LUN has an AC'97 driver assigned. */ 259 uint8_t cLUNs; 260 /** Array of active AC'97 drivers. */ 261 R3PTRTYPE(PAC97DRIVER) paDrv[32]; 262 /** The device' software mixer. */ 263 R3PTRTYPE(PAUDIOMIXER) pMixer; 264 /** Audio sink for line input. */ 265 R3PTRTYPE(PAUDMIXSINK) pSinkLineIn; 266 /** Audio sink for microphone input. */ 267 R3PTRTYPE(PAUDMIXSINK) pSinkMicIn; 268 #else 269 QEMUSoundCard card; 221 270 /** PCM in */ 222 271 SWVoiceIn *voice_pi; … … 225 274 /** Mic in */ 226 275 SWVoiceIn *voice_mc; 227 #endif 276 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 228 277 uint8_t silence[128]; 229 278 int bup_flag; 230 279 /** Pointer to the device instance. */ 231 280 PPDMDEVINSR3 pDevIns; 232 /** Pointer to the connector of the attached audio driver. */233 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER234 PPDMIAUDIOCONNECTOR pDrv[2];235 #else236 PPDMIAUDIOCONNECTOR pDrv;237 #endif238 281 /** Pointer to the attached audio driver. */ 239 282 PPDMIBASE pDrvBase; … … 286 329 #define GET_BM(a_idx) ( ((a_idx) >> 4) & 3 ) 287 330 288 static void po_callback(void *opaque, int free); 289 static void pi_callback(void *opaque, int avail); 290 static void mc_callback(void *opaque, int avail); 291 292 static void warm_reset(PAC97STATE pThis) 331 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 332 static void ichac97OutputCallback(void *pvContext, uint32_t cbFree); 333 static void ichac97InputCallback(void *pvContext, uint32_t cbAvail); 334 static void ichac97MicInCallback(void *pvContext, uint32_t cbAvail); 335 #else 336 static void ichac97OutputCallback(void *pvContext, int cbFree); 337 static void ichac97InputCallback(void *pvContext, int cbAvail); 338 static void ichac97MicInCallback(void *pvContext, int cbAvail); 339 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 340 341 static void ichac97WarmReset(PAC97STATE pThis) 293 342 { 294 343 NOREF(pThis); 295 344 } 296 345 297 static void cold_reset(PAC97STATE pThis)346 static void ichac97ColdReset(PAC97STATE pThis) 298 347 { 299 348 NOREF(pThis); 300 349 } 301 350 302 /** Fetch Buffer Descriptor at _CIV*/303 static void fetch_bd(PAC97STATE pThis, PAC97BMREG pReg)351 /** Fetches the buffer descriptor at _CIV. */ 352 static void ichac97FetchBufDesc(PAC97STATE pThis, PAC97BMREG pReg) 304 353 { 305 354 PPDMDEVINS pDevIns = ICHAC97STATE_2_DEVINS(pThis); … … 315 364 #endif 316 365 pReg->picb = pReg->bd.ctl_len & 0xffff; 317 Log (("ac97:bd %2d addr=%#x ctl=%#06x len=%#x(%d bytes)\n",318 pReg->civ, pReg->bd.addr, pReg->bd.ctl_len >> 16,319 pReg->bd.ctl_len & 0xffff, (pReg->bd.ctl_len & 0xffff) << 1));366 LogFlowFunc(("bd %2d addr=%#x ctl=%#06x len=%#x(%d bytes)\n", 367 pReg->civ, pReg->bd.addr, pReg->bd.ctl_len >> 16, 368 pReg->bd.ctl_len & 0xffff, (pReg->bd.ctl_len & 0xffff) << 1)); 320 369 } 321 370 … … 323 372 * Update the BM status register 324 373 */ 325 static void update_sr(PAC97STATE pThis, PAC97BMREG pReg, uint32_t new_sr)374 static void ichac97UpdateStatus(PAC97STATE pThis, PAC97BMREG pReg, uint32_t new_sr) 326 375 { 327 376 PPDMDEVINS pDevIns = ICHAC97STATE_2_DEVINS(pThis); … … 354 403 pReg->sr = new_sr; 355 404 356 Log (("ac97:IOC%d LVB%d sr=%#x event=%d level=%d\n",357 pReg->sr & SR_BCIS, pReg->sr & SR_LVBCI, pReg->sr, event, level));405 LogFlowFunc(("IOC%d LVB%d sr=%#x event=%d level=%d\n", 406 pReg->sr & SR_BCIS, pReg->sr & SR_LVBCI, pReg->sr, event, level)); 358 407 359 408 if (event) … … 364 413 pThis->glob_sta &= ~masks[pReg - pThis->bm_regs]; 365 414 366 Log (("ac97:set irq level=%d\n", !!level));415 LogFlowFunc(("set irq level=%d\n", !!level)); 367 416 PDMDevHlpPCISetIrq(pDevIns, 0, !!level); 368 417 } 369 418 } 370 419 371 static void voice_set_active(PAC97STATE pThis, int bm_index, int on) 372 { 420 static void ichac97StreamSetActive(PAC97STATE pThis, int bm_index, int on) 421 { 422 AssertPtrReturnVoid(pThis); 423 424 LogFlowFunc(("index=%d, on=%d\n", bm_index, on)); 425 426 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 373 427 switch (bm_index) 374 428 { 375 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER376 uint32_t lun;377 429 case PI_INDEX: 378 for (lun = 0; lun < 2; lun++) 379 pThis->pDrv[lun]->pfnEnableIn(pThis->pDrv[lun], pThis->voice_pi[lun], on); 430 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 431 pThis->paDrv[lun]->pConnector->pfnEnableIn(pThis->paDrv[lun]->pConnector, 432 pThis->paDrv[lun]->pStrmIn, RT_BOOL(on)); 380 433 break; 434 381 435 case PO_INDEX: 382 for (lun = 0; lun < 2; lun++) 383 pThis->pDrv[lun]->pfnEnableOut(pThis->pDrv[lun], pThis->voice_po[lun], on); 384 break; 436 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 437 pThis->paDrv[lun]->pConnector->pfnEnableOut(pThis->paDrv[lun]->pConnector, 438 pThis->paDrv[lun]->pStrmOut, RT_BOOL(on)); 439 break; 440 385 441 case MC_INDEX: 386 for (lun = 0; lun < 2; lun++) 387 pThis->pDrv[lun]->pfnEnableIn(pThis->pDrv[lun], pThis->voice_mc[lun], on); 442 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 443 pThis->paDrv[lun]->pConnector->pfnEnableIn(pThis->paDrv[lun]->pConnector, 444 pThis->paDrv[lun]->pStrmMic, RT_BOOL(on)); 388 445 break; 389 #else 446 447 default: 448 AssertMsgFailed(("Wrong index %d\n", bm_index)); 449 break; 450 } 451 #else 452 switch (bm_index) 453 { 390 454 case PI_INDEX: AUD_set_active_in( pThis->voice_pi, on); break; 391 455 case PO_INDEX: AUD_set_active_out(pThis->voice_po, on); break; 392 456 case MC_INDEX: AUD_set_active_in( pThis->voice_mc, on); break; 393 #endif394 457 default: AssertFailed (); break; 395 458 } 396 } 397 398 static void reset_bm_regs(PAC97STATE pThis, PAC97BMREG pReg) 399 { 400 Log(("ac97: reset_bm_regs\n")); 459 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 460 } 461 462 static void ichac97ResetBMRegs(PAC97STATE pThis, PAC97BMREG pReg) 463 { 464 LogFlowFunc(("reset_bm_regs\n")); 401 465 pReg->bdbar = 0; 402 466 pReg->civ = 0; 403 467 pReg->lvi = 0; 404 468 /** @todo do we need to do that? */ 405 update_sr(pThis, pReg, SR_DCH);469 ichac97UpdateStatus(pThis, pReg, SR_DCH); 406 470 pReg->picb = 0; 407 471 pReg->piv = 0; 408 472 pReg->cr = pReg->cr & CR_DONT_CLEAR_MASK; 409 473 pReg->bd_valid = 0; 410 voice_set_active(pThis, pReg - pThis->bm_regs, 0);411 memset(pThis->silence, 0, sizeof(pThis->silence));412 } 413 414 static void mixer_store(PAC97STATE pThis, uint32_t i, uint16_t v)474 ichac97StreamSetActive(pThis, pReg - pThis->bm_regs, 0); 475 RT_ZERO(pThis->silence); 476 } 477 478 static void ichac97MixerStore(PAC97STATE pThis, uint32_t i, uint16_t v) 415 479 { 416 480 if (i + 2 > sizeof(pThis->mixer_data)) 417 481 { 418 Log (("ac97:mixer_store: index %d out of bounds %d\n", i, sizeof(pThis->mixer_data)));482 LogFlowFunc(("mixer_store: index %d out of bounds %d\n", i, sizeof(pThis->mixer_data))); 419 483 return; 420 484 } … … 424 488 } 425 489 426 static uint16_t mixer_load(PAC97STATE pThis, uint32_t i)490 static uint16_t ichac97MixerLoad(PAC97STATE pThis, uint32_t i) 427 491 { 428 492 uint16_t val; … … 430 494 if (i + 2 > sizeof(pThis->mixer_data)) 431 495 { 432 Log (("ac97:mixer_store: index %d out of bounds %d\n", i, sizeof(pThis->mixer_data)));496 LogFlowFunc(("mixer_store: index %d out of bounds %d\n", i, sizeof(pThis->mixer_data))); 433 497 val = 0xffff; 434 498 } … … 439 503 } 440 504 441 static void open_voice(PAC97STATE pThis, int index, int freq) 442 { 443 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 505 static void ichac97OpenStream(PAC97STATE pThis, int index, uint16_t freq) 506 { 507 LogFlowFunc(("index=%d, freq=%RU16\n", index, freq)); 508 444 509 int rc; 445 #endif 446 LogFlow(("DevIchAC97: open_voice freq = %d\n", freq)); 510 511 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 447 512 if (freq) 448 513 { 449 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER 514 PDMAUDIOSTREAMCFG streamCfg; 515 RT_ZERO(streamCfg); 516 streamCfg.uHz = freq; 517 streamCfg.cChannels = 2; 518 streamCfg.enmFormat = AUD_FMT_S16; 519 streamCfg.enmEndianness = PDMAUDIOHOSTENDIANESS; 520 521 char *pszDesc; 522 523 switch (index) 524 { 525 case PI_INDEX: /* PCM in */ 526 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 527 { 528 if (RTStrAPrintf(&pszDesc, "[LUN#%RU8] ac97.pi", lun) <= 0) 529 { 530 rc = VERR_NO_MEMORY; 531 break; 532 } 533 534 rc = pThis->paDrv[lun]->pConnector->pfnOpenIn(pThis->paDrv[lun]->pConnector, 535 pszDesc, PDMAUDIORECSOURCE_LINE_IN, 536 ichac97InputCallback, pThis->paDrv[lun] /* pvContext */, 537 &streamCfg, 538 &pThis->paDrv[lun]->pStrmIn); 539 LogFlowFunc(("LUN#%RU8: Opened line input with rc=%Rrc\n", lun, rc)); 540 if (rc == VINF_SUCCESS) /* Note: Could return VWRN_ALREADY_EXISTS. */ 541 { 542 audioMixerRemoveStream(pThis->pSinkLineIn, pThis->paDrv[lun]->phStrmIn); 543 rc = audioMixerAddStreamIn(pThis->pSinkLineIn, 544 pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmIn, 545 0 /* uFlags */, 546 &pThis->paDrv[lun]->phStrmIn); 547 } 548 549 RTStrFree(pszDesc); 550 } 551 break; 552 553 case PO_INDEX: /* PCM out */ 554 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 555 { 556 if (RTStrAPrintf(&pszDesc, "[LUN#%RU8] ac97.po", lun) <= 0) 557 { 558 rc = VERR_NO_MEMORY; 559 break; 560 } 561 562 rc = pThis->paDrv[lun]->pConnector->pfnOpenOut(pThis->paDrv[lun]->pConnector, pszDesc, 563 ichac97OutputCallback, pThis->paDrv[lun] /* pvContext */, 564 &streamCfg, 565 &pThis->paDrv[lun]->pStrmOut); 566 LogFlowFunc(("LUN#%RU8: Opened output with rc=%Rrc\n", lun, rc)); 567 RTStrFree(pszDesc); 568 } 569 break; 570 571 case MC_INDEX: /* Mic in */ 572 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 573 { 574 if (RTStrAPrintf(&pszDesc, "[LUN#%RU8] ac97.mc", lun) <= 0) 575 { 576 rc = VERR_NO_MEMORY; 577 break; 578 } 579 580 rc = pThis->paDrv[lun]->pConnector->pfnOpenIn(pThis->paDrv[lun]->pConnector, 581 pszDesc, PDMAUDIORECSOURCE_MIC, 582 ichac97MicInCallback, pThis->paDrv[lun] /* pvContext */, 583 &streamCfg, 584 &pThis->paDrv[lun]->pStrmMic); 585 LogFlowFunc(("LUN#%RU8: Opened mic input with rc=%Rrc\n", lun, rc)); 586 if (rc == VINF_SUCCESS) /* Note: Could return VWRN_ALREADY_EXISTS. */ 587 { 588 audioMixerRemoveStream(pThis->pSinkMicIn, pThis->paDrv[lun]->phStrmMic); 589 rc = audioMixerAddStreamIn(pThis->pSinkMicIn, 590 pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmMic, 591 0 /* uFlags */, 592 &pThis->paDrv[lun]->phStrmMic); 593 } 594 595 RTStrFree(pszDesc); 596 } 597 break; 598 599 default: 600 AssertMsgFailed(("Unsupported index %d\n", index)); 601 break; 602 } 603 } 604 else 605 { 606 switch (index) 607 { 608 case PI_INDEX: 609 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 610 { 611 pThis->paDrv[lun]->pConnector->pfnCloseIn(pThis->paDrv[lun]->pConnector, 612 pThis->paDrv[lun]->pStrmIn); 613 audioMixerRemoveStream(pThis->pSinkLineIn, 614 pThis->paDrv[lun]->phStrmIn); 615 pThis->paDrv[lun]->pStrmIn = NULL; 616 pThis->paDrv[lun]->phStrmIn = NULL; 617 } 618 619 LogFlowFunc(("Closed line input\n")); 620 break; 621 622 case PO_INDEX: 623 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 624 { 625 pThis->paDrv[lun]->pConnector->pfnCloseOut(pThis->paDrv[lun]->pConnector, 626 pThis->paDrv[lun]->pStrmOut); 627 pThis->paDrv[lun]->pStrmOut = NULL; 628 } 629 630 LogFlowFunc(("Closed output\n")); 631 break; 632 633 case MC_INDEX: 634 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 635 { 636 pThis->paDrv[lun]->pConnector->pfnCloseIn(pThis->paDrv[lun]->pConnector, 637 pThis->paDrv[lun]->pStrmMic); 638 audioMixerRemoveStream(pThis->pSinkMicIn, 639 pThis->paDrv[lun]->phStrmMic); 640 pThis->paDrv[lun]->pStrmMic = NULL; 641 pThis->paDrv[lun]->phStrmMic = NULL; 642 } 643 644 LogFlowFunc(("Closed mic input\n")); 645 break; 646 647 default: 648 AssertMsgFailed(("Unsupported index %d\n", index)); 649 break; 650 } 651 652 rc = VINF_SUCCESS; 653 } 654 #else 655 if (freq) 656 { 450 657 audsettings_t as; 451 658 as.freq = freq; … … 453 660 as.fmt = AUD_FMT_S16; 454 661 as.endianness = 0; 455 uint32_t lun; 456 #endif 662 457 663 switch (index) 458 664 { 459 665 case PI_INDEX: /* PCM in */ 460 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 461 for (uint32_t lun = 0; lun < 2; lun++) 462 rc = pThis->pDrv[lun]->pfnOpenIn(pThis->pDrv[lun], &pThis->voice_pi[lun], "ac97.pi", 463 pThis, pi_callback, freq, 2, AUD_FMT_S16, 0); 464 #else 465 pThis->voice_pi = AUD_open_in(&pThis->card, pThis->voice_pi, "ac97.pi", pThis, pi_callback, &as); 466 #endif 666 pThis->voice_pi = AUD_open_in(&pThis->card, pThis->voice_pi, "ac97.pi", pThis, ichac97InputCallback, &as); 467 667 #ifdef LOG_VOICES 468 668 LogRel(("AC97: open PI freq=%d (%s)\n", freq, pThis->voice_pi ? "ok" : "FAIL")); 469 669 #endif 670 rc = pThis->voice_pi ? VINF_SUCCESS : VERR_GENERAL_FAILURE; 470 671 break; 471 672 472 673 case PO_INDEX: /* PCM out */ 473 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 474 for (int lun = 0; lun < 2; lun++) 475 { 476 LogFlow(("LUN###%d\n", lun)); 477 rc = pThis->pDrv[lun]->pfnOpenOut(pThis->pDrv[lun], &pThis->voice_po[lun], "ac97.po", 478 pThis, po_callback, freq, 2, AUD_FMT_S16, 0); 479 } 480 #else 481 pThis->voice_po = AUD_open_out(&pThis->card, pThis->voice_po, "ac97.po", pThis, po_callback, &as); 482 #endif 674 pThis->voice_po = AUD_open_out(&pThis->card, pThis->voice_po, "ac97.po", pThis, ichac97OutputCallback, &as); 483 675 #ifdef LOG_VOICES 484 676 LogRel(("AC97: open PO freq=%d (%s)\n", freq, pThis->voice_po ? "ok" : "FAIL")); 485 677 #endif 678 rc = pThis->voice_po ? VINF_SUCCESS : VERR_GENERAL_FAILURE; 486 679 break; 487 680 488 681 case MC_INDEX: /* Mic in */ 489 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 490 for (uint32_t lun = 0; lun < 2; lun++) 491 rc = pThis->pDrv[lun]->pfnOpenIn(pThis->pDrv[lun], &pThis->voice_mc[lun], "ac97.mc", 492 pThis, mc_callback, freq, 2, AUD_FMT_S16, 0); 493 #else 494 pThis->voice_mc = AUD_open_in(&pThis->card, pThis->voice_mc, "ac97.mc", pThis, mc_callback, &as); 495 #endif 682 pThis->voice_mc = AUD_open_in(&pThis->card, pThis->voice_mc, "ac97.mc", pThis, ichac97MicInCallback, &as); 496 683 #ifdef LOG_VOICES 497 684 LogRel(("AC97: open MC freq=%d (%s)\n", freq, pThis->voice_mc ? "ok" : "FAIL")); 498 685 #endif 686 rc = pThis->voice_mc ? VINF_SUCCESS : VERR_GENERAL_FAILURE; 499 687 break; 500 688 } … … 505 693 { 506 694 case PI_INDEX: 507 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER508 for (uint32_t lun = 0; lun < 2; lun++)509 {510 pThis->pDrv[lun]->pfnCloseIn(pThis->pDrv[lun], pThis->voice_pi[lun]);511 pThis->voice_pi[lun] = NULL;512 }513 #else514 695 AUD_close_in(&pThis->card, pThis->voice_pi); 515 696 pThis->voice_pi = NULL; 516 #endif517 697 #ifdef LOG_VOICES 518 698 LogRel(("AC97: Closing PCM IN\n")); … … 521 701 522 702 case PO_INDEX: 523 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER524 for (uint32_t lun = 0; lun < 2; lun++)525 {526 pThis->pDrv[lun]->pfnCloseOut(pThis->pDrv[lun], pThis->voice_po[lun]);527 pThis->voice_po[lun] = NULL;528 }529 #else530 703 AUD_close_out(&pThis->card, pThis->voice_po); 531 704 pThis->voice_po = NULL; 532 #endif533 705 #ifdef LOG_VOICES 534 706 LogRel(("AC97: Closing PCM OUT\n")); … … 537 709 538 710 case MC_INDEX: 539 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER540 for (uint32_t lun = 0; lun < 2; lun++)541 {542 pThis->pDrv[lun]->pfnCloseIn(pThis->pDrv[lun], pThis->voice_mc[lun]);543 pThis->voice_mc[lun] = NULL;544 }545 #else546 711 AUD_close_in(&pThis->card, pThis->voice_mc); 547 712 pThis->voice_mc = NULL; 548 #endif549 713 #ifdef LOG_VOICES 550 714 LogRel(("AC97: Closing MIC IN\n")); … … 552 716 break; 553 717 } 554 } 555 } 556 557 static void reset_voices(PAC97STATE pThis, uint8_t active[LAST_INDEX]) 558 { 559 uint16_t freq; 560 561 freq = mixer_load(pThis, AC97_PCM_LR_ADC_Rate); 562 open_voice(pThis, PI_INDEX, freq); 563 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 564 for (uint32_t lun = 0; lun < 2; lun++) 565 pThis->pDrv[lun]->pfnEnableIn(pThis->pDrv[lun], pThis->voice_pi[lun], active[PI_INDEX]); 718 719 rc = VINF_SUCCESS; 720 } 721 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 722 723 LogFlowFuncLeaveRC(rc); 724 } 725 726 /** @todo r=andy D'oh, pretty bad argument handling -- fix this! */ 727 static void ichac97ResetStreams(PAC97STATE pThis, uint8_t active[LAST_INDEX]) 728 { 729 uint16_t uFreq = ichac97MixerLoad(pThis, AC97_PCM_LR_ADC_Rate); 730 bool fEnable = RT_BOOL(active[PI_INDEX]); 731 LogFlowFunc(("Input ADC uFreq=%RU16, fEnabled=%RTbool\n", uFreq, fEnable)); 732 733 ichac97OpenStream(pThis, PI_INDEX, uFreq); 734 735 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 736 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 737 pThis->paDrv[lun]->pConnector->pfnEnableIn(pThis->paDrv[lun]->pConnector, 738 pThis->paDrv[lun]->pStrmIn, fEnable); 566 739 #else 567 740 AUD_set_active_in(pThis->voice_pi, active[PI_INDEX]); 568 #endif 569 freq = mixer_load(pThis, AC97_PCM_Front_DAC_Rate); 570 LogFlow(("DevIchAC97: reset_voices calling open_voice freq = %d\n", freq)); 571 open_voice(pThis, PO_INDEX, freq); 572 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 573 for (uint32_t lun = 0; lun < 2; lun++) 574 pThis->pDrv[lun]->pfnEnableOut(pThis->pDrv[lun], pThis->voice_po[lun], active[PO_INDEX]); 741 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 742 743 uFreq = ichac97MixerLoad(pThis, AC97_PCM_Front_DAC_Rate); 744 fEnable = RT_BOOL(active[PO_INDEX]); 745 LogFlowFunc(("Output DAC uFreq=%RU16, fEnabled=%RTbool\n", uFreq, fEnable)); 746 747 ichac97OpenStream(pThis, PO_INDEX, uFreq); 748 749 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 750 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 751 pThis->paDrv[lun]->pConnector->pfnEnableOut(pThis->paDrv[lun]->pConnector, 752 pThis->paDrv[lun]->pStrmOut, fEnable); 575 753 #else 576 754 AUD_set_active_out(pThis->voice_po, active[PO_INDEX]); 577 #endif 578 579 freq = mixer_load(pThis, AC97_MIC_ADC_Rate); 580 open_voice(pThis, MC_INDEX, freq); 581 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 582 for (uint32_t lun = 0; lun < 2; lun++) 583 pThis->pDrv[lun]->pfnEnableIn(pThis->pDrv[lun], pThis->voice_mc[lun], active[MC_INDEX]); 584 #else 585 AUD_set_active_in(pThis->voice_mc, active[MC_INDEX]); 586 #endif 755 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 756 757 uFreq = ichac97MixerLoad(pThis, AC97_MIC_ADC_Rate); 758 fEnable = RT_BOOL(active[MC_INDEX]); 759 LogFlowFunc(("Mic ADC uFreq=%RU16, fEnabled=%RTbool\n", uFreq, fEnable)); 760 761 ichac97OpenStream(pThis, MC_INDEX, uFreq); 762 763 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 764 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 765 pThis->paDrv[lun]->pConnector->pfnEnableIn(pThis->paDrv[lun]->pConnector, 766 pThis->paDrv[lun]->pStrmMic, fEnable); 767 #else 768 AUD_set_active_in(pThis->voice_mc, active[MC_INDEX]); 769 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 587 770 } 588 771 589 772 #ifdef USE_MIXER 590 773 591 static void set_volume(PAC97STATE pThis, int index, audmixerctl_t mt, uint32_t val) 774 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 775 static void ichac97SetVolume(PAC97STATE pThis, int index, PDMAUDIOMIXERCTL mt, uint32_t val) 776 #else 777 static void ichac97SetVolume(PAC97STATE pThis, int index, audmixerctl_t mt, uint32_t val) 778 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 592 779 { 593 780 int mute = (val >> MUTE_SHIFT) & 1; … … 597 784 lvol = 255 * lvol / VOL_MASK; 598 785 599 # 786 #ifdef SOFT_VOLUME 600 787 if (index == AC97_Master_Volume_Mute) 601 788 { 602 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER 603 for (uint32_t lun = 0; lun < 1; lun++) 604 pThis->pDrv[lun]->pfnIsSetOutVolume(pThis->pDrv[lun], pThis->voice_po[lun], mute, lvol, rvol); 605 # else 789 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER 790 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 791 { 792 pThis->paDrv[lun]->pConnector->pfnIsSetOutVolume(pThis->paDrv[lun]->pConnector, 793 pThis->paDrv[lun]->pStrmOut, 794 RT_BOOL(mute), lvol, rvol); 795 } 796 # else 606 797 AUD_set_volume_out(pThis->voice_po, mute, lvol, rvol); 607 # endif798 # endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 608 799 } 609 800 else 610 801 { 611 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER 612 for (uint32_t lun = 0; lun < 1; lun++) 613 /* @tod0 in SetVolume no passing audmixerctl_in as its not used in DrvAudio.c */ 614 pThis->pDrv[lun]->pfnSetVolume(pThis->pDrv[lun], &mute, &lvol, &rvol); 615 # else 802 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER 803 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 804 { 805 /** @todo In SetVolume no passing audmixerctl_in as its not used in DrvAudio.c */ 806 pThis->paDrv[lun]->pConnector->pfnSetVolume(pThis->paDrv[lun]->pConnector, 807 RT_BOOL(mute), lvol, rvol); 808 } 809 # else 616 810 AUD_set_volume(mt, &mute, &lvol, &rvol); 617 # endif 618 } 811 # endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 812 } 813 #else /* !SOFT_VOLUME */ 814 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER 815 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 816 pThis->paDrv[lun]->pConnector->pfnSetVolume(pThis->paDrv[lun]->pConnector, 817 RT_BOOL(mute), lvol, rvol); 619 818 # else 620 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER621 for (uint32_t lun = 0; lun < 1; lun++)622 pThis->pDrv[lun]->pfnSetVolume(pThis->pDrv[lun], &mute, &lvol, &rvol);623 # else624 819 AUD_set_volume(mt, &mute, &lvol, &rvol); 625 # endif626 # endif820 # endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 821 #endif /* SOFT_VOLUME */ 627 822 628 823 rvol = VOL_MASK - ((VOL_MASK * rvol) / 255); … … 642 837 val |= RT_BIT(12) | RT_BIT(11) | RT_BIT(10) | RT_BIT(9) | RT_BIT(8); 643 838 644 mixer_store(pThis, index, val);645 } 646 647 static audrecsource_t ac97_to_aud_record_source(uint8_t i)839 ichac97MixerStore(pThis, index, val); 840 } 841 842 static PDMAUDIORECSOURCE ichac97IndextoRecSource(uint8_t i) 648 843 { 649 844 switch (i) 650 845 { 651 case REC_MIC: return AUD_REC_MIC;652 case REC_CD: return AUD_REC_CD;653 case REC_VIDEO: return AUD_REC_VIDEO;654 case REC_AUX: return AUD_REC_AUX;655 case REC_LINE_IN: return AUD_REC_LINE_IN;656 case REC_PHONE: return AUD_REC_PHONE;846 case REC_MIC: return PDMAUDIORECSOURCE_MIC; 847 case REC_CD: return PDMAUDIORECSOURCE_CD; 848 case REC_VIDEO: return PDMAUDIORECSOURCE_VIDEO; 849 case REC_AUX: return PDMAUDIORECSOURCE_AUX; 850 case REC_LINE_IN: return PDMAUDIORECSOURCE_LINE_IN; 851 case REC_PHONE: return PDMAUDIORECSOURCE_PHONE; 657 852 default: 658 Log(("ac97: Unknown record source %d, using MIC\n", i)); 659 return AUD_REC_MIC; 660 } 661 } 662 663 static uint8_t aud_to_ac97_record_source(audrecsource_t rs) 853 break; 854 } 855 856 LogFlowFunc(("Unknown record source %d, using MIC\n", i)); 857 return PDMAUDIORECSOURCE_MIC; 858 } 859 860 static uint8_t ichac97RecSourceToIndex(PDMAUDIORECSOURCE rs) 664 861 { 665 862 switch (rs) 666 863 { 667 case AUD_REC_MIC: return REC_MIC;668 case AUD_REC_CD: return REC_CD;669 case AUD_REC_VIDEO: return REC_VIDEO;670 case AUD_REC_AUX: return REC_AUX;671 case AUD_REC_LINE_IN: return REC_LINE_IN;672 case AUD_REC_PHONE: return REC_PHONE;864 case PDMAUDIORECSOURCE_MIC: return REC_MIC; 865 case PDMAUDIORECSOURCE_CD: return REC_CD; 866 case PDMAUDIORECSOURCE_VIDEO: return REC_VIDEO; 867 case PDMAUDIORECSOURCE_AUX: return REC_AUX; 868 case PDMAUDIORECSOURCE_LINE_IN: return REC_LINE_IN; 869 case PDMAUDIORECSOURCE_PHONE: return REC_PHONE; 673 870 default: 674 Log(("ac97: Unknown audio recording source %d using MIC\n", rs)); 675 return REC_MIC; 676 } 677 } 678 679 static void record_select(PAC97STATE pThis, uint32_t val) 871 break; 872 } 873 874 LogFlowFunc(("Unknown audio recording source %d using MIC\n", rs)); 875 return REC_MIC; 876 } 877 878 static void ichac97RecordSelect(PAC97STATE pThis, uint32_t val) 680 879 { 681 880 uint8_t rs = val & REC_MASK; 682 881 uint8_t ls = (val >> 8) & REC_MASK; 683 audrecsource_t ars = ac97_to_aud_record_source(rs);684 audrecsource_t als = ac97_to_aud_record_source(ls);882 PDMAUDIORECSOURCE ars = ichac97IndextoRecSource(rs); 883 PDMAUDIORECSOURCE als = ichac97IndextoRecSource(ls); 685 884 //AUD_set_record_source(&als, &ars); 686 rs = aud_to_ac97_record_source(ars);687 ls = aud_to_ac97_record_source(als);688 mixer_store(pThis, AC97_Record_Select, rs | (ls << 8));885 rs = ichac97RecSourceToIndex(ars); 886 ls = ichac97RecSourceToIndex(als); 887 ichac97MixerStore(pThis, AC97_Record_Select, rs | (ls << 8)); 689 888 } 690 889 691 890 #endif /* USE_MIXER */ 692 891 693 static void mixer_reset(PAC97STATE pThis) 694 { 695 uint8_t active[LAST_INDEX]; 696 697 Log(("ac97: mixer_reset\n")); 698 memset(pThis->mixer_data, 0, sizeof(pThis->mixer_data)); 699 memset(active, 0, sizeof(active)); 700 mixer_store(pThis, AC97_Reset , 0x0000); /* 6940 */ 701 mixer_store(pThis, AC97_Master_Volume_Mono_Mute , 0x8000); 702 mixer_store(pThis, AC97_PC_BEEP_Volume_Mute , 0x0000); 703 704 mixer_store(pThis, AC97_Phone_Volume_Mute , 0x8008); 705 mixer_store(pThis, AC97_Mic_Volume_Mute , 0x8008); 706 mixer_store(pThis, AC97_CD_Volume_Mute , 0x8808); 707 mixer_store(pThis, AC97_Aux_Volume_Mute , 0x8808); 708 mixer_store(pThis, AC97_Record_Gain_Mic_Mute , 0x8000); 709 mixer_store(pThis, AC97_General_Purpose , 0x0000); 710 mixer_store(pThis, AC97_3D_Control , 0x0000); 711 mixer_store(pThis, AC97_Powerdown_Ctrl_Stat , 0x000f); 892 static void ichac97MixerReset(PAC97STATE pThis) 893 { 894 LogFlowFuncEnter(); 895 896 RT_ZERO(pThis->mixer_data); 897 898 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 899 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 900 { 901 pThis->paDrv[lun]->phStrmIn = NULL; 902 pThis->paDrv[lun]->phStrmMic = NULL; 903 } 904 905 pThis->pSinkLineIn = NULL; 906 pThis->pSinkMicIn = NULL; 907 908 if (pThis->pMixer) 909 { 910 audioMixerDestroy(pThis->pMixer); 911 pThis->pMixer = NULL; 912 } 913 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 914 915 ichac97MixerStore(pThis, AC97_Reset , 0x0000); /* 6940 */ 916 ichac97MixerStore(pThis, AC97_Master_Volume_Mono_Mute , 0x8000); 917 ichac97MixerStore(pThis, AC97_PC_BEEP_Volume_Mute , 0x0000); 918 919 ichac97MixerStore(pThis, AC97_Phone_Volume_Mute , 0x8008); 920 ichac97MixerStore(pThis, AC97_Mic_Volume_Mute , 0x8008); 921 ichac97MixerStore(pThis, AC97_CD_Volume_Mute , 0x8808); 922 ichac97MixerStore(pThis, AC97_Aux_Volume_Mute , 0x8808); 923 ichac97MixerStore(pThis, AC97_Record_Gain_Mic_Mute , 0x8000); 924 ichac97MixerStore(pThis, AC97_General_Purpose , 0x0000); 925 ichac97MixerStore(pThis, AC97_3D_Control , 0x0000); 926 ichac97MixerStore(pThis, AC97_Powerdown_Ctrl_Stat , 0x000f); 712 927 713 928 /* 714 929 * Sigmatel 9700 (STAC9700) 715 930 */ 716 mixer_store(pThis, AC97_Vendor_ID1 , 0x8384); 717 mixer_store(pThis, AC97_Vendor_ID2 , 0x7600); /* 7608 */ 718 719 mixer_store(pThis, AC97_Extended_Audio_ID , 0x0809); 720 mixer_store(pThis, AC97_Extended_Audio_Ctrl_Stat, 0x0009); 721 mixer_store(pThis, AC97_PCM_Front_DAC_Rate , 0xbb80); 722 mixer_store(pThis, AC97_PCM_Surround_DAC_Rate , 0xbb80); 723 mixer_store(pThis, AC97_PCM_LFE_DAC_Rate , 0xbb80); 724 mixer_store(pThis, AC97_PCM_LR_ADC_Rate , 0xbb80); 725 mixer_store(pThis, AC97_MIC_ADC_Rate , 0xbb80); 726 727 931 ichac97MixerStore(pThis, AC97_Vendor_ID1 , 0x8384); 932 ichac97MixerStore(pThis, AC97_Vendor_ID2 , 0x7600); /* 7608 */ 933 934 ichac97MixerStore(pThis, AC97_Extended_Audio_ID , 0x0809); 935 ichac97MixerStore(pThis, AC97_Extended_Audio_Ctrl_Stat, 0x0009); 936 ichac97MixerStore(pThis, AC97_PCM_Front_DAC_Rate , 0xbb80); 937 ichac97MixerStore(pThis, AC97_PCM_Surround_DAC_Rate , 0xbb80); 938 ichac97MixerStore(pThis, AC97_PCM_LFE_DAC_Rate , 0xbb80); 939 ichac97MixerStore(pThis, AC97_PCM_LR_ADC_Rate , 0xbb80); 940 ichac97MixerStore(pThis, AC97_MIC_ADC_Rate , 0xbb80); 728 941 729 942 #ifdef USE_MIXER 730 record_select(pThis, 0); 731 set_volume(pThis, AC97_Master_Volume_Mute, AUD_MIXER_VOLUME, 0x8000); 732 set_volume(pThis, AC97_PCM_Out_Volume_Mute, AUD_MIXER_PCM, 0x8808); 733 set_volume(pThis, AC97_Line_In_Volume_Mute, AUD_MIXER_LINE_IN, 0x8808); 734 #else 735 mixer_store(pThis, AC97_Record_Select, 0); 736 mixer_store(pThis, AC97_Master_Volume_Mute, 0x8000); 737 mixer_store(pThis, AC97_PCM_Out_Volume_Mute, 0x8808); 738 mixer_store(pThis, AC97_Line_In_Volume_Mute, 0x8808); 943 ichac97RecordSelect(pThis, 0); 944 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER 945 ichac97SetVolume(pThis, AC97_Master_Volume_Mute, PDMAUDIOMIXERCTL_VOLUME, 0x8000); 946 ichac97SetVolume(pThis, AC97_PCM_Out_Volume_Mute, PDMAUDIOMIXERCTL_PCM, 0x8808); 947 ichac97SetVolume(pThis, AC97_Line_In_Volume_Mute, PDMAUDIOMIXERCTL_LINE_IN, 0x8808); 948 # else 949 ichac97SetVolume(pThis, AC97_Master_Volume_Mute, AUD_MIXER_VOLUME, 0x8000); 950 ichac97SetVolume(pThis, AC97_PCM_Out_Volume_Mute, AUD_MIXER_PCM, 0x8808); 951 ichac97SetVolume(pThis, AC97_Line_In_Volume_Mute, AUD_MIXER_LINE_IN, 0x8808); 952 # endif 953 #else 954 ichac97MixerStore(pThis, AC97_Record_Select, 0); 955 ichac97MixerStore(pThis, AC97_Master_Volume_Mute, 0x8000); 956 ichac97MixerStore(pThis, AC97_PCM_Out_Volume_Mute, 0x8808); 957 ichac97MixerStore(pThis, AC97_Line_In_Volume_Mute, 0x8808); 739 958 #endif 740 959 741 reset_voices(pThis, active); 742 } 743 744 static int write_audio(PAC97STATE pThis, PAC97BMREG pReg, int max, int *stop) 960 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 961 int rc2 = audioMixerCreate("AC'97 Mixer", 0 /* uFlags */, 962 &pThis->pMixer); 963 if (RT_SUCCESS(rc2)) 964 { 965 PDMAUDIOSTREAMCFG streamCfg; 966 streamCfg.uHz = 48000; 967 streamCfg.cChannels = 2; 968 streamCfg.enmFormat = AUD_FMT_S16; 969 streamCfg.enmEndianness = PDMAUDIOHOSTENDIANESS; 970 971 rc2 = audioMixerSetDeviceFormat(pThis->pMixer, &streamCfg); 972 AssertRC(rc2); 973 974 /* Add all required audio sinks. */ 975 rc2 = audioMixerAddSink(pThis->pMixer, "[Recording] Line In", 976 &pThis->pSinkLineIn); 977 AssertRC(rc2); 978 979 rc2 = audioMixerAddSink(pThis->pMixer, "[Recording] Microphone In", 980 &pThis->pSinkMicIn); 981 AssertRC(rc2); 982 } 983 #endif 984 985 /* Reset all streams. */ 986 uint8_t active[LAST_INDEX] = { 0 }; 987 ichac97ResetStreams(pThis, active); 988 } 989 990 static int ichac97WriteAudio(PAC97STATE pThis, PAC97BMREG pReg, int max, int *stop) 745 991 { 746 992 PPDMDEVINS pDevIns = ICHAC97STATE_2_DEVINS(pThis); 747 uint8_t tmpbuf[4096]; 993 994 uint8_t tmpbuf[_4K]; 748 995 uint32_t addr = pReg->bd.addr; 749 uint32_t temp = pReg->picb << 1;750 996 uint32_t written = 0; 751 int to_copy = 0; 752 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 753 /* count of bytes left in buf to read = samples left in buffer (each of 16 bit) to read denoted by picb * 2) */ 754 uint32_t cbToRead = pReg->picb << 1; 755 uint32_t cbMinToRead; 756 uint8_t tmpbufCopy[4096]; 757 int lun = 0; 758 uint32_t slowestLun; 759 uint32_t cSamplesLeft; 760 #endif 761 762 temp = audio_MIN(temp, (uint32_t)max); 997 uint32_t to_copy = 0; 998 999 uint32_t temp = RT_MIN((pReg->picb << 1), (uint32_t)max); 763 1000 if (!temp) 764 1001 { … … 767 1004 } 768 1005 1006 int rc = VINF_SUCCESS; 1007 769 1008 while (temp) 770 1009 { 771 int copied; 772 to_copy = audio_MIN(temp, sizeof(tmpbuf)); 773 PDMDevHlpPhysRead(pDevIns, addr, tmpbuf, to_copy); 774 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 775 /* save a copy of the audio samples read */ 776 memcpy(tmpbufCopy, tmpbuf, to_copy); 777 uint32_t slowlun = 0; 778 for (lun = 0; lun < 2; lun++) 779 { 780 LogFlow(("DevIchAC97: write_audio to_copy = %d LUN##%d\n", to_copy, lun)); 781 copied = pThis->pDrv[lun]->pfnWrite(pThis->pDrv[lun], pThis->voice_po[lun], tmpbuf, to_copy); 782 /* call pfnwrite with the same data that has been read from the guest physical memory */ 783 LogFlow(("DevIchAC97: write_audio copied = %d\n", copied)); 784 } 1010 uint32_t copied; 1011 to_copy = RT_MIN(temp, sizeof(tmpbuf)); 1012 PDMDevHlpPhysRead(pDevIns, addr, tmpbuf, to_copy); /** @todo Check rc? */ 1013 1014 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1015 # ifdef DEBUG_LUN 1016 uint8_t lun = DEBUG_LUN_NUM; 1017 # else 1018 /* Just multiplex the output to the connected backends. 1019 * No need to utilize the virtual mixer here (yet). */ 1020 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 1021 { 1022 # endif 1023 rc = pThis->paDrv[lun]->pConnector->pfnWrite(pThis->paDrv[lun]->pConnector, 1024 pThis->paDrv[lun]->pStrmOut, 1025 tmpbuf, to_copy, &copied); 1026 if (RT_FAILURE(rc)) 1027 continue; 1028 # ifndef DEBUG_LUN 1029 } 1030 # endif 785 1031 #else 786 1032 copied = AUD_write(pThis->voice_po, tmpbuf, to_copy); 787 #endif 1033 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1034 LogRelFunc(("to_copy=%RU32, copied=%RU32, temp=%RU32, temp_left=%RU32\n", to_copy, copied, 1035 temp, temp - copied)); 1036 788 1037 if (!copied) 789 1038 { … … 800 1049 if (to_copy < 4) 801 1050 { 802 Log (("ac97:whoops\n"));1051 LogFlowFunc(("whoops\n")); 803 1052 pThis->last_samp = 0; 804 1053 } … … 808 1057 809 1058 pReg->bd.addr = addr; 1059 1060 LogRelFunc(("written=%RU32\n", written)); 810 1061 return written; 811 1062 } 812 1063 813 static void write_bup(PAC97STATE pThis, int elapsed) 814 { 815 int written = 0; 816 Log(("ac97: write_bup\n")); 1064 static void ichac97WriteBUP(PAC97STATE pThis, int elapsed) 1065 { 817 1066 if (!(pThis->bup_flag & BUP_SET)) 818 1067 { … … 825 1074 } 826 1075 else 827 memset(pThis->silence, 0, sizeof(pThis->silence));1076 RT_ZERO(pThis->silence); 828 1077 829 1078 pThis->bup_flag |= BUP_SET; 830 1079 } 831 1080 1081 int written = 0; 1082 832 1083 while (elapsed) 833 1084 { 834 unsigned int temp = audio_MIN((unsigned int)elapsed, sizeof(pThis->silence));835 int copied;1085 unsigned int temp = RT_MIN((unsigned int)elapsed, sizeof(pThis->silence)); 1086 uint32_t copied; 836 1087 while (temp) 837 1088 { 838 1089 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 839 for (int lun = 0; lun < 2; lun++) 1090 # ifdef DEBUG_LUN 1091 uint8_t lun = DEBUG_LUN_NUM; 1092 # else 1093 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 840 1094 { 841 LogFlow(("DevIchAC97: write_silence LUN##%d , to_copy=%d\n", lun, temp)); 842 copied = pThis->pDrv[lun]->pfnWrite(pThis->pDrv[lun], pThis->voice_po[lun], pThis->silence, temp); 843 LogFlow(("DevIchAC97: write_silence LUN##%d , copied=%d\n", lun, copied)); 1095 # endif 1096 int rc2 = pThis->paDrv[lun]->pConnector->pfnWrite(pThis->paDrv[lun]->pConnector, 1097 pThis->paDrv[lun]->pStrmOut, 1098 pThis->silence, temp, &copied); 1099 if (RT_FAILURE(rc2)) 1100 continue; 1101 # ifndef DEBUG_LUN 844 1102 } 1103 # endif 845 1104 #else 846 1105 copied = AUD_write(pThis->voice_po, pThis->silence, temp); 847 #endif 1106 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1107 848 1108 if (!copied) 849 1109 return; … … 855 1115 } 856 1116 857 static int read_audio(PAC97STATE pThis, PAC97BMREG pReg, int max, int *stop)1117 static int ichac97ReadAudio(PAC97STATE pThis, PAC97BMREG pReg, int max, int *stop) 858 1118 { 859 1119 PPDMDEVINS pDevIns = ICHAC97STATE_2_DEVINS(pThis); 860 1120 1121 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1122 /* Select audio sink to process. */ 1123 PAUDMIXSINK pSink = (pReg - pThis->bm_regs) == MC_INDEX 1124 ? pThis->pSinkMicIn : pThis->pSinkLineIn; 1125 AssertPtr(pSink); 1126 1127 int rc; 1128 uint32_t cbRead; 1129 1130 size_t cbMixBuf = max * sizeof(uint8_t); 1131 Assert(cbMixBuf); 1132 uint32_t cbToRead = RT_MIN(pReg->picb << 1, cbMixBuf); 1133 1134 uint8_t *pvMixBuf = (uint8_t *)RTMemAlloc(cbMixBuf); 1135 if (pvMixBuf) 1136 { 1137 rc = audioMixerProcessSinkIn(pSink, pvMixBuf, cbToRead, &cbRead); 1138 if ( RT_SUCCESS(rc) 1139 && cbRead) 1140 { 1141 PDMDevHlpPCIPhysWrite(pDevIns, pReg->bd.addr, pvMixBuf, cbRead); 1142 pReg->bd.addr += cbRead; 1143 } 1144 else 1145 *stop = 1; 1146 1147 RTMemFree(pvMixBuf); 1148 } 1149 else 1150 *stop = 1; 1151 1152 if (*stop) 1153 cbRead = 0; 1154 1155 return cbRead; 1156 #else 861 1157 uint32_t addr = pReg->bd.addr; 862 1158 uint32_t temp = pReg->picb << 1; 863 1159 uint32_t nread = 0; 864 1160 int to_copy = 0; 865 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 866 uint8_t u8DupBuf[4096]; 867 PDMHOSTSTEREOSAMPLE tmpbuf[4096]; 868 PDMHOSTSTEREOSAMPLE MixBuf[2000]; 869 PDMHOSTSTEREOSAMPLE InputBuf[2000]; 870 PPDMHOSTSTEREOSAMPLE SrcBuf; 871 uint32_t cSamplesMixed = 0; 872 uint32_t cTotalSamplesMixed = 0; 873 uint32_t cSamplesRead = 0; 874 uint32_t offRead = 0; 875 uint32_t offWrite = 0; 876 uint32_t cTotalSamplesRead = 0; 877 uint32_t isamp = 0, osamp = 0; 878 uint32_t lun =0; 879 PPDMGSTVOICEIN voice[2]; 880 memset(MixBuf, 0, sizeof(MixBuf)); 881 memset(InputBuf, 0, sizeof(InputBuf)); 882 memset(u8DupBuf, 0, sizeof(u8DupBuf)); 883 void * rate[2]; 884 885 for (lun = 0; lun < 2; lun++) 886 voice[lun] = (pReg - pThis->bm_regs) == MC_INDEX ? pThis->voice_mc[lun] : pThis->voice_pi[lun]; 887 #else 1161 888 1162 SWVoiceIn *voice = (pReg - pThis->bm_regs) == MC_INDEX ? pThis->voice_mc : pThis->voice_pi; 889 #endif890 1163 891 1164 temp = audio_MIN(temp, (uint32_t)max); … … 896 1169 } 897 1170 898 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER899 rate[0] = pThis->pDrv[0]->pfnPrepareAudioConversion(pThis->pDrv[0], 48000, 48000);900 //rate[1] = pThis->pDrv[1]->pfnPrepareAudioConversion(pThis->pDrv[1], 22100, 22100);901 rate[1] = pThis->pDrv[1]->pfnPrepareAudioConversion(pThis->pDrv[1], 48000, 48000);902 for (lun = 0; lun < 2; lun++)903 {904 temp = pReg->picb << 1;905 temp = audio_MIN(temp, (uint32_t)max);906 LogFlow(("DevIchAC97: temp = %d and max = %d\n", temp, max));907 if (!temp)908 {909 *stop = 1;910 return 0;911 }912 memset(tmpbuf, 0, sizeof(tmpbuf));913 offRead = 0;914 offWrite = 0;915 cSamplesMixed = 0;916 nread = 0;917 while (temp)918 {919 int acquired;920 to_copy = audio_MIN(temp, sizeof(tmpbuf));921 acquired = pThis->pDrv[lun]->pfnRead(pThis->pDrv[lun], voice[lun], tmpbuf, to_copy);922 cSamplesRead = acquired >> voice[lun]->Props.cShift;923 while (cSamplesRead)924 {925 SrcBuf = tmpbuf + offRead;926 isamp = cSamplesRead;927 if (!isamp)928 {929 LogFlow(("DevichAC97: No Input samples \n"));930 break;931 }932 osamp = cSamplesRead - cSamplesMixed; /*sizeof(MixBuf)*/;933 pThis->pDrv[lun]->pfnDoRateConvAndMix(pThis->pDrv[lun], rate[lun], SrcBuf,934 MixBuf, &isamp, &osamp);935 cSamplesRead -= isamp;936 offRead += isamp;937 offWrite += osamp;938 cSamplesMixed += isamp;939 }940 if (!acquired)941 {942 *stop = 1;943 break;944 }945 pThis->pDrv[lun]->pfnConvStSampleToDevFmt(pThis->pDrv[lun], u8DupBuf, MixBuf, cSamplesMixed);946 temp -= acquired;947 //addr += acquired;948 //addr += (ctotalSamplexMixed << voice->Props.cShift);949 //nread += (cSamplesMixed << voice->Props.cShift);950 nread += acquired;951 LogFlow(("DevIchAC97: looping temp = %d\n", temp));952 cTotalSamplesRead = audio_MAX(cTotalSamplesRead, nread);953 cTotalSamplesMixed = audio_MAX(cTotalSamplesMixed, cSamplesMixed);954 }955 }956 if (cTotalSamplesMixed)957 PDMDevHlpPCIPhysWrite(pDevIns, addr, u8DupBuf, (cTotalSamplesMixed << voice[0]->Props.cShift));958 addr += (cTotalSamplesMixed << voice[0]->Props.cShift);959 nread = cTotalSamplesRead;960 #else961 1171 uint8_t tmpbuf[4096]; 962 1172 while (temp) … … 975 1185 nread += acquired; 976 1186 } 977 #endif 1187 978 1188 pReg->bd.addr = addr; 979 1189 return nread; 980 } 981 982 static void transfer_audio(PAC97STATE pThis, int index, int elapsed) 983 { 1190 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1191 } 1192 1193 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1194 static void ichac97TransferAudio(PAC97DRIVER pDrv, int index, int elapsed) 1195 #else 1196 static void ichac97TransferAudio(PAC97STATE pThis, int index, int elapsed) 1197 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1198 { 1199 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1200 PAC97STATE pThis = pDrv->pAC97State; 1201 1202 if (pDrv->uLUN != 0) /* Only LUN 0 can write and read from the device. */ 1203 return; 1204 /** @todo Fix this limitation by implementing a virtual mixer. */ 1205 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1206 984 1207 PAC97BMREG pReg = &pThis->bm_regs[index]; 985 int written = 0; 986 int stop = 0; 987 988 if (pReg->sr & SR_DCH) 1208 if (pReg->sr & SR_DCH) /* Controller halted? */ 989 1209 { 990 1210 if (pReg->cr & CR_RPBM) … … 993 1213 { 994 1214 case PO_INDEX: 995 write_bup(pThis, elapsed); 1215 ichac97WriteBUP(pThis, elapsed); 1216 break; 1217 1218 default: 996 1219 break; 997 1220 } 998 1221 } 1222 999 1223 return; 1000 1224 } 1001 1225 1226 int written = 0; 1227 int stop = 0; 1228 1002 1229 while ((elapsed >> 1) && !stop) 1003 1230 { … … 1006 1233 if (!pReg->bd_valid) 1007 1234 { 1008 Log(("ac97: invalid bd\n")); 1009 fetch_bd(pThis, pReg); 1010 } 1011 1012 if (!pReg->picb) 1013 { 1014 Log(("ac97: fresh bd %d is empty %#x %#x, skipping\n", pReg->civ, pReg->bd.addr, pReg->bd.ctl_len)); 1235 LogFlowFunc(("Invalid buffer descriptor, fetching next one ...\n")); 1236 ichac97FetchBufDesc(pThis, pReg); 1237 } 1238 1239 if (!pReg->picb) /* Got a new buffer descriptor, that is, the position is 0? */ 1240 { 1241 LogFlowFunc(("Fresh buffer descriptor %d is empty, addr=%#x, len=%#x, skipping\n", 1242 pReg->civ, pReg->bd.addr, pReg->bd.ctl_len)); 1015 1243 if (pReg->civ == pReg->lvi) 1016 1244 { … … 1019 1247 break; 1020 1248 } 1249 1021 1250 pReg->sr &= ~SR_CELV; 1022 1251 pReg->civ = pReg->piv; 1023 1252 pReg->piv = (pReg->piv + 1) % 32; 1024 fetch_bd(pThis, pReg); 1253 1254 ichac97FetchBufDesc(pThis, pReg); 1025 1255 continue; 1026 1256 } … … 1029 1259 { 1030 1260 case PO_INDEX: 1031 temp = write_audio(pThis, pReg, elapsed, &stop);1261 temp = ichac97WriteAudio(pThis, pReg, elapsed, &stop); 1032 1262 written += temp; 1033 1263 elapsed -= temp; … … 1038 1268 case PI_INDEX: 1039 1269 case MC_INDEX: 1040 temp = read_audio(pThis, pReg, elapsed, &stop);1270 temp = ichac97ReadAudio(pThis, pReg, elapsed, &stop); 1041 1271 elapsed -= temp; 1042 1272 Assert((temp & 1) == 0); /* Else the following shift won't work */ 1043 1273 pReg->picb -= (temp >> 1); 1044 1274 break; 1045 } 1046 Log(("pReg->picb = %d\n", pReg->picb)); 1275 1276 default: 1277 AssertMsgFailed(("Index %d not supported\n", index)); 1278 break; 1279 } 1280 LogFlowFunc(("pReg->picb = %d\n", pReg->picb)); 1047 1281 1048 1282 if (!pReg->picb) … … 1057 1291 if (pReg->civ == pReg->lvi) 1058 1292 { 1059 Log (("ac97:Underrun civ (%d) == lvi (%d)\n", pReg->civ, pReg->lvi));1293 LogFlowFunc(("Underrun civ (%d) == lvi (%d)\n", pReg->civ, pReg->lvi)); 1060 1294 new_sr |= SR_LVBCI | SR_DCH | SR_CELV; 1061 1295 stop = 1; … … 1066 1300 pReg->civ = pReg->piv; 1067 1301 pReg->piv = (pReg->piv + 1) % 32; 1068 fetch_bd(pThis, pReg);1302 ichac97FetchBufDesc(pThis, pReg); 1069 1303 } 1070 update_sr(pThis, pReg, new_sr); 1071 } 1072 } 1073 } 1074 1075 static void pi_callback(void *opaque, int avail) 1076 { 1077 transfer_audio((AC97STATE *)opaque, PI_INDEX, avail); 1078 } 1079 1080 static void mc_callback(void *opaque, int avail) 1081 { 1082 transfer_audio((AC97STATE *)opaque, MC_INDEX, avail); 1083 } 1084 1085 static void po_callback(void *opaque, int free) 1086 { 1087 transfer_audio((AC97STATE *)opaque, PO_INDEX, free); 1088 } 1304 1305 ichac97UpdateStatus(pThis, pReg, new_sr); 1306 } 1307 } 1308 } 1309 1310 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1311 static void ichac97InputCallback(void *pvContext, uint32_t cbAvail) 1312 { 1313 PAC97DRIVER pThis = (PAC97DRIVER)pvContext; 1314 ichac97TransferAudio(pThis, PI_INDEX, cbAvail); 1315 } 1316 #else 1317 static void ichac97InputCallback(void *pvContext, int cbAvail) 1318 { 1319 ichac97TransferAudio((AC97STATE *)pvContext, PI_INDEX, cbAvail); 1320 } 1321 #endif 1322 1323 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1324 static void ichac97MicInCallback(void *pvContext, uint32_t cbAvail) 1325 { 1326 PAC97DRIVER pThis = (PAC97DRIVER)pvContext; 1327 ichac97TransferAudio(pThis, MC_INDEX, cbAvail); 1328 } 1329 #else 1330 static void ichac97MicInCallback(void *pvContext, int cbAvail) 1331 { 1332 ichac97TransferAudio((AC97STATE *)pvContext, MC_INDEX, cbAvail); 1333 } 1334 #endif 1335 1336 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1337 static void ichac97OutputCallback(void *pvContext, uint32_t cbFree) 1338 { 1339 PAC97DRIVER pThis = (PAC97DRIVER)pvContext; 1340 ichac97TransferAudio(pThis, PO_INDEX, cbFree); 1341 } 1342 #else 1343 static void ichac97OutputCallback(void *pvContext, int cbFree) 1344 { 1345 ichac97TransferAudio((AC97STATE *)pvContext, PO_INDEX, cbFree); 1346 } 1347 #endif 1089 1348 1090 1349 /** … … 1107 1366 case CAS: 1108 1367 /* Codec Access Semaphore Register */ 1109 Log (("ac97:CAS %d\n", pThis->cas));1368 LogFlowFunc(("CAS %d\n", pThis->cas)); 1110 1369 *pu32 = pThis->cas; 1111 1370 pThis->cas = 1; … … 1117 1376 pReg = &pThis->bm_regs[GET_BM(index)]; 1118 1377 *pu32 = pReg->civ; 1119 Log (("ac97:CIV[%d] -> %#x\n", GET_BM(index), *pu32));1378 LogFlowFunc(("CIV[%d] -> %#x\n", GET_BM(index), *pu32)); 1120 1379 break; 1121 1380 case PI_LVI: … … 1125 1384 pReg = &pThis->bm_regs[GET_BM(index)]; 1126 1385 *pu32 = pReg->lvi; 1127 Log (("ac97:LVI[%d] -> %#x\n", GET_BM(index), *pu32));1386 LogFlowFunc(("LVI[%d] -> %#x\n", GET_BM(index), *pu32)); 1128 1387 break; 1129 1388 case PI_PIV: … … 1133 1392 pReg = &pThis->bm_regs[GET_BM(index)]; 1134 1393 *pu32 = pReg->piv; 1135 Log (("ac97:PIV[%d] -> %#x\n", GET_BM(index), *pu32));1394 LogFlowFunc(("PIV[%d] -> %#x\n", GET_BM(index), *pu32)); 1136 1395 break; 1137 1396 case PI_CR: … … 1141 1400 pReg = &pThis->bm_regs[GET_BM(index)]; 1142 1401 *pu32 = pReg->cr; 1143 Log (("ac97:CR[%d] -> %#x\n", GET_BM(index), *pu32));1402 LogFlowFunc(("CR[%d] -> %#x\n", GET_BM(index), *pu32)); 1144 1403 break; 1145 1404 case PI_SR: … … 1149 1408 pReg = &pThis->bm_regs[GET_BM(index)]; 1150 1409 *pu32 = pReg->sr & 0xff; 1151 Log (("ac97:SRb[%d] -> %#x\n", GET_BM(index), *pu32));1410 LogFlowFunc(("SRb[%d] -> %#x\n", GET_BM(index), *pu32)); 1152 1411 break; 1153 1412 default: 1154 Log (("ac97:U nabm readb %#x -> %#x\n", Port, *pu32));1413 LogFlowFunc(("U nabm readb %#x -> %#x\n", Port, *pu32)); 1155 1414 break; 1156 1415 } … … 1172 1431 pReg = &pThis->bm_regs[GET_BM(index)]; 1173 1432 *pu32 = pReg->sr; 1174 Log (("ac97:SR[%d] -> %#x\n", GET_BM(index), *pu32));1433 LogFlowFunc(("SR[%d] -> %#x\n", GET_BM(index), *pu32)); 1175 1434 break; 1176 1435 case PI_PICB: … … 1180 1439 pReg = &pThis->bm_regs[GET_BM(index)]; 1181 1440 *pu32 = pReg->picb; 1182 Log (("ac97:PICB[%d] -> %#x\n", GET_BM(index), *pu32));1441 LogFlowFunc(("PICB[%d] -> %#x\n", GET_BM(index), *pu32)); 1183 1442 break; 1184 1443 default: 1185 Log (("ac97:U nabm readw %#x -> %#x\n", Port, *pu32));1444 LogFlowFunc(("U nabm readw %#x -> %#x\n", Port, *pu32)); 1186 1445 break; 1187 1446 } … … 1203 1462 pReg = &pThis->bm_regs[GET_BM(index)]; 1204 1463 *pu32 = pReg->bdbar; 1205 Log (("ac97:BMADDR[%d] -> %#x\n", GET_BM(index), *pu32));1464 LogFlowFunc(("BMADDR[%d] -> %#x\n", GET_BM(index), *pu32)); 1206 1465 break; 1207 1466 case PI_CIV: … … 1213 1472 pReg = &pThis->bm_regs[GET_BM(index)]; 1214 1473 *pu32 = pReg->civ | (pReg->lvi << 8) | (pReg->sr << 16); 1215 Log (("ac97:CIV LVI SR[%d] -> %#x, %#x, %#x\n", GET_BM(index), pReg->civ, pReg->lvi, pReg->sr));1474 LogFlowFunc(("CIV LVI SR[%d] -> %#x, %#x, %#x\n", GET_BM(index), pReg->civ, pReg->lvi, pReg->sr)); 1216 1475 break; 1217 1476 case PI_PICB: … … 1223 1482 pReg = &pThis->bm_regs[GET_BM(index)]; 1224 1483 *pu32 = pReg->picb | (pReg->piv << 16) | (pReg->cr << 24); 1225 Log (("ac97:PICB PIV CR[%d] -> %#x %#x %#x %#x\n", GET_BM(index), *pu32, pReg->picb, pReg->piv, pReg->cr));1484 LogFlowFunc(("PICB PIV CR[%d] -> %#x %#x %#x %#x\n", GET_BM(index), *pu32, pReg->picb, pReg->piv, pReg->cr)); 1226 1485 break; 1227 1486 case GLOB_CNT: 1228 1487 /* Global Control */ 1229 1488 *pu32 = pThis->glob_cnt; 1230 Log (("ac97:glob_cnt -> %#x\n", *pu32));1489 LogFlowFunc(("glob_cnt -> %#x\n", *pu32)); 1231 1490 break; 1232 1491 case GLOB_STA: 1233 1492 /* Global Status */ 1234 1493 *pu32 = pThis->glob_sta | GS_S0CR; 1235 Log (("ac97:glob_sta -> %#x\n", *pu32));1494 LogFlowFunc(("glob_sta -> %#x\n", *pu32)); 1236 1495 break; 1237 1496 default: 1238 Log (("ac97:U nabm readl %#x -> %#x\n", Port, *pu32));1497 LogFlowFunc(("U nabm readl %#x -> %#x\n", Port, *pu32)); 1239 1498 break; 1240 1499 } … … 1273 1532 pReg->civ = pReg->piv; 1274 1533 pReg->piv = (pReg->piv + 1) % 32; 1275 fetch_bd(pThis, pReg);1534 ichac97FetchBufDesc(pThis, pReg); 1276 1535 } 1277 1536 pReg->lvi = u32 % 32; 1278 Log (("ac97:LVI[%d] <- %#x\n", GET_BM(index), u32));1537 LogFlowFunc(("LVI[%d] <- %#x\n", GET_BM(index), u32)); 1279 1538 break; 1280 1539 case PI_CR: … … 1284 1543 pReg = &pThis->bm_regs[GET_BM(index)]; 1285 1544 if (u32 & CR_RR) 1286 reset_bm_regs(pThis, pReg);1545 ichac97ResetBMRegs(pThis, pReg); 1287 1546 else 1288 1547 { … … 1290 1549 if (!(pReg->cr & CR_RPBM)) 1291 1550 { 1292 voice_set_active(pThis, pReg - pThis->bm_regs, 0);1551 ichac97StreamSetActive(pThis, pReg - pThis->bm_regs, 0); 1293 1552 pReg->sr |= SR_DCH; 1294 1553 } … … 1297 1556 pReg->civ = pReg->piv; 1298 1557 pReg->piv = (pReg->piv + 1) % 32; 1299 fetch_bd(pThis, pReg);1558 ichac97FetchBufDesc(pThis, pReg); 1300 1559 pReg->sr &= ~SR_DCH; 1301 voice_set_active(pThis, pReg - pThis->bm_regs, 1);1560 ichac97StreamSetActive(pThis, pReg - pThis->bm_regs, 1); 1302 1561 } 1303 1562 } 1304 Log (("ac97:CR[%d] <- %#x (cr %#x)\n", GET_BM(index), u32, pReg->cr));1563 LogFlowFunc(("CR[%d] <- %#x (cr %#x)\n", GET_BM(index), u32, pReg->cr)); 1305 1564 break; 1306 1565 case PI_SR: … … 1310 1569 pReg = &pThis->bm_regs[GET_BM(index)]; 1311 1570 pReg->sr |= u32 & ~(SR_RO_MASK | SR_WCLEAR_MASK); 1312 update_sr(pThis, pReg, pReg->sr & ~(u32 & SR_WCLEAR_MASK));1313 Log (("ac97:SR[%d] <- %#x (sr %#x)\n", GET_BM(index), u32, pReg->sr));1571 ichac97UpdateStatus(pThis, pReg, pReg->sr & ~(u32 & SR_WCLEAR_MASK)); 1572 LogFlowFunc(("SR[%d] <- %#x (sr %#x)\n", GET_BM(index), u32, pReg->sr)); 1314 1573 break; 1315 1574 default: 1316 Log (("ac97:U nabm writeb %#x <- %#x\n", Port, u32));1575 LogFlowFunc(("U nabm writeb %#x <- %#x\n", Port, u32)); 1317 1576 break; 1318 1577 } … … 1332 1591 pReg = &pThis->bm_regs[GET_BM(index)]; 1333 1592 pReg->sr |= u32 & ~(SR_RO_MASK | SR_WCLEAR_MASK); 1334 update_sr(pThis, pReg, pReg->sr & ~(u32 & SR_WCLEAR_MASK));1335 Log (("ac97:SR[%d] <- %#x (sr %#x)\n", GET_BM(index), u32, pReg->sr));1593 ichac97UpdateStatus(pThis, pReg, pReg->sr & ~(u32 & SR_WCLEAR_MASK)); 1594 LogFlowFunc(("SR[%d] <- %#x (sr %#x)\n", GET_BM(index), u32, pReg->sr)); 1336 1595 break; 1337 1596 default: 1338 Log (("ac97:U nabm writew %#x <- %#x\n", Port, u32));1597 LogFlowFunc(("U nabm writew %#x <- %#x\n", Port, u32)); 1339 1598 break; 1340 1599 } … … 1354 1613 pReg = &pThis->bm_regs[GET_BM(index)]; 1355 1614 pReg->bdbar = u32 & ~3; 1356 Log (("ac97:BDBAR[%d] <- %#x (bdbar %#x)\n", GET_BM(index), u32, pReg->bdbar));1615 LogFlowFunc(("BDBAR[%d] <- %#x (bdbar %#x)\n", GET_BM(index), u32, pReg->bdbar)); 1357 1616 break; 1358 1617 case GLOB_CNT: 1359 1618 /* Global Control */ 1360 1619 if (u32 & GC_WR) 1361 warm_reset(pThis);1620 ichac97WarmReset(pThis); 1362 1621 if (u32 & GC_CR) 1363 cold_reset(pThis);1622 ichac97ColdReset(pThis); 1364 1623 if (!(u32 & (GC_WR | GC_CR))) 1365 1624 pThis->glob_cnt = u32 & GC_VALID_MASK; 1366 Log (("ac97:glob_cnt <- %#x (glob_cnt %#x)\n", u32, pThis->glob_cnt));1625 LogFlowFunc(("glob_cnt <- %#x (glob_cnt %#x)\n", u32, pThis->glob_cnt)); 1367 1626 break; 1368 1627 case GLOB_STA: … … 1370 1629 pThis->glob_sta &= ~(u32 & GS_WCLEAR_MASK); 1371 1630 pThis->glob_sta |= (u32 & ~(GS_WCLEAR_MASK | GS_RO_MASK)) & GS_VALID_MASK; 1372 Log (("ac97:glob_sta <- %#x (glob_sta %#x)\n", u32, pThis->glob_sta));1631 LogFlowFunc(("glob_sta <- %#x (glob_sta %#x)\n", u32, pThis->glob_sta)); 1373 1632 break; 1374 1633 default: 1375 Log (("ac97:U nabm writel %#x <- %#x\n", Port, u32));1634 LogFlowFunc(("U nabm writel %#x <- %#x\n", Port, u32)); 1376 1635 break; 1377 1636 } … … 1397 1656 case 1: 1398 1657 { 1399 Log (("ac97:U nam readb %#x\n", Port));1658 LogFlowFunc(("U nam readb %#x\n", Port)); 1400 1659 pThis->cas = 0; 1401 1660 *pu32 = ~0U; … … 1411 1670 { 1412 1671 default: 1413 *pu32 = mixer_load(pThis, index);1414 Log (("ac97:nam readw %#x -> %#x\n", Port, *pu32));1672 *pu32 = ichac97MixerLoad(pThis, index); 1673 LogFlowFunc(("nam readw %#x -> %#x\n", Port, *pu32)); 1415 1674 break; 1416 1675 } … … 1420 1679 case 4: 1421 1680 { 1422 Log (("ac97:U nam readl %#x\n", Port));1681 LogFlowFunc(("U nam readl %#x\n", Port)); 1423 1682 pThis->cas = 0; 1424 1683 *pu32 = ~0U; … … 1435 1694 * @callback_method_impl{FNIOMIOPORTOUT} 1436 1695 */ 1437 static DECLCALLBACK(int) ichac97IOPortNAMWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb) 1696 static DECLCALLBACK(int) ichac97IOPortNAMWrite(PPDMDEVINS pDevIns, 1697 void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb) 1438 1698 { 1439 1699 PAC97STATE pThis = (PAC97STATE)pvUser; … … 1443 1703 case 1: 1444 1704 { 1445 Log (("ac97:U nam writeb %#x <- %#x\n", Port, u32));1705 LogFlowFunc(("U nam writeb %#x <- %#x\n", Port, u32)); 1446 1706 pThis->cas = 0; 1447 1707 break; … … 1455 1715 { 1456 1716 case AC97_Reset: 1457 mixer_reset(pThis);1717 ichac97MixerReset(pThis); 1458 1718 break; 1459 1719 case AC97_Powerdown_Ctrl_Stat: 1460 1720 u32 &= ~0xf; 1461 u32 |= mixer_load(pThis, index) & 0xf;1462 mixer_store(pThis, index, u32);1721 u32 |= ichac97MixerLoad(pThis, index) & 0xf; 1722 ichac97MixerStore(pThis, index, u32); 1463 1723 break; 1464 1724 #ifdef USE_MIXER 1465 1725 case AC97_Master_Volume_Mute: 1466 set_volume(pThis, index, AUD_MIXER_VOLUME, u32); 1726 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1727 ichac97SetVolume(pThis, index, PDMAUDIOMIXERCTL_VOLUME, u32); 1728 #else 1729 ichac97SetVolume(pThis, index, AUD_MIXER_VOLUME, u32); 1730 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1467 1731 break; 1468 1732 case AC97_PCM_Out_Volume_Mute: 1469 set_volume(pThis, index, AUD_MIXER_PCM, u32); 1733 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1734 ichac97SetVolume(pThis, index, PDMAUDIOMIXERCTL_PCM, u32); 1735 #else 1736 ichac97SetVolume(pThis, index, AUD_MIXER_PCM, u32); 1737 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1470 1738 break; 1471 1739 case AC97_Line_In_Volume_Mute: 1472 set_volume(pThis, index, AUD_MIXER_LINE_IN, u32); 1740 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1741 ichac97SetVolume(pThis, index, PDMAUDIOMIXERCTL_LINE_IN, u32); 1742 #else 1743 ichac97SetVolume(pThis, index, AUD_MIXER_LINE_IN, u32); 1744 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1473 1745 break; 1474 1746 case AC97_Record_Select: 1475 record_select(pThis, u32);1747 ichac97RecordSelect(pThis, u32); 1476 1748 break; 1477 1749 #else /* !USE_MIXER */ … … 1480 1752 case AC97_Line_In_Volume_Mute: 1481 1753 case AC97_Record_Select: 1482 mixer_store(pThis, index, u32);1754 ichac97MixerStore(pThis, index, u32); 1483 1755 break; 1484 1756 #endif /* !USE_MIXER */ 1485 1757 case AC97_Vendor_ID1: 1486 1758 case AC97_Vendor_ID2: 1487 Log (("ac97:Attempt to write vendor ID to %#x\n", u32));1759 LogFlowFunc(("Attempt to write vendor ID to %#x\n", u32)); 1488 1760 break; 1489 1761 case AC97_Extended_Audio_ID: 1490 Log (("ac97:Attempt to write extended audio ID to %#x\n", u32));1762 LogFlowFunc(("Attempt to write extended audio ID to %#x\n", u32)); 1491 1763 break; 1492 1764 case AC97_Extended_Audio_Ctrl_Stat: 1493 1765 if (!(u32 & EACS_VRA)) 1494 1766 { 1495 mixer_store(pThis, AC97_PCM_Front_DAC_Rate, 0xbb80);1496 mixer_store(pThis, AC97_PCM_LR_ADC_Rate, 0xbb80);1497 open_voice(pThis, PI_INDEX, 48000);1498 open_voice(pThis, PO_INDEX, 48000);1767 ichac97MixerStore(pThis, AC97_PCM_Front_DAC_Rate, 0xbb80); 1768 ichac97MixerStore(pThis, AC97_PCM_LR_ADC_Rate, 0xbb80); 1769 ichac97OpenStream(pThis, PI_INDEX, 48000); 1770 ichac97OpenStream(pThis, PO_INDEX, 48000); 1499 1771 } 1500 1772 if (!(u32 & EACS_VRM)) 1501 1773 { 1502 mixer_store(pThis, AC97_MIC_ADC_Rate, 0xbb80);1503 open_voice(pThis, MC_INDEX, 48000);1774 ichac97MixerStore(pThis, AC97_MIC_ADC_Rate, 0xbb80); 1775 ichac97OpenStream(pThis, MC_INDEX, 48000); 1504 1776 } 1505 Log (("ac97:Setting extended audio control to %#x\n", u32));1506 mixer_store(pThis, AC97_Extended_Audio_Ctrl_Stat, u32);1777 LogFlowFunc(("Setting extended audio control to %#x\n", u32)); 1778 ichac97MixerStore(pThis, AC97_Extended_Audio_Ctrl_Stat, u32); 1507 1779 break; 1508 1780 case AC97_PCM_Front_DAC_Rate: 1509 if ( mixer_load(pThis, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRA)1781 if (ichac97MixerLoad(pThis, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRA) 1510 1782 { 1511 mixer_store(pThis, index, u32);1512 Log (("ac97:Set front DAC rate to %d\n", u32));1513 open_voice(pThis, PO_INDEX, u32);1783 ichac97MixerStore(pThis, index, u32); 1784 LogFlowFunc(("Set front DAC rate to %d\n", u32)); 1785 ichac97OpenStream(pThis, PO_INDEX, u32); 1514 1786 } 1515 1787 else 1516 Log (("ac97:Attempt to set front DAC rate to %d, but VRA is not set\n", u32));1788 LogFlowFunc(("Attempt to set front DAC rate to %d, but VRA is not set\n", u32)); 1517 1789 break; 1518 1790 case AC97_MIC_ADC_Rate: 1519 if ( mixer_load(pThis, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRM)1791 if (ichac97MixerLoad(pThis, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRM) 1520 1792 { 1521 mixer_store(pThis, index, u32);1522 Log (("ac97:Set MIC ADC rate to %d\n", u32));1523 open_voice(pThis, MC_INDEX, u32);1793 ichac97MixerStore(pThis, index, u32); 1794 LogFlowFunc(("Set MIC ADC rate to %d\n", u32)); 1795 ichac97OpenStream(pThis, MC_INDEX, u32); 1524 1796 } 1525 1797 else 1526 Log (("ac97:Attempt to set MIC ADC rate to %d, but VRM is not set\n", u32));1798 LogFlowFunc(("Attempt to set MIC ADC rate to %d, but VRM is not set\n", u32)); 1527 1799 break; 1528 1800 case AC97_PCM_LR_ADC_Rate: 1529 if ( mixer_load(pThis, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRA)1801 if (ichac97MixerLoad(pThis, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRA) 1530 1802 { 1531 mixer_store(pThis, index, u32);1532 Log (("ac97:Set front LR ADC rate to %d\n", u32));1533 open_voice(pThis, PI_INDEX, u32);1803 ichac97MixerStore(pThis, index, u32); 1804 LogFlowFunc(("Set front LR ADC rate to %d\n", u32)); 1805 ichac97OpenStream(pThis, PI_INDEX, u32); 1534 1806 } 1535 1807 else 1536 Log (("ac97:Attempt to set LR ADC rate to %d, but VRA is not set\n", u32));1808 LogFlowFunc(("Attempt to set LR ADC rate to %d, but VRA is not set\n", u32)); 1537 1809 break; 1538 1810 default: 1539 Log (("ac97:U nam writew %#x <- %#x\n", Port, u32));1540 mixer_store(pThis, index, u32);1811 LogFlowFunc(("U nam writew %#x <- %#x\n", Port, u32)); 1812 ichac97MixerStore(pThis, index, u32); 1541 1813 break; 1542 1814 } … … 1546 1818 case 4: 1547 1819 { 1548 Log (("ac97:U nam writel %#x <- %#x\n", Port, u32));1820 LogFlowFunc(("U nam writel %#x <- %#x\n", Port, u32)); 1549 1821 pThis->cas = 0; 1550 1822 break; … … 1555 1827 break; 1556 1828 } 1829 1557 1830 return VINF_SUCCESS; 1558 1831 } … … 1617 1890 1618 1891 uint8_t active[LAST_INDEX]; 1619 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1620 /* writing only host backend values here and ignoring for webm and VRDE */ 1621 active[PI_INDEX] = pThis->pDrv[0]->pfnIsActiveIn(pThis->pDrv[0], pThis->voice_pi[0]) ? 1 : 0; 1622 active[PO_INDEX] = pThis->pDrv[0]->pfnIsActiveOut(pThis->pDrv[0], pThis->voice_po[0]) ? 1 : 0; 1623 active[MC_INDEX] = pThis->pDrv[0]->pfnIsActiveIn(pThis->pDrv[0], pThis->voice_mc[0]) ? 1 : 0; 1892 1893 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1894 /* Writing only host backend values here and ignore data for other backends 1895 * like VRDE and video recording. LUN 0 always is the host backend. */ 1896 if (pThis->cLUNs >= 1) 1897 { 1898 PPDMIAUDIOCONNECTOR pCon = pThis->paDrv[0]->pConnector; 1899 AssertPtr(pCon); 1900 active[PI_INDEX] = pCon->pfnIsActiveIn(pCon, pThis->paDrv[0]->pStrmIn) ? 1 : 0; 1901 active[PO_INDEX] = pCon->pfnIsActiveOut(pCon, pThis->paDrv[0]->pStrmOut) ? 1 : 0; 1902 active[MC_INDEX] = pCon->pfnIsActiveIn(pCon, pThis->paDrv[0]->pStrmMic) ? 1 : 0; 1903 } 1904 else 1905 RT_ZERO(active); 1624 1906 #else 1625 1907 active[PI_INDEX] = AUD_is_active_in( pThis->voice_pi) ? 1 : 0; 1626 1908 active[PO_INDEX] = AUD_is_active_out(pThis->voice_po) ? 1 : 0; 1627 1909 active[MC_INDEX] = AUD_is_active_in( pThis->voice_mc) ? 1 : 0; 1628 #endif 1910 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1911 1629 1912 SSMR3PutMem(pSSM, active, sizeof(active)); 1630 1913 … … 1667 1950 1668 1951 #ifdef USE_MIXER 1669 record_select(pThis, mixer_load(pThis, AC97_Record_Select)); 1670 # define V_(a, b) set_volume(pThis, a, b, mixer_load(pThis, a)) 1952 ichac97RecordSelect(pThis, ichac97MixerLoad(pThis, AC97_Record_Select)); 1953 # define V_(a, b) ichac97SetVolume(pThis, a, b, ichac97MixerLoad(pThis, a)) 1954 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1955 V_(AC97_Master_Volume_Mute, PDMAUDIOMIXERCTL_VOLUME); 1956 V_(AC97_PCM_Out_Volume_Mute, PDMAUDIOMIXERCTL_PCM); 1957 V_(AC97_Line_In_Volume_Mute, PDMAUDIOMIXERCTL_LINE_IN); 1958 # else 1671 1959 V_(AC97_Master_Volume_Mute, AUD_MIXER_VOLUME); 1672 1960 V_(AC97_PCM_Out_Volume_Mute, AUD_MIXER_PCM); 1673 1961 V_(AC97_Line_In_Volume_Mute, AUD_MIXER_LINE_IN); 1962 # endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1674 1963 # undef V_ 1675 1964 #endif /* USE_MIXER */ 1676 reset_voices(pThis, active);1965 ichac97ResetStreams(pThis, active); 1677 1966 1678 1967 pThis->bup_flag = 0; … … 1702 1991 * make sense to me so we'll do it. 1703 1992 */ 1704 static DECLCALLBACK(void) 1993 static DECLCALLBACK(void) ac97Reset(PPDMDEVINS pDevIns) 1705 1994 { 1706 1995 PAC97STATE pThis = PDMINS_2_DATA(pDevIns, AC97STATE *); … … 1709 1998 * Reset the device state (will need pDrv later). 1710 1999 */ 1711 reset_bm_regs(pThis, &pThis->bm_regs[0]);1712 reset_bm_regs(pThis, &pThis->bm_regs[1]);1713 reset_bm_regs(pThis, &pThis->bm_regs[2]);2000 ichac97ResetBMRegs(pThis, &pThis->bm_regs[0]); 2001 ichac97ResetBMRegs(pThis, &pThis->bm_regs[1]); 2002 ichac97ResetBMRegs(pThis, &pThis->bm_regs[2]); 1714 2003 1715 2004 /* … … 1718 2007 * the codec manually. 1719 2008 */ 1720 mixer_reset(pThis); 1721 } 2009 ichac97MixerReset(pThis); 2010 } 2011 2012 2013 /** 2014 * @interface_method_impl{PDMDEVREG,pfnDestruct} 2015 */ 2016 static DECLCALLBACK(int) ichac97Destruct(PPDMDEVINS pDevIns) 2017 { 2018 PAC97STATE pThis = PDMINS_2_DATA(pDevIns, PAC97STATE); 2019 2020 LogFlowFuncEnter(); 2021 2022 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2023 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 2024 { 2025 if (pThis->paDrv[lun]) 2026 { 2027 RTMemFree(pThis->paDrv[lun]); 2028 pThis->paDrv[lun] = NULL; 2029 } 2030 } 2031 2032 pThis->cLUNs = 0; 2033 2034 if (pThis->pMixer) 2035 { 2036 audioMixerDestroy(pThis->pMixer); 2037 pThis->pMixer = NULL; 2038 } 2039 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 2040 2041 return VINF_SUCCESS; 2042 } 2043 2044 2045 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2046 /** 2047 * Attach command. 2048 * 2049 * This is called to let the device attach to a driver for a specified LUN 2050 * during runtime. This is not called during VM construction, the device 2051 * constructor have to attach to all the available drivers. 2052 * 2053 * @returns VBox status code. 2054 * @param pDevIns The device instance. 2055 * @param uLUN The logical unit which is being detached. 2056 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines. 2057 */ 2058 static DECLCALLBACK(int) ichac97Attach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags) 2059 { 2060 PAC97STATE pThis = PDMINS_2_DATA(pDevIns, PAC97STATE); 2061 2062 AssertMsgReturn(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG, 2063 ("AC'97 device does not support hotplugging\n"), 2064 VERR_INVALID_PARAMETER); 2065 2066 /* 2067 * Attach driver. 2068 */ 2069 char *pszDesc = NULL; 2070 if (RTStrAPrintf(&pszDesc, "Audio driver port (AC'97) for LUN #%u", uLUN) <= 0) 2071 AssertMsgReturn(pszDesc, 2072 ("Not enough memory for AC'97 driver port description of LUN #%u\n", uLUN), 2073 VERR_NO_MEMORY); 2074 2075 int rc = PDMDevHlpDriverAttach(pDevIns, uLUN, 2076 &pThis->IBase, &pThis->pDrvBase, pszDesc); 2077 if (RT_SUCCESS(rc)) 2078 { 2079 PAC97DRIVER pDrv = (PAC97DRIVER)RTMemAllocZ(sizeof(AC97DRIVER)); 2080 if (pDrv) 2081 { 2082 pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR); 2083 AssertMsg(pDrv->pConnector != NULL, 2084 ("Configuration error: LUN #%u has no host audio interface, rc=%Rrc\n", 2085 uLUN, rc)); 2086 pDrv->pAC97State = pThis; 2087 pDrv->uLUN = uLUN; 2088 2089 LogFlowFunc(("LUN #%u is using connector %p\n", uLUN, pDrv->pConnector)); 2090 2091 pThis->paDrv[uLUN] = pDrv; 2092 pThis->cLUNs++; 2093 } 2094 else 2095 rc = VERR_NO_MEMORY; 2096 } 2097 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 2098 { 2099 LogFunc(("No attached driver for LUN #%u\n", uLUN)); 2100 } 2101 else if (RT_FAILURE(rc)) 2102 AssertMsgFailed(("Failed to attach AC'97 LUN #%u (\"%s\"), rc=%Rrc\n", 2103 uLUN, pszDesc, rc)); 2104 2105 RTStrFree(pszDesc); 2106 2107 LogFlowFunc(("iLUN=%u, fFlags=0x%x, rc=%Rrc\n", uLUN, fFlags, rc)); 2108 return rc; 2109 } 2110 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1722 2111 1723 2112 … … 1727 2116 static DECLCALLBACK(int) ichac97Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg) 1728 2117 { 1729 AC97STATE *pThis = PDMINS_2_DATA(pDevIns, AC97STATE *); 1730 int rc; 2118 PAC97STATE pThis = PDMINS_2_DATA(pDevIns, PAC97STATE); 1731 2119 1732 2120 Assert(iInstance == 0); … … 1770 2158 * saved state item. 1771 2159 */ 1772 rc = PDMDevHlpPCIRegister(pDevIns, &pThis->PciDev);2160 int rc = PDMDevHlpPCIRegister(pDevIns, &pThis->PciDev); 1773 2161 if (RT_FAILURE (rc)) 1774 2162 return rc; … … 1790 2178 */ 1791 2179 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1792 for (uint32_t lun = 0; lun < 2; lun++) 1793 { 1794 rc = PDMDevHlpDriverAttach(pDevIns, lun, &pThis->IBase, &pThis->pDrvBase, "Audio Driver Port"); 1795 if (RT_SUCCESS(rc)) 1796 { 1797 pThis->pDrv[lun] = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR); 1798 AssertMsgReturn(pThis->pDrv[lun], 1799 ("Configuration error: instance %d has no host audio interface!\n", iInstance), 1800 VERR_PDM_MISSING_INTERFACE); 1801 } 1802 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 1803 Log(("ac97: No attached driver!\n")); 1804 else if (RT_FAILURE(rc)) 1805 { 1806 AssertMsgFailed(("Failed to attach AC97 LUN #%d! rc=%Rrc\n", lun, rc)); 1807 return rc; 1808 } 1809 } 2180 /* We support 32 LUNs max. This should be enough for now. */ 2181 for (uint8_t lun = 0; lun < 32 ; lun++) 2182 { 2183 LogFunc(("Trying to attach driver for LUN #%RU8 ...\n", lun)); 2184 rc = ichac97Attach(pDevIns, lun, PDM_TACH_FLAGS_NOT_HOT_PLUG); 2185 if (RT_FAILURE(rc)) 2186 { 2187 if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 2188 rc = VINF_SUCCESS; 2189 break; 2190 } 2191 } 2192 2193 LogRel(("AC97: %RU8 LUN(s) attached\n", pThis->cLUNs)); 1810 2194 #else 1811 2195 rc = PDMDevHlpDriverAttach(pDevIns, 0, &pThis->IBase, &pThis->pDrvBase, "Audio Driver Port"); … … 1817 2201 return rc; 1818 2202 } 1819 #endif 1820 1821 1822 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1823 pThis->pDrv[0]->pfnRegisterCard(pThis->pDrv[0], "ICH0" ); 1824 #else 2203 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 2204 2205 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER 1825 2206 AUD_register_card("ICH0", &pThis->card); 1826 2207 #endif … … 1828 2209 1829 2210 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1830 for (uint32_t lun =0; lun < 2; lun++) 1831 { 1832 if (!pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_pi[lun])) 1833 LogRel(("AC97: WARNING: Unable to open PCM IN!\n")); 1834 if (!pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_mc[lun])) 1835 LogRel(("AC97: WARNING: Unable to open PCM MC!\n")); 1836 if (!pThis->pDrv[lun]->pfnIsHostVoiceOutOK(pThis->pDrv[lun], pThis->voice_po[lun])) 1837 LogRel(("AC97: WARNING: Unable to open PCM OUT!\n")); 2211 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 2212 { 2213 if (!pThis->paDrv[lun]->pConnector->pfnIsInputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmIn)) 2214 LogRel(("AC97: WARNING: Unable to open PCM line input for LUN #%RU32!\n", lun)); 2215 if (!pThis->paDrv[lun]->pConnector->pfnIsOutputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmOut)) 2216 LogRel(("AC97: WARNING: Unable to open PCM output for LUN #%RU32!\n", lun)); 2217 if (!pThis->paDrv[lun]->pConnector->pfnIsInputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmMic)) 2218 LogRel(("AC97: WARNING: Unable to open PCM microphone input for LUN #%RU32!\n", lun)); 2219 } 2220 2221 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 2222 { 2223 if ( !pThis->paDrv[lun]->pConnector->pfnIsInputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmIn) 2224 && !pThis->paDrv[lun]->pConnector->pfnIsOutputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmOut) 2225 && !pThis->paDrv[lun]->pConnector->pfnIsInputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmMic)) 2226 { 2227 /* Was not able initialize *any* stream. Select the NULL audio driver instead. */ 2228 pThis->paDrv[lun]->pConnector->pfnCloseIn(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmIn); 2229 pThis->paDrv[lun]->pConnector->pfnCloseOut(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmOut); 2230 pThis->paDrv[lun]->pConnector->pfnCloseIn(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmMic); 2231 2232 pThis->paDrv[lun]->pStrmOut = NULL; 2233 pThis->paDrv[lun]->pStrmIn = NULL; 2234 pThis->paDrv[lun]->pStrmMic = NULL; 2235 2236 pThis->paDrv[lun]->pConnector->pfnInitNull(pThis->paDrv[lun]->pConnector); 2237 ac97Reset(pDevIns); 2238 2239 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", 2240 N_("No audio devices could be opened. Selecting the NULL audio backend " 2241 "with the consequence that no sound is audible")); 2242 } 2243 else if ( !pThis->paDrv[lun]->pConnector->pfnIsInputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmIn) 2244 || !pThis->paDrv[lun]->pConnector->pfnIsOutputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmOut) 2245 || !pThis->paDrv[lun]->pConnector->pfnIsInputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmMic)) 2246 { 2247 char szMissingStreams[128]; 2248 size_t len = 0; 2249 if (!pThis->paDrv[lun]->pConnector->pfnIsInputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmIn)) 2250 len = RTStrPrintf(szMissingStreams, sizeof(szMissingStreams), "PCM Input"); 2251 if (!pThis->paDrv[lun]->pConnector->pfnIsOutputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmOut)) 2252 len += RTStrPrintf(szMissingStreams + len, sizeof(szMissingStreams) - len, len ? ", PCM Output" : "PCM Output"); 2253 if (!pThis->paDrv[lun]->pConnector->pfnIsInputOK(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmMic)) 2254 len += RTStrPrintf(szMissingStreams + len, sizeof(szMissingStreams) - len, len ? ", PCM Mic" : "PCM Mic"); 2255 2256 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", 2257 N_("Some AC'97 audio streams (%s) could not be opened. Guest applications generating audio " 2258 "output or depending on audio input may hang. Make sure your host audio device " 2259 "is working properly. Check the logfile for error messages of the audio " 2260 "subsystem"), szMissingStreams); 2261 } 1838 2262 } 1839 2263 #else … … 1845 2269 LogRel(("AC97: WARNING: Unable to open PCM OUT!\n")); 1846 2270 1847 #endif1848 1849 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER1850 for (uint32_t lun = 0; lun < 2; lun++)1851 {1852 if ( !pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_pi[lun])1853 && !pThis->pDrv[lun]->pfnIsHostVoiceOutOK(pThis->pDrv[lun], pThis->voice_po[lun])1854 && !pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_mc[lun]))1855 {1856 /* Was not able initialize *any* voice. Select the NULL audio driver instead */1857 pThis->pDrv[lun]->pfnCloseIn(pThis->pDrv[lun], pThis->voice_pi[lun]);1858 pThis->pDrv[lun]->pfnCloseOut(pThis->pDrv[lun], pThis->voice_po[lun]);1859 pThis->pDrv[lun]->pfnCloseIn(pThis->pDrv[lun], pThis->voice_mc[lun]);1860 1861 pThis->voice_po[lun] = NULL;1862 pThis->voice_pi[lun] = NULL;1863 pThis->voice_mc[lun] = NULL;1864 1865 pThis->pDrv[lun]->pfnInitNull(pThis->pDrv[lun]);1866 ac97Reset(pDevIns);1867 1868 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",1869 N_("No audio devices could be opened. Selecting the NULL audio backend "1870 "with the consequence that no sound is audible"));1871 }1872 else if ( !pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_pi[lun])1873 || !pThis->pDrv[lun]->pfnIsHostVoiceOutOK(pThis->pDrv[lun], pThis->voice_po[lun])1874 || !pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_mc[lun]))1875 {1876 char szMissingVoices[128];1877 size_t len = 0;1878 if (!pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_pi[lun]))1879 len = RTStrPrintf(szMissingVoices, sizeof(szMissingVoices), "PCM_in");1880 if (!pThis->pDrv[lun]->pfnIsHostVoiceOutOK(pThis->pDrv[lun], pThis->voice_po[lun]))1881 len += RTStrPrintf(szMissingVoices + len, sizeof(szMissingVoices) - len, len ? ", PCM_out" : "PCM_out");1882 if (!pThis->pDrv[lun]->pfnIsHostVoiceInOK(pThis->pDrv[lun], pThis->voice_mc[lun]))1883 len += RTStrPrintf(szMissingVoices + len, sizeof(szMissingVoices) - len, len ? ", PCM_mic" : "PCM_mic");1884 1885 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",1886 N_("Some audio devices (%s) could not be opened. Guest applications generating audio "1887 "output or depending on audio input may hang. Make sure your host audio device "1888 "is working properly. Check the logfile for error messages of the audio "1889 "subsystem"), szMissingVoices);1890 }1891 }1892 #else1893 2271 if ( !AUD_is_host_voice_in_ok( pThis->voice_pi) 1894 2272 && !AUD_is_host_voice_out_ok(pThis->voice_po) … … 1928 2306 "subsystem"), szMissingVoices); 1929 2307 } 1930 #endif 2308 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 2309 1931 2310 return VINF_SUCCESS; 1932 2311 } … … 1958 2337 ichac97Construct, 1959 2338 /* pfnDestruct */ 1960 NULL,2339 ichac97Destruct, 1961 2340 /* pfnRelocate */ 1962 2341 NULL, -
trunk/src/VBox/Devices/Audio/DevIchHda.cpp
r53416 r53442 9 9 10 10 /* 11 * Copyright (C) 2006-201 3Oracle Corporation11 * Copyright (C) 2006-2014 Oracle Corporation 12 12 * 13 13 * This file is part of VirtualBox Open Source Edition (OSE), as … … 23 23 * Header Files * 24 24 *******************************************************************************/ 25 #define LOG_GROUP LOG_GROUP_DEV_AUDIO26 25 #include <VBox/vmm/pdmdev.h> 27 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER28 26 #include <VBox/vmm/pdmaudioifs.h> 29 #endif30 27 #include <VBox/version.h> 31 28 … … 38 35 # include <iprt/mem.h> 39 36 #endif 37 #include <iprt/list.h> 38 39 #if 0 40 /* Warning: Enabling this causes a *lot* of output! */ 41 #ifdef LOG_GROUP 42 # undef LOG_GROUP 43 #endif 44 #define LOG_GROUP LOG_GROUP_DEV_AUDIO 45 #include <VBox/log.h> 46 #endif 40 47 41 48 #include "VBoxDD.h" 42 49 43 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER 44 extern "C" { 45 #include "audio.h" 46 } 50 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 51 # include "AudioMixer.h" 52 #else 53 extern "C" { 54 #include "audio.h" 55 } 47 56 #endif 48 57 #include "DevIchHdaCodec.h" 49 50 58 51 59 /******************************************************************************* … … 279 287 #define HDA_STREAM_REG_DEF(name, num) (HDA_REG_SD##num##name) 280 288 #define HDA_STREAM_RMX_DEF(name, num) (HDA_RMX_SD##num##name) 281 /* Note: sdnum here _MUST_ be stream reg number [0,7] */282 #define HDA_STREAM_REG(pThis, name, sdnum) (HDA_REG_IND((pThis), HDA_REG_SD0##name + (sdnum) * 10))289 /* Note: sdnum here _MUST_ be stream reg number [0,7]. */ 290 #define HDA_STREAM_REG(pThis, name, sdnum) (HDA_REG_IND((pThis), HDA_REG_SD0##name + (sdnum) * 10)) 283 291 284 292 #define HDA_REG_SD0CTL 34 /* 0x80 */ … … 508 516 #define HDA_RMX_SD7BDPU (HDA_STREAM_RMX_DEF(BDPU, 0) + 70) 509 517 518 #define HDA_CODEC_CAD_SHIFT 28 519 /* Encodes the (required) LUN into a codec command. */ 520 #define HDA_CODEC_CMD(cmd, lun) ((cmd) | (lun << HDA_CODEC_CAD_SHIFT)) 521 522 510 523 511 524 /******************************************************************************* … … 535 548 } HDASTREAMTRANSFERDESC, *PHDASTREAMTRANSFERDESC; 536 549 550 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 551 /** 552 * Struct for maintaining a host backend driver. 553 * This driver must be associated to one, and only one, 554 * HDA codec. The HDA controller does the actual multiplexing 555 * of HDA codec data to various host backend drivers then. 556 */ 557 typedef struct HDADRIVER 558 { 559 RTLISTNODE Node; 560 /** Pointer to HDA controller (state). */ 561 PHDASTATE pHDAState; 562 /** LUN to which this driver has been assigned. */ 563 uint8_t uLUN; 564 /** Audio connector interface to the underlying 565 * host backend. */ 566 R3PTRTYPE(PPDMIAUDIOCONNECTOR) pConnector; 567 /** PCM line input stream. */ 568 R3PTRTYPE(PPDMAUDIOGSTSTRMIN) pStrmIn; 569 /** Mixer handle for line input stream. */ 570 R3PTRTYPE(PAUDMIXSTREAM) phStrmIn; 571 /** PCM microphone input stream. */ 572 R3PTRTYPE(PPDMAUDIOGSTSTRMIN) pStrmMic; 573 /** Mixer handle for microphone input stream. */ 574 R3PTRTYPE(PAUDMIXSTREAM) phStrmMic; 575 /** PCM output stream. */ 576 R3PTRTYPE(PPDMAUDIOGSTSTRMOUT) pGstStrmOut; 577 } HDADRIVER, *PHDADRIVER; 578 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 579 537 580 /** 538 581 * ICH Intel HD Audio Controller state. … … 551 594 uint32_t u32Padding; 552 595 553 /** Pointer to the connector of the attached audio driver. */554 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER555 R3PTRTYPE(PPDMIAUDIOCONNECTOR) pDrv[2];556 #else557 R3PTRTYPE(PPDMIAUDIOCONNECTOR) pDrv;558 #endif559 596 /** Pointer to the attached audio driver. */ 560 597 R3PTRTYPE(PPDMIBASE) pDrvBase; … … 569 606 uint64_t u64RIRBBase; 570 607 uint64_t u64DPBase; 571 /** pointer to CORB buf*/608 /** Pointer to CORB buffer. */ 572 609 R3PTRTYPE(uint32_t *) pu32CorbBuf; 573 /** size in bytes of CORB buf*/610 /** Size in bytes of CORB buffer. */ 574 611 uint32_t cbCorbBuf; 575 612 uint32_t u32Padding2; 576 /** pointer on RIRB buf*/613 /** Pointer to RIRB buffer. */ 577 614 R3PTRTYPE(uint64_t *) pu64RirbBuf; 578 /** size in bytes of RIRB buf*/615 /** Size in bytes of RIRB buffer. */ 579 616 uint32_t cbRirbBuf; 580 /** indicates if HDAin reset. */617 /** Indicates if HDA is in reset. */ 581 618 bool fInReset; 582 619 /** Interrupt on completion */ … … 587 624 bool fRCEnabled; 588 625 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 589 /** The HDA codec state. */ 590 R3PTRTYPE(PHDACODEC) pCodec[2]; 626 /** Number of active + allocated LUNs. Each 627 * LUN has a HDA driver assigned. */ 628 uint8_t cLUNs; 629 /** The HDA codec to use. */ 630 R3PTRTYPE(PHDACODEC) pCodec; 631 /** Array of active HDA drivers. */ 632 R3PTRTYPE(PHDADRIVER) paDrv[32]; 633 /** The device' software mixer. */ 634 R3PTRTYPE(PAUDIOMIXER) pMixer; 635 /** Audio sink for line input. */ 636 R3PTRTYPE(PAUDMIXSINK) pSinkLineIn; 637 /** Audio sink for microphone input. */ 638 R3PTRTYPE(PAUDMIXSINK) pSinkMicIn; 591 639 #else 640 R3PTRTYPE(PPDMIAUDIOCONNECTOR) pDrv; 641 /** The HDA codec to use. */ 592 642 R3PTRTYPE(PHDACODEC) pCodec; 593 #endif 643 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 594 644 uint64_t u64BaseTS; 595 645 /** 1.2.3.4.5.6.7. - someone please tell me what I'm counting! - .8.9.10... */ … … 646 696 static int hdaRegReadU8(PHDASTATE pThis, uint32_t iReg, uint32_t *pu32Value); 647 697 static int hdaRegWriteU8(PHDASTATE pThis, uint32_t iReg, uint32_t pu32Value); 698 699 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 700 static void hdaTransfer(PHDADRIVER pDrv, ENMSOUNDSOURCE enmSrc, uint32_t cbAvail); 701 #else 702 static void hdaTransfer(PHDACODEC pCodec, ENMSOUNDSOURCE enmSource, int cbAvail); 703 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 648 704 649 705 #ifdef IN_RING3 … … 774 830 { 0x000FC, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteSDBDPU , IA(SD3BDPU) }, /* ISD3 Buffer Descriptor List Pointer-Upper Base Address */ 775 831 776 { 0x00100, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24 , hdaRegWriteSDCTL , OA(SD4CTL) }, /* Output Stream Descriptor 0 (OSD0) Control */777 { 0x00103, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8 , hdaRegWriteSDSTS , OA(SD4STS) }, /* OSD 0Status */778 { 0x00104, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32 , hdaRegWriteU32 , OA(SD4LPIB) }, /* OSD 0Link Position In Buffer */779 { 0x00108, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteU32 , OA(SD4CBL) }, /* OSD 0Cyclic Buffer Length */780 { 0x0010C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , OA(SD4LVI) }, /* OSD 0Last Valid Index */781 { 0x0010E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , OA(SD4FIFOW) }, /* OSD 0FIFO Watermark */782 { 0x00110, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16 , hdaRegWriteSDFIFOS , OA(SD4FIFOS) }, /* OSD 0FIFO Size */783 { 0x00112, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16 , hdaRegWriteSDFMT , OA(SD4FMT) }, /* OSD 0Format */784 { 0x00118, 0x00004, 0xFFFFFF80, 0xFFFFFF80, hdaRegReadU32 , hdaRegWriteSDBDPL , OA(SD4BDPL) }, /* OSD 0Buffer Descriptor List Pointer-Lower Base Address */785 { 0x0011C, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteSDBDPU , OA(SD4BDPU) }, /* OSD 0Buffer Descriptor List Pointer-Upper Base Address */786 787 { 0x00120, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24 , hdaRegWriteSDCTL , OA(SD5CTL) }, /* Output Stream Descriptor 0 (OSD1) Control */788 { 0x00123, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8 , hdaRegWriteSDSTS , OA(SD5STS) }, /* OSD 1Status */789 { 0x00124, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32 , hdaRegWriteU32 , OA(SD5LPIB) }, /* OSD 1Link Position In Buffer */790 { 0x00128, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteU32 , OA(SD5CBL) }, /* OSD 1Cyclic Buffer Length */791 { 0x0012C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , OA(SD5LVI) }, /* OSD 1Last Valid Index */792 { 0x0012E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , OA(SD5FIFOW) }, /* OSD 1FIFO Watermark */793 { 0x00130, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16 , hdaRegWriteSDFIFOS , OA(SD5FIFOS) }, /* OSD 1FIFO Size */794 { 0x00132, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16 , hdaRegWriteSDFMT , OA(SD5FMT) }, /* OSD 1Format */795 { 0x00138, 0x00004, 0xFFFFFF80, 0xFFFFFF80, hdaRegReadU32 , hdaRegWriteSDBDPL , OA(SD5BDPL) }, /* OSD 1Buffer Descriptor List Pointer-Lower Base Address */796 { 0x0013C, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteSDBDPU , OA(SD5BDPU) }, /* OSD 1Buffer Descriptor List Pointer-Upper Base Address */797 798 { 0x00140, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24 , hdaRegWriteSDCTL , OA(SD6CTL) }, /* Output Stream Descriptor 0 (OSD2) Control */799 { 0x00143, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8 , hdaRegWriteSDSTS , OA(SD6STS) }, /* OSD 2Status */800 { 0x00144, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32 , hdaRegWriteU32 , OA(SD6LPIB) }, /* OSD 2Link Position In Buffer */801 { 0x00148, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteU32 , OA(SD6CBL) }, /* OSD 2Cyclic Buffer Length */802 { 0x0014C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , OA(SD6LVI) }, /* OSD 2Last Valid Index */803 { 0x0014E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , OA(SD6FIFOW) }, /* OSD 2FIFO Watermark */804 { 0x00150, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16 , hdaRegWriteSDFIFOS , OA(SD6FIFOS) }, /* OSD 2FIFO Size */805 { 0x00152, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16 , hdaRegWriteSDFMT , OA(SD6FMT) }, /* OSD 2Format */806 { 0x00158, 0x00004, 0xFFFFFF80, 0xFFFFFF80, hdaRegReadU32 , hdaRegWriteSDBDPL , OA(SD6BDPL) }, /* OSD 2Buffer Descriptor List Pointer-Lower Base Address */807 { 0x0015C, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteSDBDPU , OA(SD6BDPU) }, /* OSD 2Buffer Descriptor List Pointer-Upper Base Address */808 809 { 0x00160, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24 , hdaRegWriteSDCTL , OA(SD7CTL) }, /* Output Stream Descriptor 0 (OSD3) Control */810 { 0x00163, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8 , hdaRegWriteSDSTS , OA(SD7STS) }, /* OSD 3Status */811 { 0x00164, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32 , hdaRegWriteU32 , OA(SD7LPIB) }, /* OSD 3Link Position In Buffer */812 { 0x00168, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteU32 , OA(SD7CBL) }, /* OSD 3Cyclic Buffer Length */813 { 0x0016C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , OA(SD7LVI) }, /* OSD 3Last Valid Index */814 { 0x0016E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , OA(SD7FIFOW) }, /* OSD 3FIFO Watermark */815 { 0x00170, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16 , hdaRegWriteSDFIFOS , OA(SD7FIFOS) }, /* OSD 3FIFO Size */816 { 0x00172, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16 , hdaRegWriteSDFMT , OA(SD7FMT) }, /* OSD 3Format */817 { 0x00178, 0x00004, 0xFFFFFF80, 0xFFFFFF80, hdaRegReadU32 , hdaRegWriteSDBDPL , OA(SD7BDPL) }, /* OSD 3Buffer Descriptor List Pointer-Lower Base Address */818 { 0x0017C, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteSDBDPU , OA(SD7BDPU) }, /* OSD 3Buffer Descriptor List Pointer-Upper Base Address */832 { 0x00100, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24 , hdaRegWriteSDCTL , OA(SD4CTL) }, /* Output Stream Descriptor 4 (OSD4) Control */ 833 { 0x00103, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8 , hdaRegWriteSDSTS , OA(SD4STS) }, /* OSD4 Status */ 834 { 0x00104, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32 , hdaRegWriteU32 , OA(SD4LPIB) }, /* OSD4 Link Position In Buffer */ 835 { 0x00108, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteU32 , OA(SD4CBL) }, /* OSD4 Cyclic Buffer Length */ 836 { 0x0010C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , OA(SD4LVI) }, /* OSD4 Last Valid Index */ 837 { 0x0010E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , OA(SD4FIFOW) }, /* OSD4 FIFO Watermark */ 838 { 0x00110, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16 , hdaRegWriteSDFIFOS , OA(SD4FIFOS) }, /* OSD4 FIFO Size */ 839 { 0x00112, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16 , hdaRegWriteSDFMT , OA(SD4FMT) }, /* OSD4 Format */ 840 { 0x00118, 0x00004, 0xFFFFFF80, 0xFFFFFF80, hdaRegReadU32 , hdaRegWriteSDBDPL , OA(SD4BDPL) }, /* OSD4 Buffer Descriptor List Pointer-Lower Base Address */ 841 { 0x0011C, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteSDBDPU , OA(SD4BDPU) }, /* OSD4 Buffer Descriptor List Pointer-Upper Base Address */ 842 843 { 0x00120, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24 , hdaRegWriteSDCTL , OA(SD5CTL) }, /* Output Stream Descriptor 5 (OSD5) Control */ 844 { 0x00123, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8 , hdaRegWriteSDSTS , OA(SD5STS) }, /* OSD5 Status */ 845 { 0x00124, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32 , hdaRegWriteU32 , OA(SD5LPIB) }, /* OSD5 Link Position In Buffer */ 846 { 0x00128, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteU32 , OA(SD5CBL) }, /* OSD5 Cyclic Buffer Length */ 847 { 0x0012C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , OA(SD5LVI) }, /* OSD5 Last Valid Index */ 848 { 0x0012E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , OA(SD5FIFOW) }, /* OSD5 FIFO Watermark */ 849 { 0x00130, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16 , hdaRegWriteSDFIFOS , OA(SD5FIFOS) }, /* OSD5 FIFO Size */ 850 { 0x00132, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16 , hdaRegWriteSDFMT , OA(SD5FMT) }, /* OSD5 Format */ 851 { 0x00138, 0x00004, 0xFFFFFF80, 0xFFFFFF80, hdaRegReadU32 , hdaRegWriteSDBDPL , OA(SD5BDPL) }, /* OSD5 Buffer Descriptor List Pointer-Lower Base Address */ 852 { 0x0013C, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteSDBDPU , OA(SD5BDPU) }, /* OSD5 Buffer Descriptor List Pointer-Upper Base Address */ 853 854 { 0x00140, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24 , hdaRegWriteSDCTL , OA(SD6CTL) }, /* Output Stream Descriptor 6 (OSD6) Control */ 855 { 0x00143, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8 , hdaRegWriteSDSTS , OA(SD6STS) }, /* OSD6 Status */ 856 { 0x00144, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32 , hdaRegWriteU32 , OA(SD6LPIB) }, /* OSD6 Link Position In Buffer */ 857 { 0x00148, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteU32 , OA(SD6CBL) }, /* OSD6 Cyclic Buffer Length */ 858 { 0x0014C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , OA(SD6LVI) }, /* OSD6 Last Valid Index */ 859 { 0x0014E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , OA(SD6FIFOW) }, /* OSD6 FIFO Watermark */ 860 { 0x00150, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16 , hdaRegWriteSDFIFOS , OA(SD6FIFOS) }, /* OSD6 FIFO Size */ 861 { 0x00152, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16 , hdaRegWriteSDFMT , OA(SD6FMT) }, /* OSD6 Format */ 862 { 0x00158, 0x00004, 0xFFFFFF80, 0xFFFFFF80, hdaRegReadU32 , hdaRegWriteSDBDPL , OA(SD6BDPL) }, /* OSD6 Buffer Descriptor List Pointer-Lower Base Address */ 863 { 0x0015C, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteSDBDPU , OA(SD6BDPU) }, /* OSD6 Buffer Descriptor List Pointer-Upper Base Address */ 864 865 { 0x00160, 0x00003, 0x00FF001F, 0x00F0001F, hdaRegReadU24 , hdaRegWriteSDCTL , OA(SD7CTL) }, /* Output Stream Descriptor 7 (OSD7) Control */ 866 { 0x00163, 0x00001, 0x0000001C, 0x0000003C, hdaRegReadU8 , hdaRegWriteSDSTS , OA(SD7STS) }, /* OSD7 Status */ 867 { 0x00164, 0x00004, 0xFFFFFFFF, 0x00000000, hdaRegReadU32 , hdaRegWriteU32 , OA(SD7LPIB) }, /* OSD7 Link Position In Buffer */ 868 { 0x00168, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteU32 , OA(SD7CBL) }, /* OSD7 Cyclic Buffer Length */ 869 { 0x0016C, 0x00002, 0x0000FFFF, 0x0000FFFF, hdaRegReadU16 , hdaRegWriteSDLVI , OA(SD7LVI) }, /* OSD7 Last Valid Index */ 870 { 0x0016E, 0x00002, 0x00000007, 0x00000007, hdaRegReadU16 , hdaRegWriteSDFIFOW , OA(SD7FIFOW) }, /* OSD7 FIFO Watermark */ 871 { 0x00170, 0x00002, 0x000000FF, 0x000000FF, hdaRegReadU16 , hdaRegWriteSDFIFOS , OA(SD7FIFOS) }, /* OSD7 FIFO Size */ 872 { 0x00172, 0x00002, 0x00007F7F, 0x00007F7F, hdaRegReadU16 , hdaRegWriteSDFMT , OA(SD7FMT) }, /* OSD7 Format */ 873 { 0x00178, 0x00004, 0xFFFFFF80, 0xFFFFFF80, hdaRegReadU32 , hdaRegWriteSDBDPL , OA(SD7BDPL) }, /* OSD7 Buffer Descriptor List Pointer-Lower Base Address */ 874 { 0x0017C, 0x00004, 0xFFFFFFFF, 0xFFFFFFFF, hdaRegReadU32 , hdaRegWriteSDBDPU , OA(SD7BDPU) }, /* OSD7 Buffer Descriptor List Pointer-Upper Base Address */ 819 875 }; 820 876 … … 899 955 case HDA_SDFIFOW_32B: return 32; 900 956 default: 901 AssertMsgFailed((" hda:unsupported value (%x) in SDFIFOW(,%d)\n", HDA_REG_IND(pThis, pStreamDesc->u8Strm), pStreamDesc->u8Strm));957 AssertMsgFailed(("unsupported value (%x) in SDFIFOW(,%d)\n", HDA_REG_IND(pThis, pStreamDesc->u8Strm), pStreamDesc->u8Strm)); 902 958 } 903 959 #endif … … 923 979 if (HDA_REG_FLAG_VALUE(pThis, INTCTL, GIE)) 924 980 { 925 Log (("hda:irq %s\n", fIrq ? "asserted" : "deasserted"));981 LogFunc(("irq %s\n", fIrq ? "asserted" : "deasserted")); 926 982 PDMDevHlpPCISetIrq(pThis->CTX_SUFF(pDevIns), 0 , fIrq); 927 983 } … … 1050 1106 do 1051 1107 { 1052 Log (("hda:corb%02x: ", i));1108 LogFunc(("corb%02x: ", i)); 1053 1109 uint8_t j = 0; 1054 1110 do … … 1061 1117 else 1062 1118 prefix = " "; /* three spaces */ 1063 Log (("%s%08x", prefix, pThis->pu32CorbBuf[i + j]));1119 LogFunc(("%s%08x", prefix, pThis->pu32CorbBuf[i + j])); 1064 1120 j++; 1065 1121 } while (j < 8); 1066 Log (("\n"));1122 LogFunc(("\n")); 1067 1123 i += 8; 1068 1124 } while(i != 0); … … 1078 1134 uint8_t i = 0; 1079 1135 do { 1080 Log (("hda:rirb%02x: ", i));1136 LogFunc(("rirb%02x: ", i)); 1081 1137 uint8_t j = 0; 1082 1138 do { … … 1086 1142 else 1087 1143 prefix = " "; 1088 Log ((" %s%016lx", prefix, pThis->pu64RirbBuf[i + j]));1144 LogFunc((" %s%016lx", prefix, pThis->pu64RirbBuf[i + j])); 1089 1145 } while (++j < 8); 1090 Log (("\n"));1146 LogFunc(("\n")); 1091 1147 i += 8; 1092 1148 } while (i != 0); … … 1112 1168 rirbWp = HDA_REG(pThis, RIRBWP); 1113 1169 Assert((corbWp != corbRp)); 1114 Log (("hda:CORB(RP:%x, WP:%x) RIRBWP:%x\n", HDA_REG(pThis, CORBRP),1115 HDA_REG(pThis, CORBWP), HDA_REG(pThis, RIRBWP)));1170 LogFlowFunc(("CORB(RP:%x, WP:%x) RIRBWP:%x\n", HDA_REG(pThis, CORBRP), 1171 HDA_REG(pThis, CORBWP), HDA_REG(pThis, RIRBWP))); 1116 1172 while (corbRp != corbWp) 1117 1173 { … … 1121 1177 corbRp++; 1122 1178 cmd = pThis->pu32CorbBuf[corbRp]; 1123 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1124 for (uint32_t lun = 0; lun < 1; lun++) 1125 rc = pThis->pCodec[lun]->pfnLookup(pThis->pCodec[lun], cmd, &pfn); 1126 #else 1127 rc = pThis->pCodec->pfnLookup(pThis->pCodec, cmd, &pfn); 1128 #endif 1179 1180 rc = pThis->pCodec->pfnLookup(pThis->pCodec, 1181 HDA_CODEC_CMD(cmd, 0 /* Codec index */), 1182 &pfn); 1183 if (RT_SUCCESS(rc)) 1184 { 1185 rc = pfn(pThis->pCodec, 1186 HDA_CODEC_CMD(cmd, 0 /* LUN */), &resp); 1187 } 1188 1129 1189 if (RT_FAILURE(rc)) 1130 1190 AssertRCReturn(rc, rc); … … 1132 1192 (rirbWp)++; 1133 1193 1134 if (RT_LIKELY(pfn)) 1135 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1136 { 1137 for (uint32_t lun = 0; lun < 1; lun++) 1138 rc = pfn(pThis->pCodec[lun], cmd, &resp); 1139 } 1140 #else 1141 rc = pfn(pThis->pCodec, cmd, &resp); 1142 #endif 1143 else 1144 rc = VERR_INVALID_FUNCTION; 1145 1146 if (RT_FAILURE(rc)) 1147 AssertRCReturn(rc, rc); 1148 Log(("hda: verb:%08x->%016lx\n", cmd, resp)); 1194 LogFunc(("verb:%08x->%016lx\n", cmd, resp)); 1149 1195 if ( (resp & CODEC_RESPONSE_UNSOLICITED) 1150 1196 && !HDA_REG_FLAG_VALUE(pThis, GCTL, UR)) 1151 1197 { 1152 Log (("hda:unexpected unsolicited response.\n"));1198 LogFunc(("unexpected unsolicited response.\n")); 1153 1199 HDA_REG(pThis, CORBRP) = corbRp; 1154 1200 return rc; … … 1162 1208 HDA_REG(pThis, RIRBWP) = rirbWp; 1163 1209 rc = hdaCmdSync(pThis, false); 1164 Log (("hda:CORB(RP:%x, WP:%x) RIRBWP:%x\n", HDA_REG(pThis, CORBRP),1210 LogFunc(("CORB(RP:%x, WP:%x) RIRBWP:%x\n", HDA_REG(pThis, CORBRP), 1165 1211 HDA_REG(pThis, CORBWP), HDA_REG(pThis, RIRBWP))); 1166 1212 if (HDA_REG_FLAG_VALUE(pThis, RIRBCTL, RIC)) … … 1178 1224 static void hdaStreamReset(PHDASTATE pThis, PHDABDLEDESC pBdle, PHDASTREAMTRANSFERDESC pStreamDesc, uint8_t u8Strm) 1179 1225 { 1180 Log (("hda:reset of stream (%d) started\n", u8Strm));1226 LogFunc(("reset of stream (%d) started\n", u8Strm)); 1181 1227 Assert(( pThis 1182 1228 && pBdle 1183 1229 && pStreamDesc 1184 1230 && u8Strm <= 7)); 1185 memset(pBdle, 0, sizeof(HDABDLEDESC));1231 RT_BZERO(pBdle, sizeof(HDABDLEDESC)); 1186 1232 *pStreamDesc->pu32Lpib = 0; 1187 1233 *pStreamDesc->pu32Sts = 0; … … 1198 1244 HDA_STREAM_REG(pThis, BDPU, u8Strm) = 0; 1199 1245 HDA_STREAM_REG(pThis, BDPL, u8Strm) = 0; 1200 Log (("hda:reset of stream (%d) finished\n", u8Strm));1246 LogFunc(("reset of stream (%d) finished\n", u8Strm)); 1201 1247 } 1202 1248 … … 1286 1332 || HDA_REG_FLAG_VALUE(pThis, RIRBCTL, DMA)) 1287 1333 { 1288 Log (("hda:HDA enters in reset with DMA(RIRB:%s, CORB:%s)\n",1334 LogFunc(("HDA enters in reset with DMA(RIRB:%s, CORB:%s)\n", 1289 1335 HDA_REG_FLAG_VALUE(pThis, CORBCTL, DMA) ? "on" : "off", 1290 1336 HDA_REG_FLAG_VALUE(pThis, RIRBCTL, DMA) ? "on" : "off")); … … 1414 1460 */ 1415 1461 Assert((!fReset)); 1416 Log (("hda:guest initiated exit of stream reset.\n"));1462 LogFunc(("guest initiated exit of stream reset.\n")); 1417 1463 } 1418 1464 else if (fReset) … … 1432 1478 pBdle = &pThis->StInBdle; 1433 1479 break; 1480 case HDA_REG_SD2CTL: 1481 u8Strm = 2; 1482 pBdle = &pThis->StMicBdle; 1483 break; 1434 1484 case HDA_REG_SD4CTL: 1435 1485 u8Strm = 4; … … 1437 1487 break; 1438 1488 default: 1439 Log (("hda:changing SRST bit on non-attached stream\n"));1489 LogFunc(("changing SRST bit on non-attached stream\n")); 1440 1490 return hdaRegWriteU24(pThis, iReg, u32Value); 1441 1491 } 1442 Log (("hda:guest initiated enter to stream reset.\n"));1492 LogFunc(("guest initiated enter to stream reset.\n")); 1443 1493 hdaInitTransferDescriptor(pThis, pBdle, u8Strm, &StreamDesc); 1444 1494 hdaStreamReset(pThis, pBdle, &StreamDesc, u8Strm); … … 1458 1508 { 1459 1509 case HDA_REG_SD0CTL: 1460 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1461 for (uint32_t lun = 0; lun < 1; lun++) 1462 pThis->pDrv[lun]->pfnEnableIn(pThis->pDrv[lun], pThis->pCodec[lun]->SwVoiceIn, fRun); 1463 #else 1510 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1511 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 1512 pThis->paDrv[lun]->pConnector->pfnEnableIn(pThis->paDrv[lun]->pConnector, 1513 pThis->paDrv[lun]->pStrmIn, fRun); 1514 #else 1464 1515 AUD_set_active_in(pThis->pCodec->SwVoiceIn, fRun); 1465 #endif 1516 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1517 break; 1518 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1519 case HDA_REG_SD2CTL: 1520 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 1521 pThis->paDrv[lun]->pConnector->pfnEnableIn(pThis->paDrv[lun]->pConnector, 1522 pThis->paDrv[lun]->pStrmMic, fRun); 1523 #else 1524 1525 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1466 1526 break; 1467 1527 case HDA_REG_SD4CTL: 1468 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1469 for (uint32_t lun = 0; lun < 1; lun++) 1470 pThis->pDrv[lun]->pfnEnableOut(pThis->pDrv[lun], pThis->pCodec[lun]->SwVoiceOut, fRun); 1471 #else 1528 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1529 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 1530 pThis->paDrv[lun]->pConnector->pfnEnableOut(pThis->paDrv[lun]->pConnector, 1531 pThis->paDrv[lun]->pGstStrmOut, fRun); 1532 #else 1472 1533 AUD_set_active_out(pThis->pCodec->SwVoiceOut, fRun); 1473 #endif 1534 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1474 1535 break; 1475 1536 default: 1476 Log(("hda: changing RUN bit on non-attached stream\n"));1537 AssertMsgFailed(("Changing RUN bit on non-attached stream, register %RU32\n", iReg)); 1477 1538 break; 1478 1539 } 1479 1540 } 1480 #else 1541 #else /* !IN_RING3 */ 1481 1542 return VINF_IOM_R3_MMIO_WRITE; 1482 1543 #endif … … 1512 1573 return hdaRegWriteU16(pThis, iReg, u32Value); 1513 1574 default: 1514 Log (("hda:Attempt to store unsupported value(%x) in SDFIFOW\n", u32Value));1575 LogFunc(("Attempt to store unsupported value(%x) in SDFIFOW\n", u32Value)); 1515 1576 return hdaRegWriteU16(pThis, iReg, HDA_SDFIFOW_32B); 1516 1577 } … … 1531 1592 case HDA_REG_SD2FIFOS: 1532 1593 case HDA_REG_SD3FIFOS: 1533 Log (("hda: Guest tries change value of FIFO size of Input Stream\n"));1534 return VINF_SUCCESS;1594 LogFunc(("Guest tries change value of FIFO size of input stream\n")); 1595 break; 1535 1596 case HDA_REG_SD4FIFOS: 1536 1597 case HDA_REG_SD5FIFOS: … … 1547 1608 1548 1609 case HDA_SDONFIFO_256B: 1549 Log (("hda:256-bit is unsupported, HDA is switched into 192-bit mode\n"));1610 LogFunc(("256-bit is unsupported, HDA is switched into 192-bit mode\n")); 1550 1611 default: 1551 1612 return hdaRegWriteU16(pThis, iReg, HDA_SDONFIFO_192B); 1552 1613 } 1553 return VINF_SUCCESS;1614 break; 1554 1615 default: 1555 AssertMsgFailed(("Something weird happened with register lookup routine")); 1556 } 1616 AssertMsgFailed(("Something weird happened with register lookup routine\n")); 1617 } 1618 1557 1619 return VINF_SUCCESS; 1558 1620 } 1559 1621 1560 1622 #ifdef IN_RING3 1561 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1562 static void hdaSdFmtToAudSettings(uint32_t u32SdFmt, uint32_t * pFrequency, uint32_t * pChannels, audfmt_e *pFormat, uint32_t *pEndian) 1563 # else 1564 static void hdaSdFmtToAudSettings(uint32_t u32SdFmt, audsettings_t *pAudSetting) 1565 # endif 1566 { 1567 # ifndef VBOX_WITH_PDM_AUDIO_DRIVER 1568 Assert((pAudSetting)); 1569 # endif 1623 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1624 static int hdaSdFmtToAudSettings(uint32_t u32SdFmt, PPDMAUDIOSTREAMCFG pCfg) 1625 #else 1626 static int hdaSdFmtToAudSettings(uint32_t u32SdFmt, audsettings_t *pCfg) 1627 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1628 { 1629 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 1630 1570 1631 # define EXTRACT_VALUE(v, mask, shift) ((v & ((mask) << (shift))) >> (shift)) 1632 1633 int rc = VINF_SUCCESS; 1634 1571 1635 uint32_t u32Hz = (u32SdFmt & HDA_SDFMT_BASE_RATE_SHIFT) ? 44100 : 48000; 1572 1636 uint32_t u32HzMult = 1; 1573 1637 uint32_t u32HzDiv = 1; 1638 1574 1639 switch (EXTRACT_VALUE(u32SdFmt, HDA_SDFMT_MULT_MASK, HDA_SDFMT_MULT_SHIFT)) 1575 1640 { … … 1579 1644 case 3: u32HzMult = 4; break; 1580 1645 default: 1581 Log(("hda: unsupported multiplier %x\n", u32SdFmt)); 1646 LogFunc(("Unsupported multiplier %x\n", 1647 EXTRACT_VALUE(u32SdFmt, HDA_SDFMT_MULT_MASK, HDA_SDFMT_MULT_SHIFT))); 1648 rc = VERR_NOT_SUPPORTED; 1649 break; 1582 1650 } 1583 1651 switch (EXTRACT_VALUE(u32SdFmt, HDA_SDFMT_DIV_MASK, HDA_SDFMT_DIV_SHIFT)) … … 1591 1659 case 6: u32HzDiv = 7; break; 1592 1660 case 7: u32HzDiv = 8; break; 1593 } 1594 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1595 *pFrequency = u32Hz * u32HzMult / u32HzDiv; 1596 # else 1597 pAudSetting->freq = u32Hz * u32HzMult / u32HzDiv; 1598 # endif 1661 default: 1662 LogFunc(("Unsupported divisor %x\n", 1663 EXTRACT_VALUE(u32SdFmt, HDA_SDFMT_DIV_MASK, HDA_SDFMT_DIV_SHIFT))); 1664 rc = VERR_NOT_SUPPORTED; 1665 break; 1666 } 1667 1668 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1669 PDMAUDIOFMT enmFmt = AUD_FMT_S16; /* Default to 16-bit signed. */ 1670 #else 1671 audfmt_e enmFmt = AUD_FMT_S16; /* Default to 16-bit signed. */ 1672 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1599 1673 1600 1674 switch (EXTRACT_VALUE(u32SdFmt, HDA_SDFMT_BITS_MASK, HDA_SDFMT_BITS_SHIFT)) 1601 1675 { 1602 1676 case 0: 1603 Log (("hda:%s requested 8-bit\n", __FUNCTION__));1604 # 1605 *pFormat = AUD_FMT_S8;1606 # 1607 pAudSetting->fmt = AUD_FMT_S8;1608 # endif1677 LogFunc(("%s requested 8-bit\n", __FUNCTION__)); 1678 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1679 enmFmt = AUD_FMT_S8; 1680 #else 1681 enmFmt = AUD_FMT_S8; 1682 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1609 1683 break; 1610 1684 case 1: 1611 Log (("hda:%s requested 16-bit\n", __FUNCTION__));1612 # 1613 *pFormat = AUD_FMT_S16;1614 # 1615 pAudSetting->fmt = AUD_FMT_S16;1616 # endif1685 LogFunc(("%s requested 16-bit\n", __FUNCTION__)); 1686 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1687 enmFmt = AUD_FMT_S16; 1688 #else 1689 enmFmt = AUD_FMT_S16; 1690 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1617 1691 break; 1618 1692 case 2: 1619 Log (("hda:%s requested 20-bit\n", __FUNCTION__));1693 LogFunc(("%s requested 20-bit\n", __FUNCTION__)); 1620 1694 break; 1621 1695 case 3: 1622 Log (("hda:%s requested 24-bit\n", __FUNCTION__));1696 LogFunc(("%s requested 24-bit\n", __FUNCTION__)); 1623 1697 break; 1624 1698 case 4: 1625 Log (("hda:%s requested 32-bit\n", __FUNCTION__));1626 # 1627 *pFormat = AUD_FMT_S32;1628 # 1629 pAudSetting->fmt = AUD_FMT_S32;1630 # endif1699 LogFunc(("%s requested 32-bit\n", __FUNCTION__)); 1700 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1701 enmFmt = AUD_FMT_S32; 1702 #else 1703 enmFmt = AUD_FMT_S32; 1704 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1631 1705 break; 1632 1706 default: 1633 AssertMsgFailed(("Unsupported")); 1634 } 1635 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1636 *pChannels = (u32SdFmt & 0xf) + 1; 1637 *pFormat = AUD_FMT_S16; 1638 *pEndian = 0; 1639 # else 1640 pAudSetting->nchannels = (u32SdFmt & 0xf) + 1; 1641 pAudSetting->fmt = AUD_FMT_S16; 1642 pAudSetting->endianness = 0; 1643 # endif 1707 AssertMsgFailed(("Unsupported bits shift %x\n", 1708 EXTRACT_VALUE(u32SdFmt, HDA_SDFMT_BITS_MASK, HDA_SDFMT_BITS_SHIFT))); 1709 rc = VERR_NOT_SUPPORTED; 1710 break; 1711 } 1712 1713 if (RT_SUCCESS(rc)) 1714 { 1715 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1716 pCfg->uHz = u32Hz * u32HzMult / u32HzDiv; 1717 pCfg->cChannels = (u32SdFmt & 0xf) + 1; 1718 pCfg->enmFormat = enmFmt; 1719 pCfg->enmEndianness = PDMAUDIOHOSTENDIANESS; 1720 #else 1721 pCfg->nchannels = (u32SdFmt & 0xf) + 1; 1722 pCfg->fmt = enmFmt; 1723 pCfg->endianness = 0; 1724 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1725 } 1726 1644 1727 # undef EXTRACT_VALUE 1728 1729 return rc; 1645 1730 } 1646 1731 #endif … … 1650 1735 #ifdef IN_RING3 1651 1736 # ifdef VBOX_WITH_HDA_CODEC_EMU 1652 /** @todo a bit more investigation is required here. */ 1653 int rc = 0; 1654 /* no reason to reopen voice with same settings */ 1737 /* No reason to reopen voice with same settings. */ 1655 1738 if (u32Value == HDA_REG_IND(pThis, iReg)) 1656 1739 return VINF_SUCCESS; 1657 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1658 uint32_t uFrequency; 1659 uint32_t cChannels; 1660 audfmt_e Format; 1661 uint32_t Endian; 1662 hdaSdFmtToAudSettings(u32Value, &uFrequency, &cChannels, &Format, &Endian); 1663 # else 1664 audsettings_t as; 1665 hdaSdFmtToAudSettings(u32Value, &as); 1666 # endif 1740 1741 PDMAUDIOSTREAMCFG as; 1742 int rc = hdaSdFmtToAudSettings(u32Value, &as); 1743 if (RT_FAILURE(rc)) 1744 return rc; 1745 1667 1746 switch (iReg) 1668 1747 { 1669 1748 case HDA_REG_SD0FMT: 1670 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1671 for (uint32_t lun = 0; lun < 1; lun++) 1672 rc = hdaCodecOpenVoice(pThis->pCodec[lun], PI_INDEX, uFrequency, cChannels, Format, Endian); 1673 # else 1674 rc = hdaCodecOpenVoice(pThis->pCodec, PI_INDEX, &as); 1675 # endif 1749 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 1750 rc = hdaCodecOpenStream(pThis->pCodec, PI_INDEX, &as); 1676 1751 break; 1677 1752 case HDA_REG_SD4FMT: 1678 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1679 for (uint32_t lun = 0; lun < 1; lun++) 1680 rc = hdaCodecOpenVoice(pThis->pCodec[lun], PO_INDEX, uFrequency, cChannels, Format, Endian); 1681 # else 1682 rc = hdaCodecOpenVoice(pThis->pCodec, PO_INDEX, &as); 1683 # endif 1753 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 1754 rc = hdaCodecOpenStream(pThis->pCodec, PO_INDEX, &as); 1684 1755 break; 1685 1756 default: 1686 Log(("HDA: attempt to change format on %d\n", iReg)); 1687 rc = 0; 1688 } 1757 LogFunc(("Warning: Attempt to change format on register %d\n", iReg)); 1758 break; 1759 } 1760 1761 /** @todo r=andy rc gets lost; needs fixing. */ 1689 1762 return hdaRegWriteU16(pThis, iReg, u32Value); 1690 1763 # else … … 1726 1799 static int hdaRegWriteIRS(PHDASTATE pThis, uint32_t iReg, uint32_t u32Value) 1727 1800 { 1728 int rc= VINF_SUCCESS;1801 int rc = VINF_SUCCESS; 1729 1802 1730 1803 /* 1731 * ifguest set the ICB bit of IRS register, HDA should process the verb in IC register,1804 * If the guest set the ICB bit of IRS register, HDA should process the verb in IC register, 1732 1805 * write the response to IR register, and set the IRV (valid in case of success) bit of IRS register. 1733 1806 */ … … 1744 1817 * 3.4.3 defines behavior of immediate Command status register. 1745 1818 */ 1746 LogRel((" hda:guest attempted process immediate verb (%x) with active CORB\n", cmd));1819 LogRel(("guest attempted process immediate verb (%x) with active CORB\n", cmd)); 1747 1820 return rc; 1748 1821 } 1749 1822 HDA_REG(pThis, IRS) = HDA_REG_FIELD_FLAG_MASK(IRS, ICB); /* busy */ 1750 Log(("hda: IC:%x\n", cmd)); 1751 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1752 for (uint32_t lun = 0; lun < 1; lun++) 1753 rc = pThis->pCodec[lun]->pfnLookup(pThis->pCodec[lun], cmd, &pfn); 1823 LogFunc(("IC:%x\n", cmd)); 1824 # if 0 1825 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 1826 { 1827 rc = pThis->pCodec[lun]->pfnLookup(pThis->pCodec[lun], 1828 HDA_CODEC_CMD(cmd, lun), 1829 &pfn); 1830 if (RT_SUCCESS(rc)) 1831 { 1832 AssertPtr(pfn); 1833 rc = pfn(pThis->pCodec[lun], 1834 HDA_CODEC_CMD(cmd, lun), &resp); 1835 if (RT_FAILURE(rc)) 1836 break; 1837 } 1838 } 1754 1839 # else 1755 rc = pThis->pCodec->pfnLookup(pThis->pCodec, cmd, &pfn); 1756 # endif 1840 rc = pThis->pCodec->pfnLookup(pThis->pCodec, 1841 HDA_CODEC_CMD(cmd, 0 /* LUN */), 1842 &pfn); 1757 1843 if (RT_FAILURE(rc)) 1758 1844 AssertRCReturn(rc, rc); 1759 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1760 for (uint32_t lun = 0; lun < 1; lun++) 1761 rc = pfn(pThis->pCodec[lun], cmd, &resp); 1762 #else 1763 rc = pfn(pThis->pCodec, cmd, &resp); 1764 #endif 1845 rc = pfn(pThis->pCodec, 1846 HDA_CODEC_CMD(cmd, 0 /* LUN */), &resp); 1847 # endif 1848 1765 1849 if (RT_FAILURE(rc)) 1766 1850 AssertRCReturn(rc, rc); 1767 1851 HDA_REG(pThis, IR) = (uint32_t)resp; 1768 Log (("hda:IR:%x\n", HDA_REG(pThis, IR)));1852 LogFunc(("IR:%x\n", HDA_REG(pThis, IR))); 1769 1853 HDA_REG(pThis, IRS) = HDA_REG_FIELD_FLAG_MASK(IRS, IRV); /* result is ready */ 1770 1854 HDA_REG(pThis, IRS) &= ~HDA_REG_FIELD_FLAG_MASK(IRS, ICB); /* busy is clear */ 1771 #else 1855 #else /* !IN_RING3 */ 1772 1856 rc = VINF_IOM_R3_MMIO_WRITE; 1773 1857 #endif … … 1829 1913 default: 1830 1914 AssertMsgFailed(("Invalid index")); 1831 } 1832 Log(("hda: CORB base:%llx RIRB base: %llx DP base: %llx\n", pThis->u64CORBBase, pThis->u64RIRBBase, pThis->u64DPBase)); 1915 break; 1916 } 1917 1918 LogFunc(("CORB base:%llx RIRB base: %llx DP base: %llx\n", 1919 pThis->u64CORBBase, pThis->u64RIRBBase, pThis->u64DPBase)); 1833 1920 return rc; 1834 1921 } … … 1861 1948 len = *(uint32_t *)&bdle[8]; 1862 1949 ioc = *(uint32_t *)&bdle[12]; 1863 Log (("hda:%s bdle[%d] a:%llx, len:%d, ioc:%d\n", (i == pBdle->u32BdleCvi? "[C]": " "), i, addr, len, ioc & 0x1));1950 LogFunc(("%s bdle[%d] a:%llx, len:%d, ioc:%d\n", (i == pBdle->u32BdleCvi? "[C]": " "), i, addr, len, ioc & 0x1)); 1864 1951 sum += len; 1865 1952 } 1866 Log (("hda:sum: %d\n", sum));1953 LogFunc(("sum: %d\n", sum)); 1867 1954 for (i = 0; i < 8; ++i) 1868 1955 { 1869 1956 PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), (pThis->u64DPBase & DPBASE_ADDR_MASK) + i*8, &counter, sizeof(&counter)); 1870 Log (("hda:%s stream[%d] counter=%x\n", i == SDCTL_NUM(pThis, 4) || i == SDCTL_NUM(pThis, 0)? "[C]": " ",1957 LogFunc(("%s stream[%d] counter=%x\n", i == SDCTL_NUM(pThis, 4) || i == SDCTL_NUM(pThis, 0)? "[C]": " ", 1871 1958 i , counter)); 1872 1959 } … … 1918 2005 uint32_t *pu32DMACursor, uint32_t *pu32BackendBufferCapacity) 1919 2006 { 1920 Log (("hda:hdaBackendWriteTransferReported:cbArranged2Copy: %d, cbCopied: %d, pu32DMACursor: %d, pu32BackendBufferCapacity:%d\n",1921 cbArranged2Copy, cbCopied, pu32DMACursor ? *pu32DMACursor : 0, pu32BackendBufferCapacity ? *pu32BackendBufferCapacity : 0));2007 LogFunc(("cbArranged2Copy: %d, cbCopied: %d, pu32DMACursor: %d, pu32BackendBufferCapacity:%d\n", 2008 cbArranged2Copy, cbCopied, pu32DMACursor ? *pu32DMACursor : 0, pu32BackendBufferCapacity ? *pu32BackendBufferCapacity : 0)); 1922 2009 Assert((cbCopied)); 2010 AssertPtr(pu32DMACursor); 1923 2011 Assert((pu32BackendBufferCapacity && *pu32BackendBufferCapacity)); 1924 2012 /* Assertion!!! Fewer than cbUnderFifoW bytes were copied. … … 1929 2017 if ( pBdle->cbUnderFifoW 1930 2018 && pBdle->cbUnderFifoW <= cbCopied) 1931 Log(("hda:hdaBackendWriteTransferReported: CVI resetting cbUnderFifoW:%d(pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 2019 { 2020 LogFunc(("CVI resetting cbUnderFifoW:%d(pos:%d, len:%d)\n", 2021 pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 2022 } 1932 2023 1933 2024 pBdle->cbUnderFifoW -= RT_MIN(pBdle->cbUnderFifoW, cbCopied); … … 1942 2033 /* Decrease the backend counter by the number of bytes we copied to the backend */ 1943 2034 *pu32BackendBufferCapacity -= cbCopied; 1944 Log (("hda:hdaBackendWriteTransferReported:CVI(pos:%d, len:%d), pu32DMACursor: %d, pu32BackendBufferCapacity:%d\n",1945 pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, *pu32DMACursor, *pu32BackendBufferCapacity));2035 LogFunc(("CVI(pos:%d, len:%d), pu32DMACursor: %d, pu32BackendBufferCapacity:%d\n", 2036 pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, *pu32DMACursor, *pu32BackendBufferCapacity)); 1946 2037 } 1947 2038 … … 1952 2043 *pu32BackendBufferCapacity -= cbCopied; 1953 2044 pBdle->u32BdleCviPos += cbCopied; 1954 Log (("hda:hdaBackendReadTransferReported:CVI resetting cbUnderFifoW:%d(pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));2045 LogFunc(("CVI resetting cbUnderFifoW:%d(pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1955 2046 *pu32DMACursor += cbCopied + pBdle->cbUnderFifoW; 1956 2047 pBdle->cbUnderFifoW = 0; 1957 Log (("hda:hdaBackendReadTransferReported:CVI(pos:%d, len:%d), pu32DMACursor: %d, pu32BackendBufferCapacity:%d\n",2048 LogFunc(("CVI(pos:%d, len:%d), pu32DMACursor: %d, pu32BackendBufferCapacity:%d\n", 1958 2049 pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, pu32DMACursor ? *pu32DMACursor : 0, pu32BackendBufferCapacity ? *pu32BackendBufferCapacity : 0)); 1959 2050 } … … 1962 2053 uint32_t cbCopied, uint32_t *pu32BackendBufferCapacity) 1963 2054 { 1964 Log (("hda:hdaBackendTransferUnreported:CVI (cbUnderFifoW:%d, pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));2055 LogFunc(("CVI (cbUnderFifoW:%d, pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1965 2056 pBdle->u32BdleCviPos += cbCopied; 1966 2057 pBdle->cbUnderFifoW += cbCopied; … … 1968 2059 if (pu32BackendBufferCapacity) 1969 2060 *pu32BackendBufferCapacity -= cbCopied; 1970 Log (("hda:hdaBackendTransferUnreported:CVI (cbUnderFifoW:%d, pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen));2061 LogFunc(("CVI (cbUnderFifoW:%d, pos:%d, len:%d)\n", pBdle->cbUnderFifoW, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 1971 2062 Assert((pBdle->cbUnderFifoW <= hdaFifoWToSz(pThis, pStreamDesc))); 1972 2063 } … … 2012 2103 2013 2104 hdaUpdatePosBuf(pThis, pStreamDesc); 2014 2015 2105 } 2016 2106 } … … 2043 2133 } 2044 2134 2045 /* 2135 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2136 /** 2046 2137 * hdaReadAudio - copies samples from audio backend to DMA. 2047 * Note: this function writes to the DMA buffer immediately, but "reports bytes" when all conditions are met (FIFOW) 2138 * Note: This function writes to the DMA buffer immediately, 2139 * but "reports bytes" when all conditions are met (FIFOW). 2048 2140 */ 2141 static uint32_t hdaReadAudio(PHDASTATE pThis, PAUDMIXSINK pSink, PHDABDLEDESC pBdle, 2142 PHDASTREAMTRANSFERDESC pStreamDesc, 2143 uint32_t *pu32Avail, bool *fStop, uint32_t u32CblLimit) 2144 { 2145 uint32_t cbTransferred = 0; 2146 2147 LogFlowFunc(("CVI(pos:%d, len:%d)\n", pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 2148 2149 uint32_t cb2Copy = hdaCalculateTransferBufferLength(pBdle, pStreamDesc, *pu32Avail, u32CblLimit); 2150 if (!cb2Copy) 2151 { 2152 /* If we enter here we can't report "unreported bits". */ 2153 *fStop = true; 2154 } 2155 else 2156 { 2157 uint32_t cbRead = 0; 2158 int rc = audioMixerProcessSinkIn(pSink, pBdle->au8HdaBuffer, cb2Copy, &cbRead); 2159 if (RT_SUCCESS(rc)) 2160 { 2161 /* 2162 * Write the HDA DMA buffer. 2163 */ 2164 PDMDevHlpPCIPhysWrite(pThis->CTX_SUFF(pDevIns), 2165 pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, 2166 pBdle->au8HdaBuffer, cbRead); 2167 2168 /* Don't see any reason why cb2Copy would differ from cbRead. */ 2169 Assert((cbRead == cb2Copy && (*pu32Avail) >= cb2Copy)); /* sanity */ 2170 2171 if (pBdle->cbUnderFifoW + cbRead > hdaFifoWToSz(pThis, 0)) 2172 hdaBackendReadTransferReported(pBdle, cb2Copy, cbRead, &cbTransferred, pu32Avail); 2173 else 2174 { 2175 hdaBackendTransferUnreported(pThis, pBdle, pStreamDesc, cbRead, pu32Avail); 2176 *fStop = true; 2177 } 2178 } 2179 else 2180 *fStop = true; 2181 } 2182 2183 Assert((cbTransferred <= (SDFIFOS(pThis, 0) + 1))); 2184 LogFunc(("CVI(pos:%RU32, len:%RU32), cbTransferred: %RU32\n", 2185 pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, cbTransferred)); 2186 return cbTransferred; 2187 } 2188 #else 2049 2189 static uint32_t hdaReadAudio(PHDASTATE pThis, PHDASTREAMTRANSFERDESC pStreamDesc, uint32_t *pu32Avail, bool *fStop, uint32_t u32CblLimit) 2050 2190 { … … 2092 2232 return cbTransferred; 2093 2233 } 2234 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 2094 2235 2095 2236 static uint32_t hdaWriteAudio(PHDASTATE pThis, PHDASTREAMTRANSFERDESC pStreamDesc, uint32_t *pu32Avail, bool *fStop, uint32_t u32CblLimit) … … 2097 2238 PHDABDLEDESC pBdle = &pThis->StOutBdle; 2098 2239 uint32_t cbTransferred = 0; 2099 uint32_t cb 2Copy = 0; /* local byte counter (on local buffer)*/2100 uint32_t cbBackendCopy = 0; /* local byte counter, how many bytes copied to backend */ 2101 2102 Log(("hda:wa: CVI(cvi:%d, pos:%d, len:%d)\n", pBdle->u32BdleCvi, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 2103 2104 cb2Copy = hdaCalculateTransferBufferLength(pBdle, pStreamDesc, *pu32Avail, u32CblLimit);2240 uint32_t cbWrittenMax = 0; /* local byte counter, how many bytes copied to backend */ 2241 2242 LogFunc(("CVI(cvi:%RU32, pos:%RU32, len:%RU32)\n", pBdle->u32BdleCvi, pBdle->u32BdleCviPos, pBdle->u32BdleCviLen)); 2243 2244 /* Local byte counter (on local buffer). */ 2245 uint32_t cb2Copy = hdaCalculateTransferBufferLength(pBdle, pStreamDesc, *pu32Avail, u32CblLimit); 2105 2246 2106 2247 /* … … 2112 2253 else 2113 2254 { 2114 PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, pBdle->au8HdaBuffer + pBdle->cbUnderFifoW, cb2Copy); 2255 PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), 2256 pBdle->u64BdleCviAddr + pBdle->u32BdleCviPos, 2257 pBdle->au8HdaBuffer + pBdle->cbUnderFifoW, cb2Copy); 2258 2115 2259 /* 2116 * Write to audio backend. we should ensure that we have enough bytes to copy to the backend.2260 * Write to audio backend. We should ensure that we have enough bytes to copy to the backend. 2117 2261 */ 2118 2262 if (cb2Copy + pBdle->cbUnderFifoW >= hdaFifoWToSz(pThis, pStreamDesc)) 2119 2263 { 2120 /*2121 * Feed the newly fetched samples, including unreported ones, to the backend.2122 */2123 2264 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2124 for (uint32_t lun = 0; lun < 1; lun++) 2125 cbBackendCopy = pThis->pDrv[lun]->pfnWrite(pThis->pDrv[lun], pThis->pCodec[lun]->SwVoiceOut, pBdle->au8HdaBuffer, cb2Copy + pBdle->cbUnderFifoW); 2126 LogFlow(("cbBackendCopy write %d bytes \n", cbBackendCopy)); 2265 int rc; 2266 uint32_t cbWritten; 2267 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 2268 { 2269 rc = pThis->paDrv[lun]->pConnector->pfnWrite(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pGstStrmOut, 2270 pBdle->au8HdaBuffer, cb2Copy + pBdle->cbUnderFifoW, 2271 &cbWritten); 2272 if (RT_FAILURE(rc)) 2273 continue; 2274 2275 cbWrittenMax = RT_MAX(cbWrittenMax, cbWritten); 2276 } 2127 2277 #else 2128 cbBackendCopy = AUD_write (pThis->pCodec->SwVoiceOut, pBdle->au8HdaBuffer, cb2Copy + pBdle->cbUnderFifoW); 2129 #endif 2130 hdaBackendWriteTransferReported(pBdle, cb2Copy, cbBackendCopy, &cbTransferred, pu32Avail); 2278 cbWrittenMax = AUD_write (pThis->pCodec->SwVoiceOut, pBdle->au8HdaBuffer, cb2Copy + pBdle->cbUnderFifoW); 2279 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 2280 2281 hdaBackendWriteTransferReported(pBdle, cb2Copy, cbWrittenMax, &cbTransferred, pu32Avail); 2131 2282 } 2132 2283 else 2133 2284 { 2134 /* Not enough bytes to be processed and reported, we'll try our luck next time around */2285 /* Not enough bytes to be processed and reported, we'll try our luck next time around. */ 2135 2286 hdaBackendTransferUnreported(pThis, pBdle, pStreamDesc, cb2Copy, NULL); 2136 2287 *fStop = true; … … 2139 2290 2140 2291 Assert(cbTransferred <= SDFIFOS(pThis, 4) + 1); 2141 Log (("hda:wa: CVI(pos:%d, len:%d, cbTransferred:%d)\n", pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, cbTransferred));2292 LogFunc(("CVI(pos:%RU32, len:%RU32, cbTransferred:%RU32)\n", pBdle->u32BdleCviPos, pBdle->u32BdleCviLen, cbTransferred)); 2142 2293 return cbTransferred; 2143 2294 } … … 2148 2299 DECLCALLBACK(int) hdaCodecReset(PHDACODEC pCodec) 2149 2300 { 2150 PHDASTATE pThis = (PHDASTATE)pCodec->pvHDAState;2301 PHDASTATE pThis = pCodec->pHDAState; 2151 2302 NOREF(pThis); 2152 2303 return VINF_SUCCESS; … … 2158 2309 Assert(pThis); Assert(pBdle); Assert(pStreamDesc); Assert(u8Strm <= 7); 2159 2310 2160 memset(pStreamDesc, 0, sizeof(HDASTREAMTRANSFERDESC));2311 RT_BZERO(pStreamDesc, sizeof(HDASTREAMTRANSFERDESC)); 2161 2312 pStreamDesc->u8Strm = u8Strm; 2162 2313 pStreamDesc->u32Ctl = HDA_STREAM_REG(pThis, CTL, u8Strm); … … 2174 2325 && pBdle->u32BdleMaxCvi) 2175 2326 { 2176 Log (("Initialization of transfer descriptor:\n"));2327 LogFunc(("Initialization of transfer descriptor:\n")); 2177 2328 dump_bd(pThis, pBdle, pStreamDesc->u64BaseDMA); 2178 2329 } … … 2180 2331 } 2181 2332 2182 2183 /** 2184 * @interface_method_impl{HDACODEC,pfnTransfer} 2185 */ 2186 static DECLCALLBACK(void) hdaTransfer(PHDACODEC pCodec, ENMSOUNDSOURCE src, int avail) 2187 { 2188 PHDASTATE pThis = (PHDASTATE)pCodec->pvHDAState; 2189 uint8_t u8Strm = 0; 2190 PHDABDLEDESC pBdle = NULL; 2191 2192 switch (src) 2193 { 2333 static DECLCALLBACK(void) hdaCloseIn(PHDASTATE pThis, PDMAUDIORECSOURCE enmRecSource) 2334 { 2335 NOREF(pThis); 2336 NOREF(enmRecSource); 2337 LogFlowFuncEnter(); 2338 } 2339 2340 static DECLCALLBACK(void) hdaCloseOut(PHDASTATE pThis) 2341 { 2342 NOREF(pThis); 2343 LogFlowFuncEnter(); 2344 } 2345 2346 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2347 static void hdaMicInputCallback(void *pvDrv, uint32_t cbAvail) 2348 { 2349 PHDADRIVER pThis = (PHDADRIVER)pvDrv; 2350 hdaTransfer(pThis, MC_INDEX, cbAvail); 2351 } 2352 2353 static void hdaLineInputCallback(void *pvDrv, uint32_t cbAvail) 2354 { 2355 PHDADRIVER pThis = (PHDADRIVER)pvDrv; 2356 hdaTransfer(pThis, PI_INDEX, cbAvail); 2357 } 2358 2359 static void hdaOutputCallback(void *pvDrv, uint32_t cbFree) 2360 { 2361 PHDADRIVER pThis = (PHDADRIVER)pvDrv; 2362 hdaTransfer(pThis, PO_INDEX, cbFree); 2363 } 2364 2365 static DECLCALLBACK(int) hdaOpenIn(PHDASTATE pThis, 2366 const char *pszName, PDMAUDIORECSOURCE enmRecSource, 2367 PPDMAUDIOSTREAMCFG pCfg) 2368 { 2369 PDMAUDIOCALLBACK_FN pfnCallback; 2370 PAUDMIXSINK pSink; 2371 2372 switch (enmRecSource) 2373 { 2374 case PDMAUDIORECSOURCE_MIC: 2375 pfnCallback = hdaMicInputCallback; 2376 pSink = pThis->pSinkMicIn; 2377 break; 2378 case PDMAUDIORECSOURCE_LINE_IN: 2379 pfnCallback = hdaLineInputCallback; 2380 pSink = pThis->pSinkLineIn; 2381 break; 2382 default: 2383 AssertMsgFailed(("Audio source %ld not supported\n", enmRecSource)); 2384 return VERR_NOT_SUPPORTED; 2385 } 2386 2387 int rc; 2388 char *pszDesc; 2389 2390 Assert(pThis->cLUNs); 2391 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 2392 { 2393 if (RTStrAPrintf(&pszDesc, "[LUN#%RU8] %s", lun, pszName) <= 0) 2394 { 2395 rc = VERR_NO_MEMORY; 2396 break; 2397 } 2398 2399 PHDADRIVER pDrv = pThis->paDrv[lun]; 2400 rc = pDrv->pConnector->pfnOpenIn(pDrv->pConnector, 2401 pszDesc, enmRecSource, 2402 pfnCallback /* fnCallback */, pDrv /* pvCallback */, 2403 pCfg, 2404 &pDrv->pStrmIn); 2405 LogFlowFunc(("LUN#%RU8: Opened input \"%s\", with rc=%Rrc\n", lun, pszDesc, rc)); 2406 if (rc == VINF_SUCCESS) /* Note: Could return VWRN_ALREADY_EXISTS. */ 2407 { 2408 audioMixerRemoveStream(pSink, pDrv->phStrmIn); 2409 rc = audioMixerAddStreamIn(pSink, 2410 pDrv->pConnector, pDrv->pStrmIn, 2411 0 /* uFlags */, &pDrv->phStrmIn); 2412 } 2413 2414 RTStrFree(pszDesc); 2415 } 2416 2417 LogFlowFuncLeaveRC(rc); 2418 return rc; 2419 } 2420 2421 static DECLCALLBACK(int) hdaOpenOut(PHDASTATE pThis, 2422 const char *pszName, PPDMAUDIOSTREAMCFG pCfg) 2423 { 2424 int rc; 2425 2426 Assert(pThis->cLUNs); 2427 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 2428 { 2429 PHDADRIVER pDrv = pThis->paDrv[lun]; 2430 rc = pDrv->pConnector->pfnOpenOut(pDrv->pConnector, pszName, 2431 hdaOutputCallback /* fnCallback */, pDrv /* pvCallback */, 2432 pCfg, 2433 &pDrv->pGstStrmOut); 2434 } 2435 2436 LogFlowFuncLeaveRC(rc); 2437 return rc; 2438 } 2439 2440 static DECLCALLBACK(int) hdaSetVolume(PHDASTATE pThis, 2441 bool fMute, uint8_t uVolLeft, uint8_t uVolRight) 2442 { 2443 int rc; 2444 2445 Assert(pThis->cLUNs); 2446 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 2447 { 2448 PHDADRIVER pDrv = pThis->paDrv[lun]; 2449 rc = pDrv->pConnector->pfnSetVolume(pDrv->pConnector, 2450 fMute, uVolLeft, uVolRight); 2451 } 2452 2453 LogFlowFuncLeaveRC(rc); 2454 return rc; 2455 } 2456 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 2457 2458 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2459 static DECLCALLBACK(void) hdaTransfer(PHDADRIVER pDrv, 2460 ENMSOUNDSOURCE enmSrc, uint32_t cbAvail) 2461 { 2462 AssertPtrReturnVoid(pDrv); 2463 PHDASTATE pThis = pDrv->pHDAState; 2464 2465 LogFlowFunc(("pDrv=%p (LUN #%RU8), enmSrc=%ld, cbAvail=%RU32\n", 2466 pDrv, pDrv->uLUN, enmSrc, cbAvail)); 2467 #else 2468 static DECLCALLBACK(void) hdaTransfer(PHDACODEC pCodec, ENMSOUNDSOURCE enmSrc, int cbAvail) 2469 { 2470 AssertPtrReturnVoid(pCodec); 2471 PHDASTATE pThis = pCodec->pHDAState; 2472 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 2473 uint8_t u8Strm; 2474 PHDABDLEDESC pBdle; 2475 2476 switch (enmSrc) 2477 { 2478 case PI_INDEX: 2479 { 2480 u8Strm = 0; 2481 pBdle = &pThis->StInBdle; 2482 break; 2483 } 2484 2485 case MC_INDEX: 2486 { 2487 u8Strm = 2; 2488 pBdle = &pThis->StMicBdle; 2489 break; 2490 } 2491 2194 2492 case PO_INDEX: 2195 2493 { … … 2198 2496 break; 2199 2497 } 2200 case PI_INDEX: 2201 { 2202 u8Strm = 0; 2203 pBdle = &pThis->StInBdle; 2204 break; 2205 } 2498 2206 2499 default: 2500 AssertMsgFailed(("Unknown source index %ld\n", enmSrc)); 2207 2501 return; 2208 2502 } … … 2212 2506 2213 2507 bool fStop = false; 2214 while ( avail && !fStop)2508 while (cbAvail && !fStop) 2215 2509 { 2216 2510 Assert( (StreamDesc.u32Ctl & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)) 2217 && avail2511 && cbAvail 2218 2512 && StreamDesc.u64BaseDMA); 2219 2513 2220 2514 /* Fetch the Buffer Descriptor Entry (BDE). */ 2221 2222 2515 if (hdaIsTransferCountersOverlapped(pThis, pBdle, &StreamDesc)) 2223 2516 hdaFetchBdle(pThis, pBdle, &StreamDesc); 2517 2224 2518 *StreamDesc.pu32Sts |= HDA_REG_FIELD_FLAG_MASK(SDSTS, FIFORDY); 2225 Assert(( avail >= 0 && (StreamDesc.u32Cbl >= (*StreamDesc.pu32Lpib)))); /* sanity */2519 Assert((cbAvail >= 0 && (StreamDesc.u32Cbl >= (*StreamDesc.pu32Lpib)))); /* sanity */ 2226 2520 uint32_t u32CblLimit = StreamDesc.u32Cbl - (*StreamDesc.pu32Lpib); 2227 2521 Assert((u32CblLimit > hdaFifoWToSz(pThis, &StreamDesc))); 2228 Log(("hda: CBL=%d, LPIB=%d\n", StreamDesc.u32Cbl, *StreamDesc.pu32Lpib)); 2522 2523 LogFunc(("CBL=%RU32, LPIB=%RU32\n", StreamDesc.u32Cbl, *StreamDesc.pu32Lpib)); 2524 2525 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2526 PAUDMIXSINK pSink; 2527 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 2229 2528 uint32_t cb; 2230 switch ( src)2529 switch (enmSrc) 2231 2530 { 2531 case PI_INDEX: 2532 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2533 pSink = pThis->pSinkLineIn; 2534 cb = hdaReadAudio(pThis, pSink, pBdle, &StreamDesc, &cbAvail, &fStop, u32CblLimit); 2535 #else 2536 cb = hdaReadAudio(pThis, &StreamDesc, (uint32_t *)&cbAvail, &fStop, u32CblLimit); 2537 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 2538 break; 2232 2539 case PO_INDEX: 2233 cb = hdaWriteAudio(pThis, &StreamDesc, (uint32_t *)&avail, &fStop, u32CblLimit); 2540 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2541 cb = hdaWriteAudio(pThis, &StreamDesc, &cbAvail, &fStop, u32CblLimit); 2542 #else 2543 cb = hdaWriteAudio(pThis, &StreamDesc, (uint32_t *)&cbAvail, &fStop, u32CblLimit); 2544 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 2234 2545 break; 2235 case PI_INDEX: 2236 cb = hdaReadAudio(pThis, &StreamDesc, (uint32_t *)&avail, &fStop, u32CblLimit); 2546 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2547 case MC_INDEX: 2548 pSink = pThis->pSinkMicIn; 2549 cb = hdaReadAudio(pThis, pSink, pBdle, &StreamDesc, &cbAvail, &fStop, u32CblLimit); 2237 2550 break; 2551 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 2238 2552 default: 2239 2553 cb = 0; 2240 2554 fStop = true; 2241 AssertMsgFailed(("Unsupported")); 2555 AssertMsgFailedReturnVoid(("Unsupported source index %d\n", enmSrc)); 2556 break; 2242 2557 } 2243 2558 Assert(cb <= StreamDesc.u32Fifos + 1); … … 2249 2564 } 2250 2565 } 2251 #endif 2566 #endif /* IN_RING3 */ 2252 2567 2253 2568 /* MMIO callbacks */ … … 2275 2590 #endif 2276 2591 2277 Log (("hdaMMIORead:offReg=%#x cb=%#x\n", offReg, cb));2592 LogFunc(("offReg=%#x cb=%#x\n", offReg, cb)); 2278 2593 #define NEW_READ_CODE 2279 2594 #ifdef NEW_READ_CODE … … 2281 2596 2282 2597 if (pThis->fInReset && idxRegDsc != HDA_REG_GCTL) 2283 Log (("hda:access to registers except GCTL is blocked while reset\n"));2598 LogFunc(("access to registers except GCTL is blocked while reset\n")); 2284 2599 2285 2600 if (idxRegDsc == -1) 2286 LogRel((" hda:Invalid read access @0x%x(of bytes:%d)\n", offReg, cb));2601 LogRel(("Invalid read access @0x%x(of bytes:%d)\n", offReg, cb)); 2287 2602 2288 2603 if (idxRegDsc != -1) … … 2295 2610 */ 2296 2611 rc = g_aHdaRegMap[idxRegDsc].pfnRead(pThis, idxRegDsc, (uint32_t *)pv); 2297 Log (("hda:read %s => %x (%Rrc)\n", g_aHdaRegMap[idxRegDsc].abbrev, *(uint32_t *)pv, rc));2612 LogFunc(("read %s => %x (%Rrc)\n", g_aHdaRegMap[idxRegDsc].abbrev, *(uint32_t *)pv, rc)); 2298 2613 } 2299 2614 else … … 2311 2626 2312 2627 rc = g_aHdaRegMap[idxRegDsc].pfnRead(pThis, idxRegDsc, &u32Tmp); 2313 Log (("hda:read %s[%db] => %x (%Rrc)*\n", g_aHdaRegMap[idxRegDsc].abbrev, cbReg, u32Tmp, rc));2628 LogFunc(("read %s[%db] => %x (%Rrc)*\n", g_aHdaRegMap[idxRegDsc].abbrev, cbReg, u32Tmp, rc)); 2314 2629 if (rc != VINF_SUCCESS) 2315 2630 break; … … 2330 2645 { 2331 2646 rc = VINF_IOM_MMIO_UNUSED_FF; 2332 Log (("hda:hole at %x is accessed for read\n", offReg));2647 LogFunc(("hole at %x is accessed for read\n", offReg)); 2333 2648 } 2334 2649 #else … … 2368 2683 rc = g_aHdaRegMap[idxRegDsc].pfnRead(pThis, idxRegDsc, &u32Value); 2369 2684 *(uint32_t *)pv |= (u32Value & mask); 2370 Log (("hda:read %s[%x/%x]\n", g_aHdaRegMap[idxRegDsc].abbrev, u32Value, *(uint32_t *)pv));2685 LogFunc(("read %s[%x/%x]\n", g_aHdaRegMap[idxRegDsc].abbrev, u32Value, *(uint32_t *)pv)); 2371 2686 } 2372 2687 else 2373 2688 { 2374 2689 *(uint32_t *)pv = 0xFF; 2375 Log (("hda:hole at %x is accessed for read\n", offReg));2690 LogFunc(("hole at %x is accessed for read\n", offReg)); 2376 2691 rc = VINF_SUCCESS; 2377 2692 } … … 2383 2698 #ifdef LOG_ENABLED 2384 2699 if (cbLog == 4) 2385 Log (("hdaMMIORead:@%#05x -> %#010x %Rrc\n", offRegLog, *(uint32_t *)pv, rc));2700 LogFunc(("@%#05x -> %#010x %Rrc\n", offRegLog, *(uint32_t *)pv, rc)); 2386 2701 else if (cbLog == 2) 2387 Log (("hdaMMIORead:@%#05x -> %#06x %Rrc\n", offRegLog, *(uint16_t *)pv, rc));2702 LogFunc(("@%#05x -> %#06x %Rrc\n", offRegLog, *(uint16_t *)pv, rc)); 2388 2703 else if (cbLog == 1) 2389 Log (("hdaMMIORead:@%#05x -> %#04x %Rrc\n", offRegLog, *(uint8_t *)pv, rc));2704 LogFunc(("@%#05x -> %#04x %Rrc\n", offRegLog, *(uint8_t *)pv, rc)); 2390 2705 #endif 2391 2706 return rc; … … 2396 2711 { 2397 2712 if (pThis->fInReset && idxRegDsc != HDA_REG_GCTL) 2398 Log (("hda:access to registers except GCTL is blocked while reset\n")); /** @todo where is this enforced? */2713 LogFunc(("access to registers except GCTL is blocked while reset\n")); /** @todo where is this enforced? */ 2399 2714 2400 2715 uint32_t idxRegMem = g_aHdaRegMap[idxRegDsc].mem_idx; … … 2403 2718 #endif 2404 2719 int rc = g_aHdaRegMap[idxRegDsc].pfnWrite(pThis, idxRegDsc, u32Value); 2405 Log (("hda:write %#x -> %s[%db]; %x => %x%s\n", u32Value, g_aHdaRegMap[idxRegDsc].abbrev,2720 LogFunc(("write %#x -> %s[%db]; %x => %x%s\n", u32Value, g_aHdaRegMap[idxRegDsc].abbrev, 2406 2721 g_aHdaRegMap[idxRegDsc].size, u32CurValue, pThis->au32Regs[idxRegMem], pszLog)); 2407 2722 return rc; … … 2444 2759 2445 2760 #ifdef LOG_ENABLED 2446 uint32_t const u32LogOldValue = idxRegDsc != -1? pThis->au32Regs[idxRegMem] : UINT32_MAX;2761 uint32_t const u32LogOldValue = idxRegDsc >= 0 ? pThis->au32Regs[idxRegMem] : UINT32_MAX; 2447 2762 uint32_t const offRegLog = offReg; 2448 2763 int const idxRegLog = idxRegMem; 2449 2764 if (idxRegDsc == -1) 2450 Log (("hdaMMIOWrite:@%#05x u32=%#010x cb=%d\n", offReg, *(uint32_t const *)pv, cb));2765 LogFunc(("@%#05x u32=%#010x cb=%d\n", offReg, *(uint32_t const *)pv, cb)); 2451 2766 else if (cb == 4) 2452 Log (("hdaMMIOWrite:@%#05x u32=%#010x %s\n", offReg, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));2767 LogFunc(("@%#05x u32=%#010x %s\n", offReg, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev)); 2453 2768 else if (cb == 2) 2454 Log (("hdaMMIOWrite:@%#05x u16=%#06x (%#010x) %s\n", offReg, *(uint16_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));2769 LogFunc(("@%#05x u16=%#06x (%#010x) %s\n", offReg, *(uint16_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev)); 2455 2770 else if (cb == 1) 2456 Log (("hdaMMIOWrite:@%#05x u8=%#04x (%#010x) %s\n", offReg, *(uint8_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev));2457 if (idxRegDsc != -1&& g_aHdaRegMap[idxRegDsc].size != cb)2458 Log (("hdaMMIOWrite:size=%d != cb=%d!!\n", g_aHdaRegMap[idxRegDsc].size, cb));2771 LogFunc(("@%#05x u8=%#04x (%#010x) %s\n", offReg, *(uint8_t *)pv, *(uint32_t *)pv, g_aHdaRegMap[idxRegDsc].abbrev)); 2772 if (idxRegDsc >= 0 && g_aHdaRegMap[idxRegDsc].size != cb) 2773 LogFunc(("size=%d != cb=%d!!\n", g_aHdaRegMap[idxRegDsc].size, cb)); 2459 2774 #endif 2460 2775 … … 2467 2782 { 2468 2783 rc = hdaWriteReg(pThis, idxRegDsc, u64Value, ""); 2469 Log (("hdaMMIOWrite:@%#05x %#x -> %#x\n", offRegLog, u32LogOldValue,2784 LogFunc(("@%#05x %#x -> %#x\n", offRegLog, u32LogOldValue, 2470 2785 idxRegLog != -1 ? pThis->au32Regs[idxRegLog] : UINT32_MAX)); 2471 2786 } … … 2486 2801 u64Value <<= cbBefore * 8; 2487 2802 u64Value |= pThis->au32Regs[idxRegMem] & g_afMasks[cbBefore]; 2488 Log (("hdaMMIOWrite:Within register, supplied %u leading bits: %#llx -> %#llx ...\n",2803 LogFunc(("Within register, supplied %u leading bits: %#llx -> %#llx ...\n", 2489 2804 cbBefore * 8, ~g_afMasks[cbBefore] & u64Value, u64Value)); 2490 2805 } … … 2502 2817 { 2503 2818 u64Value |= pThis->au32Regs[idxRegMem] & g_afMasks[cbReg] & ~g_afMasks[cb]; 2504 Log (("hdaMMIOWrite:Supplying missing bits (%#x): %#llx -> %#llx ...\n",2819 LogFunc(("Supplying missing bits (%#x): %#llx -> %#llx ...\n", 2505 2820 g_afMasks[cbReg] & ~g_afMasks[cb], u64Value & g_afMasks[cb], u64Value)); 2506 2821 } 2507 2822 uint32_t u32LogOldVal = pThis->au32Regs[idxRegMem]; 2508 2823 rc = hdaWriteReg(pThis, idxRegDsc, u64Value, "*"); 2509 Log (("hdaMMIOWrite:@%#05x %#x -> %#x\n", offRegLog, u32LogOldVal,2824 LogFunc(("@%#05x %#x -> %#x\n", offRegLog, u32LogOldVal, 2510 2825 pThis->au32Regs[idxRegMem])); 2511 2826 } 2512 2827 else 2513 2828 { 2514 LogRel((" hda:Invalid write access @0x%x!\n", offReg));2829 LogRel(("Invalid write access @0x%x!\n", offReg)); 2515 2830 cbReg = 1; 2516 2831 } … … 2582 2897 2583 2898 rc = g_aHdaRegMap[idxRegDsc].pfnWrite(pThis, idxRegDsc, u32NewValue); 2584 Log (("hda:write %s:(%x) %x => %x\n", g_aHdaRegMap[idxRegDsc].abbrev, u32NewValue,2899 LogFunc(("write %s:(%x) %x => %x\n", g_aHdaRegMap[idxRegDsc].abbrev, u32NewValue, 2585 2900 u32CurValue, pThis->au32Regs[idxRegMem])); 2586 2901 } … … 2588 2903 rc = VINF_SUCCESS; 2589 2904 2590 Log (("hdaMMIOWrite:@%#05x %#x -> %#x\n", offRegLog, u32LogOldValue,2905 LogFunc(("@%#05x %#x -> %#x\n", offRegLog, u32LogOldValue, 2591 2906 idxRegLog != -1 ? pThis->au32Regs[idxRegLog] : UINT32_MAX)); 2592 2907 #endif … … 2658 2973 PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE); 2659 2974 /* Save Codec nodes states */ 2660 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2975 #if 0 2976 /** @todo Handle LUNs > 0! */ 2661 2977 hdaCodecSaveState(pThis->pCodec[0], pSSM); 2662 2978 #else … … 2689 3005 * Load Codec nodes states. 2690 3006 */ 2691 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 3007 #if 0 3008 /** @todo Handle LUNs > 0! */ 2692 3009 int rc = hdaCodecLoadState(pThis->pCodec[0], pSSM, uVersion); 2693 3010 #else … … 2727 3044 rc = SSMR3GetU32(pSSM, &cRegs); AssertRCReturn(rc, rc); 2728 3045 if (cRegs != RT_ELEMENTS(pThis->au32Regs)) 2729 LogRel((" hda:cRegs is %d, expected %d\n", cRegs, RT_ELEMENTS(pThis->au32Regs)));3046 LogRel(("cRegs is %d, expected %d\n", cRegs, RT_ELEMENTS(pThis->au32Regs))); 2730 3047 break; 2731 3048 … … 2743 3060 2744 3061 /* 2745 * Load HDA dmacounters.3062 * Load HDA DMA counters. 2746 3063 */ 2747 3064 uint32_t fFlags = uVersion <= HDA_SSM_VERSION_2 ? SSMSTRUCT_FLAGS_MEM_BAND_AID_RELAXED : 0; 2748 3065 PCSSMFIELD paFields = uVersion <= HDA_SSM_VERSION_2 ? g_aHdaBDLEDescFieldsOld : g_aHdaBDLEDescFields; 2749 SSMR3GetStructEx(pSSM, &pThis->StOutBdle, sizeof(pThis->StOutBdle), fFlags, paFields, NULL); 2750 SSMR3GetStructEx(pSSM, &pThis->StMicBdle, sizeof(pThis->StMicBdle), fFlags, paFields, NULL); 3066 rc = SSMR3GetStructEx(pSSM, &pThis->StOutBdle, sizeof(pThis->StOutBdle), fFlags, paFields, NULL); 3067 AssertRCReturn(rc, rc); 3068 rc = SSMR3GetStructEx(pSSM, &pThis->StMicBdle, sizeof(pThis->StMicBdle), fFlags, paFields, NULL); 3069 AssertRCReturn(rc, rc); 2751 3070 rc = SSMR3GetStructEx(pSSM, &pThis->StInBdle, sizeof(pThis->StInBdle), fFlags, paFields, NULL); 2752 3071 AssertRCReturn(rc, rc); … … 2755 3074 * Update stuff after the state changes. 2756 3075 */ 3076 bool fEnableIn = RT_BOOL(SDCTL(pThis, 0) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 3077 bool fEnableMicIn = RT_BOOL(SDCTL(pThis, 2) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 3078 bool fEnableOut = RT_BOOL(SDCTL(pThis, 4) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 3079 2757 3080 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2758 for (uint32_t lun = 0; lun < 1; lun++) 2759 { 2760 pThis->pDrv[lun]->pfnEnableIn(pThis->pDrv[lun], pThis->pCodec[lun]->SwVoiceIn, SDCTL(pThis, 0) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 2761 pThis->pDrv[lun]->pfnEnableOut(pThis->pDrv[lun], pThis->pCodec[lun]->SwVoiceOut, SDCTL(pThis, 4) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 3081 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 3082 { 3083 rc = pThis->paDrv[lun]->pConnector->pfnEnableIn(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmIn, 3084 fEnableIn); 3085 if (RT_FAILURE(rc)) 3086 break; 3087 rc = pThis->paDrv[lun]->pConnector->pfnEnableIn(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmMic, 3088 fEnableMicIn); 3089 if (RT_FAILURE(rc)) 3090 break; 3091 rc = pThis->paDrv[lun]->pConnector->pfnEnableOut(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pGstStrmOut, 3092 fEnableOut); 3093 if (RT_FAILURE(rc)) 3094 break; 2762 3095 } 2763 3096 #else 2764 3097 AUD_set_active_in(pThis->pCodec->SwVoiceIn, SDCTL(pThis, 0) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 2765 3098 AUD_set_active_out(pThis->pCodec->SwVoiceOut, SDCTL(pThis, 4) & HDA_REG_FIELD_FLAG_MASK(SDCTL, RUN)); 2766 #endif 2767 2768 pThis->u64CORBBase = RT_MAKE_U64(HDA_REG(pThis, CORBLBASE), HDA_REG(pThis, CORBUBASE)); 2769 pThis->u64RIRBBase = RT_MAKE_U64(HDA_REG(pThis, RIRBLBASE), HDA_REG(pThis, RIRBUBASE)); 2770 pThis->u64DPBase = RT_MAKE_U64(HDA_REG(pThis, DPLBASE), HDA_REG(pThis, DPUBASE)); 2771 return VINF_SUCCESS; 3099 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 3100 3101 if (RT_SUCCESS(rc)) 3102 { 3103 pThis->u64CORBBase = RT_MAKE_U64(HDA_REG(pThis, CORBLBASE), HDA_REG(pThis, CORBUBASE)); 3104 pThis->u64RIRBBase = RT_MAKE_U64(HDA_REG(pThis, RIRBLBASE), HDA_REG(pThis, RIRBUBASE)); 3105 pThis->u64DPBase = RT_MAKE_U64(HDA_REG(pThis, DPLBASE), HDA_REG(pThis, DPUBASE)); 3106 } 3107 3108 LogFlowFuncLeaveRC(rc); 3109 return rc; 2772 3110 } 2773 3111 … … 2880 3218 && iHdaIndex >= 0 2881 3219 && iHdaIndex < HDA_NREGS); 2882 pHlp->pfnPrintf(pHlp, " hda:%s: 0x%x\n", g_aHdaRegMap[iHdaIndex].abbrev, pThis->au32Regs[g_aHdaRegMap[iHdaIndex].mem_idx]);3220 pHlp->pfnPrintf(pHlp, "%s: 0x%x\n", g_aHdaRegMap[iHdaIndex].abbrev, pThis->au32Regs[g_aHdaRegMap[iHdaIndex].mem_idx]); 2883 3221 } 2884 3222 … … 2939 3277 { 2940 3278 PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE); 2941 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2942 for (uint32_t lun = 0; lun < 1; lun++) 3279 #if 0 3280 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 3281 { 2943 3282 if (pThis->pCodec[lun]->pfnCodecDbgListNodes) 2944 3283 pThis->pCodec[lun]->pfnCodecDbgListNodes(pThis->pCodec[lun], pHlp, pszArgs); 2945 3284 else 2946 pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback.\n"); 3285 pHlp->pfnPrintf(pHlp, "Codec implementation for LUN #%RU8 doesn't provide corresponding callback\n", lun); 3286 } 2947 3287 #else 2948 3288 if (pThis->pCodec->pfnCodecDbgListNodes) 2949 3289 pThis->pCodec->pfnCodecDbgListNodes(pThis->pCodec, pHlp, pszArgs); 2950 3290 else 2951 pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback .\n");3291 pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback\n"); 2952 3292 #endif 2953 3293 } … … 2960 3300 { 2961 3301 PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE); 2962 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2963 for (uint32_t lun = 0; lun < 1; lun++) 3302 #if 0 3303 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 3304 { 2964 3305 if (pThis->pCodec[lun]->pfnCodecDbgSelector) 2965 3306 pThis->pCodec[lun]->pfnCodecDbgSelector(pThis->pCodec[lun], pHlp, pszArgs); 2966 3307 else 2967 pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback.\n"); 3308 pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback\n"); 3309 } 2968 3310 #else 2969 3311 if (pThis->pCodec->pfnCodecDbgSelector) 2970 3312 pThis->pCodec->pfnCodecDbgSelector(pThis->pCodec, pHlp, pszArgs); 2971 3313 else 2972 pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback .\n");3314 pHlp->pfnPrintf(pHlp, "Codec implementation doesn't provide corresponding callback\n"); 2973 3315 #endif 2974 3316 } … … 3001 3343 * make sense to me so we'll do it. 3002 3344 */ 3003 static DECLCALLBACK(void) 3345 static DECLCALLBACK(void) hdaReset(PPDMDEVINS pDevIns) 3004 3346 { 3005 3347 PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE); … … 3014 3356 HDA_REG(pThis, RIRBWP) = 0x0; 3015 3357 3016 Log(("hda: inter HDA reset.\n")); 3017 3358 LogFunc(("Resetting ...\n")); 3359 3360 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 3018 3361 /* Stop any audio currently playing. */ 3019 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 3020 for (uint32_t lun = 0; lun < 1; lun++) 3021 { 3022 pThis->pDrv[lun]->pfnEnableIn(pThis->pDrv[lun], pThis->pCodec[lun]->SwVoiceIn, false); 3023 pThis->pDrv[lun]->pfnEnableOut(pThis->pDrv[lun], pThis->pCodec[lun]->SwVoiceOut, false); 3362 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 3363 { 3364 pThis->paDrv[lun]->pConnector->pfnEnableIn(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmIn, 3365 false /* Disable */); 3366 /* Ignore rc. */ 3367 pThis->paDrv[lun]->pConnector->pfnEnableIn(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pStrmMic, 3368 false /* Disable */); 3369 /* Ditto. */ 3370 pThis->paDrv[lun]->pConnector->pfnEnableOut(pThis->paDrv[lun]->pConnector, pThis->paDrv[lun]->pGstStrmOut, 3371 false /* Disable */); 3372 /* Ditto. */ 3024 3373 } 3025 3374 #else 3026 3375 AUD_set_active_in(pThis->pCodec->SwVoiceIn, false); 3027 3376 AUD_set_active_out(pThis->pCodec->SwVoiceOut, false); 3028 #endif 3029 3377 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 3030 3378 3031 3379 pThis->cbCorbBuf = 256 * sizeof(uint32_t); 3032 3380 3033 3381 if (pThis->pu32CorbBuf) 3034 memset(pThis->pu32CorbBuf, 0, pThis->cbCorbBuf);3382 RT_ZERO(pThis->pu32CorbBuf); 3035 3383 else 3036 3384 pThis->pu32CorbBuf = (uint32_t *)RTMemAllocZ(pThis->cbCorbBuf); … … 3038 3386 pThis->cbRirbBuf = 256 * sizeof(uint64_t); 3039 3387 if (pThis->pu64RirbBuf) 3040 memset(pThis->pu64RirbBuf, 0, pThis->cbRirbBuf);3388 RT_ZERO(pThis->pu64RirbBuf); 3041 3389 else 3042 3390 pThis->pu64RirbBuf = (uint64_t *)RTMemAllocZ(pThis->cbRirbBuf); … … 3051 3399 if (u8Strm == 0) 3052 3400 pBdle = &pThis->StInBdle; 3401 else if (u8Strm == 2) 3402 pBdle = &pThis->StMicBdle; 3053 3403 else if(u8Strm == 4) 3054 3404 pBdle = &pThis->StOutBdle; 3055 3405 else 3056 3406 { 3057 memset(&StEmptyBdle, 0, sizeof(HDABDLEDESC));3407 RT_ZERO(StEmptyBdle); 3058 3408 pBdle = &StEmptyBdle; 3059 3409 } … … 3067 3417 HDA_REG(pThis, STATESTS) = 0x1; 3068 3418 3069 Log(("hda: reset finished\n")); 3070 } 3071 3419 LogFunc(("Reset finished\n")); 3420 } 3072 3421 3073 3422 /** … … 3078 3427 PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE); 3079 3428 3429 if (pThis->pCodec) 3430 { 3431 int rc = hdaCodecDestruct(pThis->pCodec); 3432 AssertRC(rc); 3433 3434 RTMemFree(pThis->pCodec); 3435 pThis->pCodec = NULL; 3436 } 3437 3080 3438 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 3081 for (uint 32_t lun = 0; lun < 1; lun++)3082 { 3083 if (pThis->p Codec[lun])3439 for (uint8_t lun = 0; lun < pThis->cLUNs; lun++) 3440 { 3441 if (pThis->paDrv[lun]) 3084 3442 { 3085 int rc = hdaCodecDestruct(pThis->pCodec[lun]); 3086 AssertRC(rc); 3087 RTMemFree(pThis->pCodec[lun]); 3088 pThis->pCodec[lun] = NULL; 3443 RTMemFree(pThis->paDrv[lun]); 3444 pThis->paDrv[lun] = NULL; 3089 3445 } 3090 3446 } 3447 3448 if (pThis->pMixer) 3449 { 3450 audioMixerDestroy(pThis->pMixer); 3451 pThis->pMixer = NULL; 3452 } 3453 3454 pThis->cLUNs = 0; 3091 3455 #else 3092 3456 if (pThis->pCodec) … … 3098 3462 pThis->pCodec = NULL; 3099 3463 } 3100 #endif 3464 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 3101 3465 3102 3466 RTMemFree(pThis->pu32CorbBuf); … … 3108 3472 return VINF_SUCCESS; 3109 3473 } 3474 3475 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 3476 /** 3477 * Attach command. 3478 * 3479 * This is called to let the device attach to a driver for a specified LUN 3480 * during runtime. This is not called during VM construction, the device 3481 * constructor have to attach to all the available drivers. 3482 * 3483 * @returns VBox status code. 3484 * @param pDevIns The device instance. 3485 * @param uLUN The logical unit which is being detached. 3486 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines. 3487 */ 3488 static DECLCALLBACK(int) hdaAttach(PPDMDEVINS pDevIns, unsigned uLUN, uint32_t fFlags) 3489 { 3490 PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE); 3491 3492 AssertMsgReturn(fFlags & PDM_TACH_FLAGS_NOT_HOT_PLUG, 3493 ("HDA device does not support hotplugging\n"), 3494 VERR_INVALID_PARAMETER); 3495 3496 /* 3497 * Attach driver. 3498 */ 3499 char *pszDesc = NULL; 3500 if (RTStrAPrintf(&pszDesc, "Audio driver port (HDA) for LUN #%u", uLUN) <= 0) 3501 AssertMsgReturn(pszDesc, 3502 ("Not enough memory for HDA driver port description of LUN #%u\n", uLUN), 3503 VERR_NO_MEMORY); 3504 3505 int rc = PDMDevHlpDriverAttach(pDevIns, uLUN, 3506 &pThis->IBase, &pThis->pDrvBase, pszDesc); 3507 if (RT_SUCCESS(rc)) 3508 { 3509 PHDADRIVER pDrv = (PHDADRIVER)RTMemAllocZ(sizeof(HDADRIVER)); 3510 if (pDrv) 3511 { 3512 pDrv->pConnector = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR); 3513 AssertMsg(pDrv->pConnector != NULL, 3514 ("Configuration error: LUN #%u has no host audio interface, rc=%Rrc\n", 3515 uLUN, rc)); 3516 pDrv->pHDAState = pThis; 3517 pDrv->uLUN = uLUN; 3518 3519 pThis->paDrv[uLUN] = pDrv; 3520 pThis->cLUNs++; 3521 } 3522 else 3523 rc = VERR_NO_MEMORY; 3524 } 3525 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 3526 { 3527 LogFunc(("No attached driver for LUN #%u\n", uLUN)); 3528 } 3529 else if (RT_FAILURE(rc)) 3530 AssertMsgFailed(("Failed to attach HDA LUN #%u (\"%s\"), rc=%Rrc\n", 3531 uLUN, pszDesc, rc)); 3532 3533 RTStrFree(pszDesc); 3534 3535 LogFlowFunc(("iLUN=%u, fFlags=0x%x, rc=%Rrc\n", uLUN, fFlags, rc)); 3536 return rc; 3537 } 3538 3539 static DECLCALLBACK(void) hdaDetach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags) 3540 { 3541 NOREF(pDevIns); NOREF(iLUN); NOREF(fFlags); 3542 3543 LogFlowFuncEnter(); 3544 } 3545 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 3110 3546 3111 3547 /** … … 3114 3550 static DECLCALLBACK(int) hdaConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle) 3115 3551 { 3116 PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE); 3117 int rc; 3118 3552 PHDASTATE pThis = PDMINS_2_DATA(pDevIns, PHDASTATE); 3119 3553 Assert(iInstance == 0); 3120 3554 PDMDEV_CHECK_VERSIONS_RETURN(pDevIns); … … 3128 3562 N_ ("Invalid configuration for the Intel HDA device")); 3129 3563 3130 rc = CFGMR3QueryBoolDef(pCfgHandle, "RCEnabled", &pThis->fRCEnabled, false);3564 int rc = CFGMR3QueryBoolDef(pCfgHandle, "RCEnabled", &pThis->fRCEnabled, false); 3131 3565 if (RT_FAILURE(rc)) 3132 3566 return PDMDEV_SET_ERROR(pDevIns, rc, … … 3251 3685 if (RT_FAILURE(rc)) 3252 3686 return rc; 3687 3253 3688 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 3254 //for (iter = 0; i < 3; i++) 3255 { 3256 /* 3257 * Attach driver. 3258 */ 3259 rc = PDMDevHlpDriverAttach(pDevIns, 0, &pThis->IBase, &pThis->pDrvBase, "Audio Driver Port"); 3689 /* We support 32 LUNs max. This should be enough for now. */ 3690 for (uint8_t lun = 0; lun < 32 ; lun++) 3691 { 3692 LogFunc(("Trying to attach driver for LUN #%RU32 ...\n", lun)); 3693 rc = hdaAttach(pDevIns, lun, PDM_TACH_FLAGS_NOT_HOT_PLUG); 3694 if (RT_FAILURE(rc)) 3695 { 3696 if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 3697 rc = VINF_SUCCESS; 3698 break; 3699 } 3700 } 3701 3702 if (RT_SUCCESS(rc)) 3703 { 3704 rc = audioMixerCreate("HDA Mixer", 0 /* uFlags */, 3705 &pThis->pMixer); 3260 3706 if (RT_SUCCESS(rc)) 3261 3707 { 3262 pThis->pDrv[0] = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR); 3263 AssertMsgReturn(pThis->pDrv, 3264 ("Configuration error: instance %d has no host audio interface!\n", iInstance), 3265 VERR_PDM_MISSING_INTERFACE); 3708 PDMAUDIOSTREAMCFG streamCfg; 3709 streamCfg.uHz = 48000; 3710 streamCfg.cChannels = 2; 3711 streamCfg.enmFormat = AUD_FMT_S16; 3712 streamCfg.enmEndianness = PDMAUDIOHOSTENDIANESS; 3713 3714 rc = audioMixerSetDeviceFormat(pThis->pMixer, &streamCfg); 3715 AssertRC(rc); 3716 3717 /* Add all required audio sinks. */ 3718 rc = audioMixerAddSink(pThis->pMixer, "[Recording] Line In", 3719 &pThis->pSinkLineIn); 3720 AssertRC(rc); 3721 3722 rc = audioMixerAddSink(pThis->pMixer, "[Recording] Microphone In", 3723 &pThis->pSinkMicIn); 3724 AssertRC(rc); 3266 3725 } 3267 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 3268 { 3269 Log(("ac97: No attached driver!\n")); 3270 } 3271 else if (RT_FAILURE(rc)) 3272 { 3273 AssertMsgFailed(("Failed to attach AC97 LUN #0! rc=%Rrc\n", rc)); 3274 return rc; 3275 } 3276 rc = PDMDevHlpDriverAttach(pDevIns, 1, &pThis->IBase, &pThis->pDrvBase, "Audio Driver Port"); 3277 if (RT_SUCCESS(rc)) 3278 { 3279 pThis->pDrv[1] = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIAUDIOCONNECTOR); 3280 AssertMsgReturn(pThis->pDrv[1], 3281 ("Configuration error: instance %d has no host audio interface!\n", iInstance), 3282 VERR_PDM_MISSING_INTERFACE); 3283 } 3284 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 3285 { 3286 Log(("ac97: No attached driver! LUN#1\n")); 3287 } 3288 else if (RT_FAILURE(rc)) 3289 { 3290 AssertMsgFailed(("Failed to attach AC97 LUN #1! rc=%Rrc\n", rc)); 3291 return rc; 3292 } 3293 } 3726 } 3727 3728 LogFunc(("cLUNs=%RU8, rc=%Rrc\n", pThis->cLUNs, rc)); 3294 3729 #else 3295 3730 /* … … 3304 3739 return rc; 3305 3740 } 3306 #endif 3307 /* Construct codec state. */ 3741 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 3742 3743 if (RT_SUCCESS(rc)) 3744 { 3745 /* Construct codec. */ 3746 pThis->pCodec = (PHDACODEC)RTMemAllocZ(sizeof(HDACODEC)); 3747 if (!pThis->pCodec) 3748 return PDMDEV_SET_ERROR(pDevIns, VERR_NO_MEMORY, N_("Out of memory allocating HDA codec state")); 3749 3308 3750 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 3309 pThis->pCodec[0] = (PHDACODEC)RTMemAllocZ(sizeof(HDACODEC)); 3310 if (!pThis->pCodec[0]) 3311 return PDMDEV_SET_ERROR(pDevIns, VERR_NO_MEMORY, N_("HDA: Out of memory allocating codec state")); 3312 pThis->pCodec[1] = (PHDACODEC)RTMemAllocZ(sizeof(HDACODEC)); 3313 if (!pThis->pCodec[1]) 3314 return PDMDEV_SET_ERROR(pDevIns, VERR_NO_MEMORY, N_("HDA: Out of memory allocating codec state")); 3315 3316 pThis->pCodec[0]->pvHDAState = pThis; 3317 pThis->pCodec[1]->pvHDAState = pThis; 3318 3319 pThis->pCodec[0]->pDrv = pThis->pDrv[0]; 3320 //pThis->pCodec[1]->pDrv = pThis->pDrv[1]; 3321 3322 rc = hdaCodecConstruct(pDevIns, pThis->pCodec[0], pCfgHandle); 3323 if (RT_FAILURE(rc)) 3324 AssertRCReturn(rc, rc); 3325 rc = hdaCodecConstruct(pDevIns, pThis->pCodec[1], pCfgHandle); 3326 if (RT_FAILURE(rc)) 3327 AssertRCReturn(rc, rc); 3328 3329 /* ICH6 datasheet defines 0 values for SVID and SID (18.1.14-15), which together with values returned for 3330 verb F20 should provide device/codec recognition. */ 3331 Assert(pThis->pCodec[0]->u16VendorId); 3332 Assert(pThis->pCodec[0]->u16DeviceId); 3333 Assert(pThis->pCodec[1]->u16VendorId); 3334 Assert(pThis->pCodec[1]->u16DeviceId); 3335 PCIDevSetSubSystemVendorId(&pThis->PciDev, pThis->pCodec[0]->u16VendorId); /* 2c ro - intel.) */ 3336 PCIDevSetSubSystemId( &pThis->PciDev, pThis->pCodec[0]->u16DeviceId); /* 2e ro. */ 3337 PCIDevSetSubSystemVendorId(&pThis->PciDev, pThis->pCodec[1]->u16VendorId); /* 2c ro - intel.) */ 3338 PCIDevSetSubSystemId( &pThis->PciDev, pThis->pCodec[1]->u16DeviceId); /* 2e ro. */ 3339 3340 hdaReset(pDevIns); 3341 pThis->pCodec[0]->id = 0; 3342 pThis->pCodec[0]->pfnTransfer = hdaTransfer; 3343 pThis->pCodec[0]->pfnReset = hdaCodecReset; 3344 pThis->pCodec[1]->id = 0; 3345 pThis->pCodec[1]->pfnTransfer = hdaTransfer; 3346 pThis->pCodec[1]->pfnReset = hdaCodecReset; 3347 #else 3348 pThis->pCodec = (PHDACODEC)RTMemAllocZ(sizeof(HDACODEC)); 3349 if (!pThis->pCodec) 3350 return PDMDEV_SET_ERROR(pDevIns, VERR_NO_MEMORY, N_("HDA: Out of memory allocating codec state")); 3351 3352 pThis->pCodec->pvHDAState = pThis; 3353 rc = hdaCodecConstruct(pDevIns, pThis->pCodec, pCfgHandle); 3354 if (RT_FAILURE(rc)) 3355 AssertRCReturn(rc, rc); 3356 3357 /* ICH6 datasheet defines 0 values for SVID and SID (18.1.14-15), which together with values returned for 3358 verb F20 should provide device/codec recognition. */ 3359 Assert(pThis->pCodec->u16VendorId); 3360 Assert(pThis->pCodec->u16DeviceId); 3361 PCIDevSetSubSystemVendorId(&pThis->PciDev, pThis->pCodec->u16VendorId); /* 2c ro - intel.) */ 3362 PCIDevSetSubSystemId( &pThis->PciDev, pThis->pCodec->u16DeviceId); /* 2e ro. */ 3363 3364 hdaReset(pDevIns); 3365 pThis->pCodec->id = 0; 3366 pThis->pCodec->pfnTransfer = hdaTransfer; 3367 pThis->pCodec->pfnReset = hdaCodecReset; 3368 3369 /* 3370 * 18.2.6,7 defines that values of this registers might be cleared on power on/reset 3371 * hdaReset shouldn't affects these registers. 3372 */ 3373 HDA_REG(pThis, WAKEEN) = 0x0; 3374 HDA_REG(pThis, STATESTS) = 0x0; 3375 #endif 3376 /* 3377 * Debug and string formatter types. 3378 */ 3379 PDMDevHlpDBGFInfoRegister(pDevIns, "hda", "HDA info. (hda [register case-insensitive])", hdaInfo); 3380 PDMDevHlpDBGFInfoRegister(pDevIns, "hdastrm", "HDA stream info. (hdastrm [stream number])", hdaInfoStream); 3381 PDMDevHlpDBGFInfoRegister(pDevIns, "hdcnodes", "HDA codec nodes.", hdaInfoCodecNodes); 3382 PDMDevHlpDBGFInfoRegister(pDevIns, "hdcselector", "HDA codec's selector states [node number].", hdaInfoCodecSelector); 3383 3384 rc = RTStrFormatTypeRegister("sdctl", hdaFormatStrmCtl, NULL); 3385 AssertRC(rc); 3386 rc = RTStrFormatTypeRegister("sdsts", hdaFormatStrmSts, NULL); 3387 AssertRC(rc); 3388 rc = RTStrFormatTypeRegister("sdfifos", hdaFormatStrmFifos, NULL); 3389 AssertRC(rc); 3390 rc = RTStrFormatTypeRegister("sdfifow", hdaFormatStrmFifow, NULL); 3391 AssertRC(rc); 3392 #if 0 3393 rc = RTStrFormatTypeRegister("sdfmt", printHdaStrmFmt, NULL); 3394 AssertRC(rc); 3395 #endif 3396 3397 /* 3398 * Some debug assertions. 3399 */ 3400 for (unsigned i = 0; i < RT_ELEMENTS(g_aHdaRegMap); i++) 3401 { 3402 struct HDAREGDESC const *pReg = &g_aHdaRegMap[i]; 3403 struct HDAREGDESC const *pNextReg = i + 1 < RT_ELEMENTS(g_aHdaRegMap) ? &g_aHdaRegMap[i + 1] : NULL; 3404 3405 /* binary search order. */ 3406 AssertReleaseMsg(!pNextReg || pReg->offset + pReg->size <= pNextReg->offset, 3407 ("[%#x] = {%#x LB %#x} vs. [%#x] = {%#x LB %#x}\n", 3408 i, pReg->offset, pReg->size, i + 1, pNextReg->offset, pNextReg->size)); 3409 3410 /* alignment. */ 3411 AssertReleaseMsg( pReg->size == 1 3412 || (pReg->size == 2 && (pReg->offset & 1) == 0) 3413 || (pReg->size == 3 && (pReg->offset & 3) == 0) 3414 || (pReg->size == 4 && (pReg->offset & 3) == 0), 3415 ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size)); 3416 3417 /* registers are packed into dwords - with 3 exceptions with gaps at the end of the dword. */ 3418 AssertRelease(((pReg->offset + pReg->size) & 3) == 0 || pNextReg); 3419 if (pReg->offset & 3) 3751 /* Audio driver callbacks for multiplexing. */ 3752 pThis->pCodec->pfnCloseIn = hdaCloseIn; 3753 pThis->pCodec->pfnCloseOut = hdaCloseOut; 3754 pThis->pCodec->pfnOpenIn = hdaOpenIn; 3755 pThis->pCodec->pfnOpenOut = hdaOpenOut; 3756 pThis->pCodec->pfnSetVolume = hdaSetVolume; 3757 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 3758 3759 pThis->pCodec->pHDAState = pThis; /* Assign HDA controller state to codec. */ 3760 3761 /* Construct the codec. */ 3762 rc = hdaCodecConstruct(pDevIns, pThis->pCodec, 0 /* Codec index */, pCfgHandle); 3763 if (RT_FAILURE(rc)) 3764 AssertRCReturn(rc, rc); 3765 3766 /* ICH6 datasheet defines 0 values for SVID and SID (18.1.14-15), which together with values returned for 3767 verb F20 should provide device/codec recognition. */ 3768 Assert(pThis->pCodec->u16VendorId); 3769 Assert(pThis->pCodec->u16DeviceId); 3770 PCIDevSetSubSystemVendorId(&pThis->PciDev, pThis->pCodec->u16VendorId); /* 2c ro - intel.) */ 3771 PCIDevSetSubSystemId( &pThis->PciDev, pThis->pCodec->u16DeviceId); /* 2e ro. */ 3772 3773 pThis->pCodec->pfnTransfer = hdaTransfer; 3774 pThis->pCodec->pfnReset = hdaCodecReset; 3775 } 3776 3777 if (RT_SUCCESS(rc)) 3778 { 3779 hdaReset(pDevIns); 3780 3781 /* 3782 * 18.2.6,7 defines that values of this registers might be cleared on power on/reset 3783 * hdaReset shouldn't affects these registers. 3784 */ 3785 HDA_REG(pThis, WAKEEN) = 0x0; 3786 HDA_REG(pThis, STATESTS) = 0x0; 3787 3788 /* 3789 * Debug and string formatter types. 3790 */ 3791 PDMDevHlpDBGFInfoRegister(pDevIns, "hda", "HDA info. (hda [register case-insensitive])", hdaInfo); 3792 PDMDevHlpDBGFInfoRegister(pDevIns, "hdastrm", "HDA stream info. (hdastrm [stream number])", hdaInfoStream); 3793 PDMDevHlpDBGFInfoRegister(pDevIns, "hdcnodes", "HDA codec nodes.", hdaInfoCodecNodes); 3794 PDMDevHlpDBGFInfoRegister(pDevIns, "hdcselector", "HDA codec's selector states [node number].", hdaInfoCodecSelector); 3795 3796 rc = RTStrFormatTypeRegister("sdctl", hdaFormatStrmCtl, NULL); 3797 AssertRC(rc); 3798 rc = RTStrFormatTypeRegister("sdsts", hdaFormatStrmSts, NULL); 3799 AssertRC(rc); 3800 rc = RTStrFormatTypeRegister("sdfifos", hdaFormatStrmFifos, NULL); 3801 AssertRC(rc); 3802 rc = RTStrFormatTypeRegister("sdfifow", hdaFormatStrmFifow, NULL); 3803 AssertRC(rc); 3804 #if 0 3805 rc = RTStrFormatTypeRegister("sdfmt", printHdaStrmFmt, NULL); 3806 AssertRC(rc); 3807 #endif 3808 3809 /* 3810 * Some debug assertions. 3811 */ 3812 for (unsigned i = 0; i < RT_ELEMENTS(g_aHdaRegMap); i++) 3420 3813 { 3421 struct HDAREGDESC const *pPrevReg = i > 0 ? &g_aHdaRegMap[i - 1] : NULL; 3422 AssertReleaseMsg(pPrevReg, ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size)); 3423 if (pPrevReg) 3424 AssertReleaseMsg(pPrevReg->offset + pPrevReg->size == pReg->offset, 3425 ("[%#x] = {%#x LB %#x} vs. [%#x] = {%#x LB %#x}\n", 3426 i - 1, pPrevReg->offset, pPrevReg->size, i + 1, pReg->offset, pReg->size)); 3814 struct HDAREGDESC const *pReg = &g_aHdaRegMap[i]; 3815 struct HDAREGDESC const *pNextReg = i + 1 < RT_ELEMENTS(g_aHdaRegMap) ? &g_aHdaRegMap[i + 1] : NULL; 3816 3817 /* binary search order. */ 3818 AssertReleaseMsg(!pNextReg || pReg->offset + pReg->size <= pNextReg->offset, 3819 ("[%#x] = {%#x LB %#x} vs. [%#x] = {%#x LB %#x}\n", 3820 i, pReg->offset, pReg->size, i + 1, pNextReg->offset, pNextReg->size)); 3821 3822 /* alignment. */ 3823 AssertReleaseMsg( pReg->size == 1 3824 || (pReg->size == 2 && (pReg->offset & 1) == 0) 3825 || (pReg->size == 3 && (pReg->offset & 3) == 0) 3826 || (pReg->size == 4 && (pReg->offset & 3) == 0), 3827 ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size)); 3828 3829 /* registers are packed into dwords - with 3 exceptions with gaps at the end of the dword. */ 3830 AssertRelease(((pReg->offset + pReg->size) & 3) == 0 || pNextReg); 3831 if (pReg->offset & 3) 3832 { 3833 struct HDAREGDESC const *pPrevReg = i > 0 ? &g_aHdaRegMap[i - 1] : NULL; 3834 AssertReleaseMsg(pPrevReg, ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size)); 3835 if (pPrevReg) 3836 AssertReleaseMsg(pPrevReg->offset + pPrevReg->size == pReg->offset, 3837 ("[%#x] = {%#x LB %#x} vs. [%#x] = {%#x LB %#x}\n", 3838 i - 1, pPrevReg->offset, pPrevReg->size, i + 1, pReg->offset, pReg->size)); 3839 } 3840 #if 0 3841 if ((pReg->offset + pReg->size) & 3) 3842 { 3843 AssertReleaseMsg(pNextReg, ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size)); 3844 if (pNextReg) 3845 AssertReleaseMsg(pReg->offset + pReg->size == pNextReg->offset, 3846 ("[%#x] = {%#x LB %#x} vs. [%#x] = {%#x LB %#x}\n", 3847 i, pReg->offset, pReg->size, i + 1, pNextReg->offset, pNextReg->size)); 3848 } 3849 #endif 3850 3851 /* The final entry is a full dword, no gaps! Allows shortcuts. */ 3852 AssertReleaseMsg(pNextReg || ((pReg->offset + pReg->size) & 3) == 0, 3853 ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size)); 3427 3854 } 3428 #if 0 3429 if ((pReg->offset + pReg->size) & 3) 3430 { 3431 AssertReleaseMsg(pNextReg, ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size)); 3432 if (pNextReg) 3433 AssertReleaseMsg(pReg->offset + pReg->size == pNextReg->offset, 3434 ("[%#x] = {%#x LB %#x} vs. [%#x] = {%#x LB %#x}\n", 3435 i, pReg->offset, pReg->size, i + 1, pNextReg->offset, pNextReg->size)); 3436 } 3437 #endif 3438 3439 /* The final entry is a full dword, no gaps! Allows shortcuts. */ 3440 AssertReleaseMsg(pNextReg || ((pReg->offset + pReg->size) & 3) == 0, 3441 ("[%#x] = {%#x LB %#x}\n", i, pReg->offset, pReg->size)); 3442 } 3443 3444 return VINF_SUCCESS; 3855 } 3856 3857 LogFlowFuncLeaveRC(rc); 3858 return rc; 3445 3859 } 3446 3860 -
trunk/src/VBox/Devices/Audio/DevIchHdaCodec.cpp
r51636 r53442 9 9 10 10 /* 11 * Copyright (C) 2006-201 3Oracle Corporation11 * Copyright (C) 2006-2014 Oracle Corporation 12 12 * 13 13 * This file is part of VirtualBox Open Source Edition (OSE), as … … 24 24 * Header Files * 25 25 *******************************************************************************/ 26 #define LOG_GROUP LOG_GROUP_DEV_AUDIO26 //#define LOG_GROUP LOG_GROUP_DEV_AUDIO 27 27 #include <VBox/vmm/pdmdev.h> 28 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER29 28 #include <VBox/vmm/pdmaudioifs.h> 30 #endif31 29 #include <iprt/assert.h> 32 30 #include <iprt/uuid.h> … … 49 47 *******************************************************************************/ 50 48 /* PRM 5.3.1 */ 49 /** Codec address mask. */ 51 50 #define CODEC_CAD_MASK 0xF0000000 51 /** Codec address shift. */ 52 52 #define CODEC_CAD_SHIFT 28 53 53 #define CODEC_DIRECT_MASK RT_BIT(27) 54 /** Node ID mask. */ 54 55 #define CODEC_NID_MASK 0x07F00000 56 /** Node ID shift. */ 55 57 #define CODEC_NID_SHIFT 20 56 58 #define CODEC_VERBDATA_MASK 0x000FFFFF … … 62 64 #define CODEC_VERB_16BIT_DATA 0x0000FFFF 63 65 64 #define CODEC_CAD(cmd) (( cmd) & CODEC_CAD_MASK)66 #define CODEC_CAD(cmd) (((cmd) & CODEC_CAD_MASK) >> CODEC_CAD_SHIFT) 65 67 #define CODEC_DIRECT(cmd) ((cmd) & CODEC_DIRECT_MASK) 66 68 #define CODEC_NID(cmd) ((((cmd) & CODEC_NID_MASK)) >> CODEC_NID_SHIFT) … … 1096 1098 pThis->u8AssemblyId = 0x80; 1097 1099 pThis->paNodes = (PCODECNODE)RTMemAllocZ(sizeof(CODECNODE) * pThis->cTotalNodes); 1100 if (!pThis->paNodes) 1101 return VERR_NO_MEMORY; 1098 1102 pThis->fInReset = false; 1099 1103 #define STAC9220WIDGET(type) pThis->au8##type##s = g_abStac9220##type##s … … 1164 1168 */ 1165 1169 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1166 static int hdaCodecToAudVolume(PHDACODEC pThis, AMPLIFIER *pAmp, audmixerctl_tmt)1170 static int hdaCodecToAudVolume(PHDACODEC pThis, AMPLIFIER *pAmp, PDMAUDIOMIXERCTL mt) 1167 1171 #else 1168 1172 static int hdaCodecToAudVolume(AMPLIFIER *pAmp, audmixerctl_t mt) … … 1172 1176 switch (mt) 1173 1177 { 1178 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1179 case PDMAUDIOMIXERCTL_VOLUME: 1180 case PDMAUDIOMIXERCTL_PCM: 1181 #else 1174 1182 case AUD_MIXER_VOLUME: 1175 1183 case AUD_MIXER_PCM: 1184 #endif 1176 1185 dir = AMPLIFIER_OUT; 1177 1186 break; 1187 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1188 case PDMAUDIOMIXERCTL_LINE_IN: 1189 #else 1178 1190 case AUD_MIXER_LINE_IN: 1191 #endif 1179 1192 dir = AMPLIFIER_IN; 1180 1193 break; 1181 } 1194 default: 1195 AssertMsgFailed(("Invalid mixer control %ld\n", mt)); 1196 break; 1197 } 1198 1182 1199 int mute = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_LEFT, 0) & RT_BIT(7); 1183 1200 mute |= AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_RIGHT, 0) & RT_BIT(7); … … 1186 1203 uint8_t lVol = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_LEFT, 0) & 0x7f; 1187 1204 uint8_t rVol = AMPLIFIER_REGISTER(*pAmp, dir, AMPLIFIER_RIGHT, 0) & 0x7f; 1205 1188 1206 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1189 /* @todo in SetVolume no passing audmixerctl_in as its not used in DrvAudio.c*/1190 pThis->p Drv->pfnSetVolume(pThis->pDrv, &mute, &lVol, &rVol);1207 /** @todo In SetVolume no passing audmixerctl_in as its not used in DrvAudio.cpp. */ 1208 pThis->pfnSetVolume(pThis->pHDAState, RT_BOOL(mute), lVol, rVol); 1191 1209 #else 1192 1210 AUD_set_volume(mt, &mute, &lVol, &rVol); … … 1219 1237 static DECLCALLBACK(int) vrbProcUnimplemented(PHDACODEC pThis, uint32_t cmd, uint64_t *pResp) 1220 1238 { 1221 Log (("vrbProcUnimplemented:cmd(raw:%x: cad:%x, d:%c, nid:%x, verb:%x)\n", cmd,1239 LogFlowFunc(("cmd(raw:%x: cad:%x, d:%c, nid:%x, verb:%x)\n", cmd, 1222 1240 CODEC_CAD(cmd), CODEC_DIRECT(cmd) ? 'N' : 'Y', CODEC_NID(cmd), CODEC_VERBDATA(cmd))); 1223 1241 *pResp = 0; … … 1240 1258 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1241 1259 { 1242 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1260 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1243 1261 return VINF_SUCCESS; 1244 1262 } … … 1295 1313 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1296 1314 { 1297 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1315 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1298 1316 return VINF_SUCCESS; 1299 1317 } … … 1340 1358 if (CODEC_NID(cmd) == pThis->u8DacLineOut) 1341 1359 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1342 hdaCodecToAudVolume(pThis, pAmplifier, AUD_MIXER_VOLUME);1360 hdaCodecToAudVolume(pThis, pAmplifier, PDMAUDIOMIXERCTL_VOLUME); 1343 1361 #else 1344 1362 hdaCodecToAudVolume(pAmplifier, AUD_MIXER_VOLUME); 1345 1363 #endif 1364 1346 1365 if (CODEC_NID(cmd) == pThis->u8AdcVolsLineIn) /* Microphone */ 1347 1366 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1348 hdaCodecToAudVolume(pThis, pAmplifier, AUD_MIXER_LINE_IN);1367 hdaCodecToAudVolume(pThis, pAmplifier, PDMAUDIOMIXERCTL_LINE_IN); 1349 1368 #else 1350 1369 hdaCodecToAudVolume(pAmplifier, AUD_MIXER_LINE_IN); 1351 1370 #endif 1371 1352 1372 return VINF_SUCCESS; 1353 1373 } … … 1358 1378 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1359 1379 { 1360 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1380 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1361 1381 return VINF_SUCCESS; 1362 1382 } … … 1364 1384 if ((cmd & CODEC_VERB_8BIT_DATA) >= CODECNODE_F00_PARAM_LENGTH) 1365 1385 { 1366 Log (("HdaCodec:invalid F00 parameter %d\n", (cmd & CODEC_VERB_8BIT_DATA)));1386 LogFlowFunc(("invalid F00 parameter %d\n", (cmd & CODEC_VERB_8BIT_DATA))); 1367 1387 return VINF_SUCCESS; 1368 1388 } … … 1378 1398 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1379 1399 { 1380 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1400 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1381 1401 return VINF_SUCCESS; 1382 1402 } … … 1401 1421 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1402 1422 { 1403 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1423 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1404 1424 return VINF_SUCCESS; 1405 1425 } … … 1429 1449 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1430 1450 { 1431 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1451 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1432 1452 return VINF_SUCCESS; 1433 1453 } … … 1457 1477 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1458 1478 { 1459 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1479 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1460 1480 return VINF_SUCCESS; 1461 1481 } … … 1488 1508 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1489 1509 { 1490 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1510 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1491 1511 return VINF_SUCCESS; 1492 1512 } … … 1516 1536 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1517 1537 { 1518 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1538 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1519 1539 return VINF_SUCCESS; 1520 1540 } … … 1546 1566 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1547 1567 { 1548 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1568 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1549 1569 return VINF_SUCCESS; 1550 1570 } … … 1566 1586 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1567 1587 { 1568 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1588 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1569 1589 return VINF_SUCCESS; 1570 1590 } … … 1588 1608 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1589 1609 { 1590 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1610 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1591 1611 return VINF_SUCCESS; 1592 1612 } … … 1594 1614 if ((cmd & CODEC_VERB_8BIT_DATA) >= CODECNODE_F02_PARAM_LENGTH) 1595 1615 { 1596 Log (("HdaCodec:access to invalid F02 index %d\n", (cmd & CODEC_VERB_8BIT_DATA)));1616 LogFlowFunc(("access to invalid F02 index %d\n", (cmd & CODEC_VERB_8BIT_DATA))); 1597 1617 return VINF_SUCCESS; 1598 1618 } … … 1608 1628 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1609 1629 { 1610 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1630 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1611 1631 return VINF_SUCCESS; 1612 1632 } … … 1624 1644 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1625 1645 { 1626 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1646 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1627 1647 return VINF_SUCCESS; 1628 1648 } … … 1640 1660 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1641 1661 { 1642 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1662 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1643 1663 return VINF_SUCCESS; 1644 1664 } … … 1657 1677 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1658 1678 { 1659 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1679 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1660 1680 return VINF_SUCCESS; 1661 1681 } … … 1687 1707 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1688 1708 { 1689 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1709 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1690 1710 return VINF_SUCCESS; 1691 1711 } … … 1703 1723 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1704 1724 { 1705 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1725 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1706 1726 return VINF_SUCCESS; 1707 1727 } … … 1751 1771 { 1752 1772 uint8_t i; 1753 Log (("HdaCodec:enters reset\n"));1773 LogFlowFunc(("enters reset\n")); 1754 1774 Assert(pThis->pfnCodecNodeReset); 1755 1775 for (i = 0; i < pThis->cTotalNodes; ++i) … … 1758 1778 } 1759 1779 pThis->fInReset = false; 1760 Log (("HdaCodec:exits reset\n"));1780 LogFlowFunc(("exits reset\n")); 1761 1781 } 1762 1782 *pResp = 0; … … 1771 1791 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1772 1792 { 1773 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1793 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1774 1794 return VINF_SUCCESS; 1775 1795 } … … 1811 1831 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1812 1832 { 1813 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1833 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1814 1834 return VINF_SUCCESS; 1815 1835 } … … 1877 1897 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1878 1898 { 1879 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1899 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1880 1900 return VINF_SUCCESS; 1881 1901 } … … 1900 1920 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1901 1921 { 1902 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1922 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1903 1923 return VINF_SUCCESS; 1904 1924 } … … 1927 1947 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1928 1948 { 1929 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1949 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1930 1950 return VINF_SUCCESS; 1931 1951 } … … 1948 1968 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1949 1969 { 1950 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1970 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1951 1971 return VINF_SUCCESS; 1952 1972 } … … 1970 1990 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1971 1991 { 1972 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));1992 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1973 1993 return VINF_SUCCESS; 1974 1994 } … … 1990 2010 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 1991 2011 { 1992 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));2012 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 1993 2013 return VINF_SUCCESS; 1994 2014 } … … 2016 2036 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 2017 2037 { 2018 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));2038 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 2019 2039 return VINF_SUCCESS; 2020 2040 } … … 2032 2052 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 2033 2053 { 2034 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));2054 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 2035 2055 return VINF_SUCCESS; 2036 2056 } … … 2052 2072 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 2053 2073 { 2054 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));2074 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 2055 2075 return VINF_SUCCESS; 2056 2076 } … … 2069 2089 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 2070 2090 { 2071 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));2091 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 2072 2092 return VINF_SUCCESS; 2073 2093 } … … 2089 2109 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 2090 2110 { 2091 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));2111 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 2092 2112 return VINF_SUCCESS; 2093 2113 } … … 2114 2134 if (CODEC_NID(cmd) >= pThis->cTotalNodes) 2115 2135 { 2116 Log (("HdaCodec:invalid node address %d\n", CODEC_NID(cmd)));2136 LogFlowFunc(("invalid node address %d\n", CODEC_NID(cmd))); 2117 2137 return VINF_SUCCESS; 2118 2138 } … … 2219 2239 Assert(CODEC_CAD(cmd) == pThis->id); 2220 2240 if (hdaCodecIsReservedNode(pThis, CODEC_NID(cmd))) 2221 Log (("HdaCodec:cmd %x was addressed to reserved node\n", cmd));2241 LogFlowFunc(("cmd %x was addressed to reserved node\n", cmd)); 2222 2242 2223 2243 if ( CODEC_VERBDATA(cmd) == 0 … … 2226 2246 *pfn = vrbProcUnimplemented; 2227 2247 /// @todo r=michaln: There needs to be a counter to avoid log flooding (see e.g. DevRTC.cpp) 2228 Log (("HdaCodec:cmd %x was ignored\n", cmd));2248 LogFlowFunc(("cmd %x was ignored\n", cmd)); 2229 2249 return VINF_SUCCESS; 2230 2250 } … … 2240 2260 2241 2261 *pfn = vrbProcUnimplemented; 2242 Log(("HdaCodec: callback for %x wasn't found\n", CODEC_VERBDATA(cmd))); 2243 return VINF_SUCCESS; 2244 } 2245 2262 LogFlowFunc(("callback for %x wasn't found\n", CODEC_VERBDATA(cmd))); 2263 return VINF_SUCCESS; 2264 } 2265 2266 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER 2246 2267 static void pi_callback(void *opaque, int avail) 2247 2268 { … … 2255 2276 pThis->pfnTransfer(pThis, PO_INDEX, avail); 2256 2277 } 2257 2278 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 2258 2279 2259 2280 /* … … 2271 2292 */ 2272 2293 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2273 int hdaCodecOpenVoice(PHDACODEC pThis, ENMSOUNDSOURCE enmSoundSource, uint32_t uFrequency, uint32_t cChannels, 2274 audfmt_e fmt, uint32_t Endian) 2294 int hdaCodecOpenStream(PHDACODEC pThis, ENMSOUNDSOURCE enmSoundSource, PPDMAUDIOSTREAMCFG pCfg) 2275 2295 #else 2276 int hdaCodecOpen Voice(PHDACODEC pThis, ENMSOUNDSOURCE enmSoundSource, audsettings_t *pAudioSettings)2296 int hdaCodecOpenStream(PHDACODEC pThis, ENMSOUNDSOURCE enmSoundSource, audsettings_t *pAudioSettings) 2277 2297 #endif 2278 2298 { 2299 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 2300 2279 2301 int rc; 2280 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2281 Assert(pThis); 2282 if (!pThis) 2283 return -1; 2284 #else 2285 Assert(pThis && pAudioSettings); 2286 if ( !pThis 2287 || !pAudioSettings) 2288 return -1; 2289 #endif 2302 2290 2303 switch (enmSoundSource) 2291 2304 { … … 2293 2306 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2294 2307 /* old and new stream settings are not same. Then only call open */ 2295 2296 2308 //if (!hdaCodecCompareAudioSettings(&(pThis->SwVoiceIn)->info, pAudioSettings) && !pThis->SwVoiceIn) 2297 rc = pThis->p Drv->pfnOpenIn(pThis->pDrv, &pThis->SwVoiceIn, "hda.in", pThis, pi_callback, uFrequency,2298 cChannels, fmt, Endian);2309 rc = pThis->pfnOpenIn(pThis->pHDAState, "hda.in", 2310 PDMAUDIORECSOURCE_LINE_IN, pCfg); 2299 2311 #else 2300 pThis->SwVoiceIn = AUD_open_in(&pThis->card, pThis->SwVoiceIn, "hda.in", pThis, pi_callback, pAudioSettings); 2312 pThis->SwVoiceIn = AUD_open_in(&pThis->card, pThis->SwVoiceIn, "hda.in", pThis, pi_callback, pAudioSettings); 2313 rc = pThis->SwVoiceIn ? VINF_SUCCESS : VERR_GENERAL_FAILURE; 2301 2314 #endif 2302 rc = pThis->SwVoiceIn ? 0 : 1;2303 break; 2315 break; 2316 2304 2317 case PO_INDEX: 2305 2318 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2306 rc = pThis->pDrv->pfnOpenOut(pThis->pDrv, &pThis->SwVoiceOut, "hda.out", pThis, po_callback, uFrequency, 2307 cChannels, fmt, Endian); 2319 rc = pThis->pfnOpenOut(pThis->pHDAState, "hda.out", pCfg); 2308 2320 #else 2309 2321 pThis->SwVoiceOut = AUD_open_out(&pThis->card, pThis->SwVoiceOut, "hda.out", pThis, po_callback, pAudioSettings); 2322 rc = pThis->SwVoiceOut ? VINF_SUCCESS : VERR_GENERAL_FAILURE; 2310 2323 #endif 2311 rc = pThis->SwVoiceOut ? 0 : 1; 2312 break; 2324 break; 2325 2326 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2327 case MC_INDEX: 2328 /* old and new stream settings are not same. Then only call open */ 2329 //if (!hdaCodecCompareAudioSettings(&(pThis->SwVoiceIn)->info, pAudioSettings) && !pThis->SwVoiceIn) 2330 rc = pThis->pfnOpenIn(pThis->pHDAState, "hda.mc", 2331 PDMAUDIORECSOURCE_MIC, pCfg); 2332 break; 2333 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 2334 2313 2335 default: 2314 return -1; 2315 } 2316 if (!rc) 2317 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2318 LogRel(("HdaCodec: Can't open %s fmt(freq: %d)\n", enmSoundSource == PI_INDEX? "in" : "out", uFrequency)); 2319 #else 2320 LogRel(("HdaCodec: Can't open %s fmt(freq: %d)\n", enmSoundSource == PI_INDEX? "in" : "out", pAudioSettings->freq)); 2321 #endif 2336 AssertMsgFailed(("Index %ld not implemented\n", enmSoundSource)); 2337 rc = VERR_NOT_IMPLEMENTED; 2338 } 2339 2340 LogFlowFuncLeaveRC(rc); 2322 2341 return rc; 2323 2342 } 2324 2325 2343 2326 2344 int hdaCodecSaveState(PHDACODEC pThis, PSSMHANDLE pSSM) … … 2334 2352 return VINF_SUCCESS; 2335 2353 } 2336 2337 2354 2338 2355 int hdaCodecLoadState(PHDACODEC pThis, PSSMHANDLE pSSM, uint32_t uVersion) … … 2391 2408 if (hdaCodecIsDacNode(pThis, pThis->u8DacLineOut)) 2392 2409 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2393 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params, AUD_MIXER_VOLUME);2410 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params, PDMAUDIOMIXERCTL_VOLUME); 2394 2411 #else 2395 2412 hdaCodecToAudVolume(&pThis->paNodes[pThis->u8DacLineOut].dac.B_params, AUD_MIXER_VOLUME); … … 2397 2414 else if (hdaCodecIsSpdifOutNode(pThis, pThis->u8DacLineOut)) 2398 2415 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2399 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].spdifout.B_params, AUD_MIXER_VOLUME);2400 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, AUD_MIXER_LINE_IN);2416 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].spdifout.B_params, PDMAUDIOMIXERCTL_VOLUME); 2417 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, PDMAUDIOMIXERCTL_LINE_IN); 2401 2418 #else 2402 2419 hdaCodecToAudVolume(&pThis->paNodes[pThis->u8DacLineOut].spdifout.B_params, AUD_MIXER_VOLUME); … … 2407 2424 } 2408 2425 2409 2410 2426 int hdaCodecDestruct(PHDACODEC pThis) 2411 2427 { 2412 RTMemFree(pThis->paNodes); 2413 pThis->paNodes = NULL; 2414 return VINF_SUCCESS; 2415 } 2416 2417 2418 int hdaCodecConstruct(PPDMDEVINS pDevIns, PHDACODEC pThis, PCFGMNODE pCfg) 2419 { 2428 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 2429 2430 if (pThis->paNodes) 2431 { 2432 RTMemFree(pThis->paNodes); 2433 pThis->paNodes = NULL; 2434 } 2435 2436 return VINF_SUCCESS; 2437 } 2438 2439 int hdaCodecConstruct(PPDMDEVINS pDevIns, PHDACODEC pThis, 2440 uint16_t uLUN, PCFGMNODE pCfg) 2441 { 2442 AssertPtrReturn(pDevIns, VERR_INVALID_POINTER); 2443 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 2444 AssertPtrReturn(pCfg, VERR_INVALID_POINTER); 2445 2446 pThis->id = uLUN; 2420 2447 pThis->paVerbs = &g_aCodecVerbs[0]; 2421 2448 pThis->cVerbs = RT_ELEMENTS(g_aCodecVerbs); … … 2423 2450 int rc = stac9220Construct(pThis); 2424 2451 AssertRC(rc); 2425 2426 2452 2427 2453 /* common root node initializers */ … … 2433 2459 pThis->paNodes[1].afg.u32F20_param = CODEC_MAKE_F20(pThis->u16VendorId, pThis->u8BSKU, pThis->u8AssemblyId); 2434 2460 2435 /// @todo r=michaln: Was this meant to be 'HDA' or something like that? (AC'97 was on ICH0)2436 2461 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2437 pThis->pDrv->pfnRegisterCard(pThis->pDrv, "ICH0"); 2462 /* 44.1 kHz. */ 2463 PDMAUDIOSTREAMCFG as; 2464 as.uHz = 44100; 2465 as.cChannels = 2; 2466 as.enmFormat = AUD_FMT_S16; 2467 as.enmEndianness = PDMAUDIOHOSTENDIANESS; 2438 2468 #else 2439 2469 AUD_register_card("ICH0", &pThis->card); … … 2448 2478 2449 2479 pThis->paNodes[1].node.au32F00_param[0xA] = CODEC_F00_0A_16_BIT; 2450 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2451 hdaCodecOpenVoice(pThis, PI_INDEX, 44100, 2, AUD_FMT_S16, 0); 2452 hdaCodecOpenVoice(pThis, PO_INDEX, 44100, 2, AUD_FMT_S16, 0); 2453 #else 2454 hdaCodecOpenVoice(pThis, PI_INDEX, &as); 2455 hdaCodecOpenVoice(pThis, PO_INDEX, &as); 2456 #endif 2480 2481 hdaCodecOpenStream(pThis, PI_INDEX, &as); 2482 hdaCodecOpenStream(pThis, PO_INDEX, &as); 2457 2483 2458 2484 pThis->paNodes[1].node.au32F00_param[0xA] |= CODEC_F00_0A_44_1KHZ; … … 2461 2487 Assert(pThis->paNodes); 2462 2488 Assert(pThis->pfnCodecNodeReset); 2489 2463 2490 for (i = 0; i < pThis->cTotalNodes; ++i) 2464 {2465 2491 pThis->pfnCodecNodeReset(pThis, i, &pThis->paNodes[i]); 2466 } 2492 2467 2493 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2468 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params, AUD_MIXER_VOLUME);2469 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, AUD_MIXER_LINE_IN);2494 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8DacLineOut].dac.B_params, PDMAUDIOMIXERCTL_VOLUME); 2495 hdaCodecToAudVolume(pThis, &pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, PDMAUDIOMIXERCTL_LINE_IN); 2470 2496 #else 2471 2497 hdaCodecToAudVolume(&pThis->paNodes[pThis->u8DacLineOut].dac.B_params, AUD_MIXER_VOLUME); 2472 2498 hdaCodecToAudVolume(&pThis->paNodes[pThis->u8AdcVolsLineIn].adcvol.B_params, AUD_MIXER_LINE_IN); 2473 #endif 2474 2475 /* If no host voices were created, then fallback to nul audio. */ 2476 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2477 if (!pThis->pDrv->pfnIsHostVoiceInOK(pThis->pDrv, pThis->SwVoiceIn)) 2478 LogRel (("HDA: pfnIsHostVoiceInOK WARNING: Unable to open PCM IN!\n")); 2479 if (!pThis->pDrv->pfnIsHostVoiceOutOK(pThis->pDrv, pThis->SwVoiceOut)) 2480 LogRel (("HDA: pfnIsHostVoiceOutOK WARNING: Unable to open PCM OUT!\n")); 2481 #else 2499 2482 2500 if (!AUD_is_host_voice_in_ok(pThis->SwVoiceIn)) 2483 2501 LogRel (("HDA: WARNING: Unable to open PCM IN!\n")); 2484 2502 if (!AUD_is_host_voice_out_ok(pThis->SwVoiceOut)) 2485 2503 LogRel (("HDA: WARNING: Unable to open PCM OUT!\n")); 2486 #endif 2487 2488 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2489 if ( !pThis->pDrv->pfnIsHostVoiceInOK(pThis->pDrv, pThis->SwVoiceIn) 2490 && !pThis->pDrv->pfnIsHostVoiceOutOK(pThis->pDrv, pThis->SwVoiceOut)) 2491 #else 2504 2492 2505 if ( !AUD_is_host_voice_in_ok(pThis->SwVoiceIn) 2493 2506 && !AUD_is_host_voice_out_ok(pThis->SwVoiceOut)) 2494 #endif 2495 { 2496 /* Was not able initialize *any* voice. Select the NULL audio driver instead */ 2497 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2498 pThis->pDrv->pfnCloseIn(pThis->pDrv, pThis->SwVoiceIn); 2499 pThis->pDrv->pfnCloseOut(pThis->pDrv, pThis->SwVoiceOut); 2500 #else 2507 { 2501 2508 AUD_close_in(&pThis->card, pThis->SwVoiceIn); 2502 2509 AUD_close_out(&pThis->card, pThis->SwVoiceOut); 2503 #endif 2510 2504 2511 pThis->SwVoiceOut = NULL; 2505 2512 pThis->SwVoiceIn = NULL; 2506 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2507 pThis->pDrv->pfnInitNull(pThis->pDrv); 2508 #else 2513 2509 2514 AUD_init_null (); 2510 #endif2511 2515 2512 2516 PDMDevHlpVMSetRuntimeError (pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", … … 2514 2518 "with the consequence that no sound is audible")); 2515 2519 } 2516 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER2517 else if ( !pThis->pDrv->pfnIsHostVoiceInOK(pThis->pDrv, pThis->SwVoiceIn)2518 || !pThis->pDrv->pfnIsHostVoiceOutOK(pThis->pDrv, pThis->SwVoiceOut))2519 2520 #else2521 2520 else if ( !AUD_is_host_voice_in_ok(pThis->SwVoiceIn) 2522 2521 || !AUD_is_host_voice_out_ok(pThis->SwVoiceOut)) 2523 #endif2524 2522 { 2525 2523 char szMissingVoices[128]; 2526 2524 size_t len = 0; 2527 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2528 if (!pThis->pDrv->pfnIsHostVoiceInOK(pThis->pDrv, pThis->SwVoiceIn)) 2529 len = RTStrPrintf (szMissingVoices, sizeof(szMissingVoices), "PCM_in"); 2530 if (!pThis->pDrv->pfnIsHostVoiceOutOK(pThis->pDrv, pThis->SwVoiceOut)) 2531 len += RTStrPrintf (szMissingVoices + len, sizeof(szMissingVoices) - len, len ? ", PCM_out" : "PCM_out"); 2532 #else 2525 2533 2526 if (!AUD_is_host_voice_in_ok(pThis->SwVoiceIn)) 2534 2527 len = RTStrPrintf (szMissingVoices, sizeof(szMissingVoices), "PCM_in"); … … 2536 2529 len += RTStrPrintf (szMissingVoices + len, sizeof(szMissingVoices) - len, len ? ", PCM_out" : "PCM_out"); 2537 2530 2538 #endif2539 2531 PDMDevHlpVMSetRuntimeError (pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", 2540 2532 N_ ("Some audio devices (%s) could not be opened. Guest applications generating audio " … … 2543 2535 "subsystem"), szMissingVoices); 2544 2536 } 2545 2546 return VINF_SUCCESS; 2547 } 2548 2537 #endif 2538 2539 return VINF_SUCCESS; 2540 } 2541 -
trunk/src/VBox/Devices/Audio/DevIchHdaCodec.h
r50686 r53442 5 5 6 6 /* 7 * Copyright (C) 2006-201 3Oracle Corporation7 * Copyright (C) 2006-2014 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 18 18 #ifndef DEV_CODEC_H 19 19 #define DEV_CODEC_H 20 //#include <VBox/vmm/pdmdev.h> 20 21 /** The ICH HDA (Intel) controller. */ 22 typedef struct HDASTATE *PHDASTATE; 21 23 /** The ICH HDA (Intel) codec state. */ 22 typedef struct HDACODEC HDACODEC; 23 /** Pointer to the Intel ICH HDA codec state. */ 24 typedef HDACODEC *PHDACODEC; 25 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 26 typedef struct PDMIAUDIOCONNECTOR * PPDMIAUDIOCONNECTOR; 27 typedef struct PDMGSTVOICEOUT *PPDMGSTVOICEOUT; 28 typedef struct PDMGSTVOICEIN *PPDMGSTVOICEIN; 29 #endif 24 typedef struct HDACODEC HDACODEC, *PHDACODEC; 25 /** The HDA host driver backend. */ 26 typedef struct HDADRIVER HDADRIVER, *PHDADRIVER; 27 typedef struct PDMIAUDIOCONNECTOR *PPDMIAUDIOCONNECTOR; 28 typedef struct PDMAUDIOGSTSTRMOUT *PPDMAUDIOGSTSTRMOUT; 29 typedef struct PDMAUDIOGSTSTRMIN *PPDMAUDIOGSTSTRMIN; 30 30 31 /** 31 32 * Verb processor method. … … 68 69 } ENMSOUNDSOURCE; 69 70 70 71 71 typedef struct HDACODEC 72 72 { … … 76 76 uint8_t u8BSKU; 77 77 uint8_t u8AssemblyId; 78 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 79 R3PTRTYPE(PPDMIAUDIOCONNECTOR) pDrv; 80 /** Pointer to the attached audio driver. */ 81 R3PTRTYPE(PPDMIBASE) pDrvBase; 82 #endif 78 /* List of assigned HDA drivers to this codec. 79 * A driver only can be assigned to one codec 80 * at a time. */ 81 RTLISTANCHOR lstDrv; 83 82 84 83 #ifndef VBOX_WITH_HDA_CODEC_EMU … … 89 88 #endif 90 89 PCODECNODE paNodes; 91 90 /** Pointer to HDA state (controller) this 91 * codec is assigned to. */ 92 PHDASTATE pHDAState; 93 bool fInReset; 94 #ifndef VBOX_WITH_HDA_CODEC_EMU 95 const uint8_t cTotalNodes; 96 const uint8_t *au8Ports; 97 const uint8_t *au8Dacs; 98 const uint8_t *au8AdcVols; 99 const uint8_t *au8Adcs; 100 const uint8_t *au8AdcMuxs; 101 const uint8_t *au8Pcbeeps; 102 const uint8_t *au8SpdifIns; 103 const uint8_t *au8SpdifOuts; 104 const uint8_t *au8DigInPins; 105 const uint8_t *au8DigOutPins; 106 const uint8_t *au8Cds; 107 const uint8_t *au8VolKnobs; 108 const uint8_t *au8Reserveds; 109 const uint8_t u8AdcVolsLineIn; 110 const uint8_t u8DacLineOut; 111 #endif 92 112 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 93 /** PCM in */ 94 R3PTRTYPE(PPDMGSTVOICEIN) SwVoiceIn; 95 /** PCM out */ 96 R3PTRTYPE(PPDMGSTVOICEOUT) SwVoiceOut; 113 /* Callbacks to the HDA controller, mostly used for multiplexing to the various host backends. */ 114 DECLR3CALLBACKMEMBER(void, pfnCloseIn, (PHDASTATE pThis, PDMAUDIORECSOURCE enmRecSource)); 115 DECLR3CALLBACKMEMBER(void, pfnCloseOut, (PHDASTATE pThis)); 116 DECLR3CALLBACKMEMBER(int, pfnOpenIn, (PHDASTATE pThis, const char *pszName, PDMAUDIORECSOURCE enmRecSource, PPDMAUDIOSTREAMCFG pCfg)); 117 DECLR3CALLBACKMEMBER(int, pfnOpenOut, (PHDASTATE pThis, const char *pszName, PPDMAUDIOSTREAMCFG pCfg)); 118 DECLR3CALLBACKMEMBER(int, pfnSetVolume, (PHDASTATE pThis, bool fMute, uint8_t uVolLeft, uint8_t uVolRight)); 119 /* Callbacks for host driver backends. */ 120 DECLR3CALLBACKMEMBER(void, pfnTransfer, (PHDADRIVER pDrv, ENMSOUNDSOURCE enmSource, uint32_t cbAvail)); 97 121 #else 98 122 QEMUSoundCard card; 99 123 /** PCM in */ 100 SWVoiceIn 124 SWVoiceIn *SwVoiceIn; 101 125 /** PCM out */ 102 SWVoiceOut *SwVoiceOut; 103 #endif 104 void *pvHDAState; 105 bool fInReset; 106 #ifndef VBOX_WITH_HDA_CODEC_EMU 107 const uint8_t cTotalNodes; 108 const uint8_t *au8Ports; 109 const uint8_t *au8Dacs; 110 const uint8_t *au8AdcVols; 111 const uint8_t *au8Adcs; 112 const uint8_t *au8AdcMuxs; 113 const uint8_t *au8Pcbeeps; 114 const uint8_t *au8SpdifIns; 115 const uint8_t *au8SpdifOuts; 116 const uint8_t *au8DigInPins; 117 const uint8_t *au8DigOutPins; 118 const uint8_t *au8Cds; 119 const uint8_t *au8VolKnobs; 120 const uint8_t *au8Reserveds; 121 const uint8_t u8AdcVolsLineIn; 122 const uint8_t u8DacLineOut; 123 #endif 124 DECLR3CALLBACKMEMBER(int, pfnProcess, (PHDACODEC pCodec)); 125 DECLR3CALLBACKMEMBER(void, pfnTransfer, (PHDACODEC pCodec, ENMSOUNDSOURCE, int avail)); 126 /* These callbacks are set by Codec implementation. */ 126 SWVoiceOut *SwVoiceOut; 127 /* Callbacks for host driver backends. */ 128 DECLR3CALLBACKMEMBER(void, pfnTransfer, (PHDACODEC pCodec, ENMSOUNDSOURCE enmSource, int cbAvail)); 129 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 130 /* Callbacks by codec implementation. */ 127 131 DECLR3CALLBACKMEMBER(int, pfnLookup, (PHDACODEC pThis, uint32_t verb, PPFNHDACODECVERBPROCESSOR)); 128 132 DECLR3CALLBACKMEMBER(int, pfnReset, (PHDACODEC pThis)); 129 133 DECLR3CALLBACKMEMBER(int, pfnCodecNodeReset, (PHDACODEC pThis, uint8_t, PCODECNODE)); 130 /* These callbacks are setby codec implementation to answer debugger requests. */134 /* Callbacks by codec implementation to answer debugger requests. */ 131 135 DECLR3CALLBACKMEMBER(void, pfnCodecDbgListNodes, (PHDACODEC pThis, PCDBGFINFOHLP pHlp, const char *pszArgs)); 132 136 DECLR3CALLBACKMEMBER(void, pfnCodecDbgSelector, (PHDACODEC pThis, PCDBGFINFOHLP pHlp, const char *pszArgs)); 133 137 } CODECState; 134 138 135 int hdaCodecConstruct(PPDMDEVINS pDevIns, PHDACODEC pThis, PCFGMNODE pCfg);139 int hdaCodecConstruct(PPDMDEVINS pDevIns, PHDACODEC pThis, uint16_t uLUN, PCFGMNODE pCfg); 136 140 int hdaCodecDestruct(PHDACODEC pThis); 137 141 int hdaCodecSaveState(PHDACODEC pThis, PSSMHANDLE pSSM); 138 142 int hdaCodecLoadState(PHDACODEC pThis, PSSMHANDLE pSSM, uint32_t uVersion); 143 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 144 int hdaCodecOpenStream(PHDACODEC pThis, PDMAUDIORECSOURCE enmRecSource, PDMAUDIOSTREAMCFG *pAudioSettings); 145 #else 139 146 int hdaCodecOpenVoice(PHDACODEC pThis, ENMSOUNDSOURCE enmSoundSource, audsettings_t *pAudioSettings); 147 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 140 148 141 149 #define HDA_SSM_VERSION 4 … … 154 162 # endif 155 163 #endif 164 -
trunk/src/VBox/Devices/Audio/DevSB16.cpp
r50686 r53442 34 34 #define LOG_GROUP LOG_GROUP_DEV_AUDIO 35 35 #include <VBox/vmm/pdmdev.h> 36 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER37 36 #include <VBox/vmm/pdmaudioifs.h> 38 #endif39 37 #include <iprt/assert.h> 40 38 #include <iprt/string.h> … … 90 88 /** Pointer to the device instance. */ 91 89 PPDMDEVINSR3 pDevIns; 92 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER93 90 /** Pointer to the connector of the attached audio driver. */ 94 91 PPDMIAUDIOCONNECTOR pDrv; 95 # endif96 #endif97 #ifndef VBOX98 qemu_irq *pic;99 #endif100 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER101 QEMUSoundCard card;102 92 #endif 103 93 #ifdef VBOX /* lazy bird */ … … 119 109 int fmt_signed; 120 110 int fmt_bits; 111 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 112 PDMAUDIOFMT fmt; 113 #else 121 114 audfmt_e fmt; 115 QEMUSoundCard card; 116 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 122 117 int dma_auto; 123 118 int block_size; … … 154 149 int bytes_per_second; 155 150 int align; 156 int audio_free; 151 uint32_t audio_free; 152 157 153 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 158 PPDM GSTVOICEOUT voice;154 PPDMAUDIOGSTSTRMOUT pGstStrmOut; 159 155 #else 160 156 SWVoiceOut *voice; 161 #endif 162 163 #ifndef VBOX 164 QEMUTimer *aux_ts; 165 #else 157 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 158 166 159 PTMTIMER pTimer; 167 160 PPDMIBASE pDrvBase; 168 161 /** LUN\#0: Base interface. */ 169 162 PDMIBASE IBase; 170 #endif 163 171 164 /* mixer state */ 172 165 int mixer_nreg; … … 174 167 } SB16State; 175 168 176 static void SB_audio_callback (void *opaque, int free); 169 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 170 static void sb16AudioCallback(void *pvContext, uint32_t cbFree); 171 #else 172 static void sb16AudioCallback(void *pvContext, int cbFree); 173 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 177 174 178 175 static int magic_of_irq (int irq) … … 188 185 return 8; 189 186 default: 190 LogFlow (("SB16:bad irq %d\n", irq));187 LogFlowFunc(("bad irq %d\n", irq)); 191 188 return 2; 192 189 } … … 205 202 return 10; 206 203 default: 207 LogFlow (("SB16:bad irq magic %d\n", magic));204 LogFlowFunc(("bad irq magic %d\n", magic)); 208 205 return -1; 209 206 } … … 236 233 s->dma_running = hold; 237 234 238 LogFlow (("SB16:hold %d high %d dma %d\n", hold, s->use_hdma, dma));235 LogFlowFunc(("hold %d high %d dma %d\n", hold, s->use_hdma, dma)); 239 236 240 237 #ifndef VBOX … … 253 250 PDMDevHlpDMASchedule (s->pDevIns); 254 251 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 255 s->pDrv->pfnEnableOut(s->pDrv, s-> voice, 1);252 s->pDrv->pfnEnableOut(s->pDrv, s->pGstStrmOut, true /* fEnable */); 256 253 #else 257 254 AUD_set_active_out (s->voice, 1); … … 262 259 PDMDevHlpDMASetDREQ (s->pDevIns, dma, 0); 263 260 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 264 s->pDrv->pfnEnableOut(s->pDrv, s-> voice, 0);261 s->pDrv->pfnEnableOut(s->pDrv, s->pGstStrmOut, false /* fEnable */); 265 262 #else 266 263 AUD_set_active_out (s->voice, 0); … … 291 288 static void continue_dma8 (SB16State *s) 292 289 { 290 if (s->freq > 0) 291 { 292 s->audio_free = 0; 293 293 294 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 294 int rc; 295 #endif 296 if (s->freq > 0) { 297 298 s->audio_free = 0; 299 300 301 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 302 rc = s->pDrv->pfnOpenOut(s->pDrv, &s->voice, "sb16", s, SB_audio_callback, s->freq, 1 << s->fmt_stereo, 303 s->fmt, 0); 295 PDMAUDIOSTREAMCFG as; 296 as.uHz = s->freq; 297 as.cChannels = 1 << s->fmt_stereo; 298 as.enmFormat = s->fmt; 299 as.enmEndianness = PDMAUDIOHOSTENDIANESS; 300 301 int rc = s->pDrv->pfnOpenOut(s->pDrv, "sb16.out", 302 sb16AudioCallback /* fnCallback */, s /* pvCallback */, 303 &as, 304 &s->pGstStrmOut); 305 AssertRC(rc); 304 306 #else 305 307 audsettings_t as; … … 313 315 "sb16", 314 316 s, 315 SB_audio_callback,317 sb16AudioCallback, 316 318 &as 317 319 ); 318 #endif 320 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 319 321 } 320 322 … … 345 347 and SecondReality/FC work 346 348 349 r=andy Wow, actually someone who remembers Future Crew :-) 350 347 351 Act1 sets block size via command 0x48 and it's an odd number 348 352 SR does the same with even number … … 360 364 361 365 if (s->block_size & s->align) { 362 LogFlow (("SB16:warning: misaligned block size %d, alignment %d\n",366 LogFlowFunc(("warning: misaligned block size %d, alignment %d\n", 363 367 s->block_size, s->align + 1)); 364 368 } 365 369 366 LogFlow (("SB16:freq %d, stereo %d, sign %d, bits %d, "370 LogFlowFunc(("freq %d, stereo %d, sign %d, bits %d, " 367 371 "dma %d, auto %d, fifo %d, high %d\n", 368 372 s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits, … … 412 416 } 413 417 414 LogFlow (("SB16:freq %d, stereo %d, sign %d, bits %d, "418 LogFlowFunc(("freq %d, stereo %d, sign %d, bits %d, " 415 419 "dma %d, auto %d, fifo %d, high %d\n", 416 420 s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits, … … 440 444 s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1; 441 445 if (s->block_size & s->align) { 442 LogFlow (("SB16:warning: misaligned block size %d, alignment %d\n",446 LogFlowFunc(("warning: misaligned block size %d, alignment %d\n", 443 447 s->block_size, s->align + 1)); 444 448 } 445 449 446 if (s->freq) {447 450 if (s->freq) 451 { 448 452 s->audio_free = 0; 449 453 450 451 454 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 452 int rc; 453 rc = s->pDrv->pfnOpenOut(s->pDrv, &s->voice, "sb16", s,SB_audio_callback, s->freq, 1 << s->fmt_stereo, s->fmt, 0); 455 PDMAUDIOSTREAMCFG as; 456 as.uHz = s->freq; 457 as.cChannels = 1 << s->fmt_stereo; 458 as.enmFormat = s->fmt; 459 as.enmEndianness = PDMAUDIOHOSTENDIANESS; 460 461 int rc = s->pDrv->pfnOpenOut(s->pDrv, "sb16.out", 462 sb16AudioCallback /* fnCallback */, s /* pvCallback */, 463 &as, 464 &s->pGstStrmOut); 465 AssertRC(rc); 454 466 #else 455 467 audsettings_t as; … … 463 475 "sb16", 464 476 s, 465 SB_audio_callback,477 sb16AudioCallback, 466 478 &as 467 479 ); 468 #endif 480 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 469 481 } 470 482 … … 475 487 static inline void dsp_out_data (SB16State *s, uint8_t val) 476 488 { 477 LogFlow (("SB16:outdata %#x\n", val));489 LogFlowFunc(("outdata %#x\n", val)); 478 490 if ((size_t) s->out_data_len < sizeof (s->out_data)) { 479 491 s->out_data[s->out_data_len++] = val; … … 487 499 } 488 500 else { 489 LogFlow (("SB16:buffer underflow\n"));501 LogFlowFunc(("buffer underflow\n")); 490 502 return 0; 491 503 } … … 494 506 static void command (SB16State *s, uint8_t cmd) 495 507 { 496 LogFlow (("SB16:command %#x\n", cmd));508 LogFlowFunc(("command %#x\n", cmd)); 497 509 498 510 if (cmd > 0xaf && cmd < 0xd0) { 499 511 if (cmd & 8) { 500 LogFlow (("SB16:ADC not yet supported (command %#x)\n", cmd));512 LogFlowFunc(("ADC not yet supported (command %#x)\n", cmd)); 501 513 } 502 514 … … 506 518 break; 507 519 default: 508 LogFlow (("SB16:%#x wrong bits\n", cmd));520 LogFlowFunc(("%#x wrong bits\n", cmd)); 509 521 } 510 522 s->needed_bytes = 3; … … 560 572 561 573 case 0x35: 562 LogFlow (("SB16:0x35 - MIDI command not implemented\n"));574 LogFlowFunc(("0x35 - MIDI command not implemented\n")); 563 575 break; 564 576 … … 594 606 case 0x74: 595 607 s->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */ 596 LogFlow (("SB16:0x75 - DMA DAC, 4-bit ADPCM not implemented\n"));608 LogFlowFunc(("0x75 - DMA DAC, 4-bit ADPCM not implemented\n")); 597 609 break; 598 610 599 611 case 0x75: /* DMA DAC, 4-bit ADPCM Reference */ 600 612 s->needed_bytes = 2; 601 LogFlow (("SB16:0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n"));613 LogFlowFunc(("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n")); 602 614 break; 603 615 604 616 case 0x76: /* DMA DAC, 2.6-bit ADPCM */ 605 617 s->needed_bytes = 2; 606 LogFlow (("SB16:0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n"));618 LogFlowFunc(("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n")); 607 619 break; 608 620 609 621 case 0x77: /* DMA DAC, 2.6-bit ADPCM Reference */ 610 622 s->needed_bytes = 2; 611 LogFlow (("SB16:0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n"));623 LogFlowFunc(("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n")); 612 624 break; 613 625 614 626 case 0x7d: 615 LogFlow (("SB16:0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n"));616 LogFlow (("SB16:not implemented\n"));627 LogFlowFunc(("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n")); 628 LogFlowFunc(("not implemented\n")); 617 629 break; 618 630 619 631 case 0x7f: 620 LogFlow (("SB16:0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"));621 LogFlow (("SB16:not implemented\n"));632 LogFlowFunc(("0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n")); 633 LogFlowFunc(("not implemented\n")); 622 634 break; 623 635 … … 691 703 692 704 case 0xe7: 693 LogFlow (("SB16:Attempt to probe for ESS (0xe7)?\n"));705 LogFlowFunc(("Attempt to probe for ESS (0xe7)?\n")); 694 706 break; 695 707 … … 722 734 723 735 default: 724 LogFlow (("SB16:Unrecognized command %#x\n", cmd));736 LogFlowFunc(("Unrecognized command %#x\n", cmd)); 725 737 break; 726 738 } … … 741 753 742 754 warn: 743 LogFlow (("SB16:warning: command %#x,%d is not truly understood yet\n",755 LogFlowFunc(("warning: command %#x,%d is not truly understood yet\n", 744 756 cmd, s->needed_bytes)); 745 757 goto exit; … … 764 776 { 765 777 int d0, d1, d2; 766 LogFlow (("SB16:complete command %#x, in_index %d, needed_bytes %d\n",778 LogFlowFunc(("complete command %#x, in_index %d, needed_bytes %d\n", 767 779 s->cmd, s->in_index, s->needed_bytes)); 768 780 … … 773 785 774 786 if (s->cmd & 8) { 775 LogFlow (("SB16:ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",787 LogFlowFunc(("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n", 776 788 s->cmd, d0, d1, d2)); 777 789 } 778 790 else { 779 LogFlow (("SB16:cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",791 LogFlowFunc(("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n", 780 792 s->cmd, d0, d1, d2)); 781 793 dma_cmd (s, s->cmd, d0, d1 + (d2 << 8)); … … 788 800 s->csp_reg83r = 0; 789 801 s->csp_reg83w = 0; 790 LogFlow (("SB16:CSP command 0x04: mode=%#x\n", s->csp_mode));802 LogFlowFunc(("CSP command 0x04: mode=%#x\n", s->csp_mode)); 791 803 break; 792 804 … … 794 806 s->csp_param = dsp_get_data (s); 795 807 s->csp_value = dsp_get_data (s); 796 LogFlow (("SB16:CSP command 0x05: param=%#x value=%#x\n",808 LogFlowFunc(("CSP command 0x05: param=%#x value=%#x\n", 797 809 s->csp_param, 798 810 s->csp_value)); … … 802 814 d0 = dsp_get_data (s); 803 815 d1 = dsp_get_data (s); 804 LogFlow (("SB16:write CSP register %d <- %#x\n", d1, d0));816 LogFlowFunc(("write CSP register %d <- %#x\n", d1, d0)); 805 817 if (d1 == 0x83) { 806 LogFlow (("SB16:0x83[%d] <- %#x\n", s->csp_reg83r, d0));818 LogFlowFunc(("0x83[%d] <- %#x\n", s->csp_reg83r, d0)); 807 819 s->csp_reg83[s->csp_reg83r % 4] = d0; 808 820 s->csp_reg83r += 1; … … 815 827 case 0x0f: 816 828 d0 = dsp_get_data (s); 817 LogFlow (("SB16:read CSP register %#x -> %#x, mode=%#x\n",829 LogFlowFunc(("read CSP register %#x -> %#x, mode=%#x\n", 818 830 d0, s->csp_regs[d0], s->csp_mode)); 819 831 if (d0 == 0x83) { 820 LogFlow (("SB16:0x83[%d] -> %#x\n",832 LogFlowFunc(("0x83[%d] -> %#x\n", 821 833 s->csp_reg83w, 822 834 s->csp_reg83[s->csp_reg83w % 4])); … … 831 843 case 0x10: 832 844 d0 = dsp_get_data (s); 833 LogFlow (("SB16:cmd 0x10 d0=%#x\n", d0));845 LogFlowFunc(("cmd 0x10 d0=%#x\n", d0)); 834 846 break; 835 847 … … 840 852 case 0x40: 841 853 s->time_const = dsp_get_data (s); 842 LogFlow (("SB16:set time const %d\n", s->time_const));854 LogFlowFunc(("set time const %d\n", s->time_const)); 843 855 break; 844 856 845 857 case 0x42: /* FT2 sets output freq with this, go figure */ 846 858 #if 0 847 dolog ("cmd 0x42 might not do what it think it should\n");859 LogFlowFunc(("cmd 0x42 might not do what it think it should\n")); 848 860 #endif 849 861 case 0x41: 850 862 s->freq = dsp_get_hilo (s); 851 LogFlow (("SB16:set freq %d\n", s->freq));863 LogFlowFunc(("set freq %d\n", s->freq)); 852 864 break; 853 865 854 866 case 0x48: 855 867 s->block_size = dsp_get_lohi (s) + 1; 856 LogFlow (("SB16:set dma block len %d\n", s->block_size));868 LogFlowFunc(("set dma block len %d\n", s->block_size)); 857 869 break; 858 870 … … 885 897 } 886 898 } 887 LogFlow (("SB16:mix silence %d %d %" PRId64 "\n", samples, bytes, ticks));899 LogFlowFunc(("mix silence %d %d %" PRId64 "\n", samples, bytes, ticks)); 888 900 #else /* VBOX */ 889 901 ticks = (bytes * TMTimerGetFreq(s->pTimer)) / freq; … … 892 904 else 893 905 TMTimerSet(s->pTimer, TMTimerGet(s->pTimer) + ticks); 894 LogFlow (("SB16:mix silence %d %d % %RU64\n", samples, bytes, ticks));906 LogFlowFunc(("mix silence %d %d % %RU64\n", samples, bytes, ticks)); 895 907 #endif /* VBOX */ 896 908 } … … 900 912 d0 = dsp_get_data (s); 901 913 s->out_data_len = 0; 902 LogFlow (("SB16:E0 data = %#x\n", d0));914 LogFlowFunc(("E0 data = %#x\n", d0)); 903 915 dsp_out_data (s, ~d0); 904 916 break; … … 915 927 case 0xf9: 916 928 d0 = dsp_get_data (s); 917 LogFlow (("SB16:command 0xf9 with %#x\n", d0));929 LogFlowFunc(("command 0xf9 with %#x\n", d0)); 918 930 switch (d0) { 919 931 case 0x0e: … … 936 948 937 949 default: 938 LogFlow (("SB16:complete: unrecognized command %#x\n", s->cmd));950 LogFlowFunc(("complete: unrecognized command %#x\n", s->cmd)); 939 951 return; 940 952 } … … 948 960 static void legacy_reset (SB16State *s) 949 961 { 950 951 962 s->freq = 11025; 952 963 s->fmt_signed = 0; … … 955 966 956 967 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 957 int rc; 958 rc = s->pDrv->pfnOpenOut(s->pDrv, &s->voice, "sb16", s, SB_audio_callback, 11025, 1, AUD_FMT_U8, 0); 968 PDMAUDIOSTREAMCFG as; 969 as.uHz = s->freq; 970 as.cChannels = 1; 971 as.enmFormat = AUD_FMT_U8; 972 as.enmEndianness = PDMAUDIOHOSTENDIANESS; 973 974 int rc = s->pDrv->pfnOpenOut(s->pDrv, "sb16.out", 975 sb16AudioCallback /* fnCallback */, s /* pvContext */, 976 &as, 977 &s->pGstStrmOut); 978 AssertRC(rc); 959 979 #else 960 980 audsettings_t as; … … 968 988 "sb16", 969 989 s, 970 SB_audio_callback,990 sb16AudioCallback, 971 991 &as 972 992 ); 973 974 #endif 993 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 994 975 995 /* Not sure about that... */ 976 996 /* AUD_set_active_out (s->voice, 1); */ … … 1016 1036 int iport = nport - s->port; 1017 1037 1018 LogFlow (("SB16:write %#x <- %#x\n", nport, val));1038 LogFlowFunc(("write %#x <- %#x\n", nport, val)); 1019 1039 switch (iport) { 1020 1040 case 0x06: … … 1077 1097 else { 1078 1098 if (s->in_index == sizeof (s->in2_data)) { 1079 LogFlow (("SB16:in data overrun\n"));1099 LogFlowFunc(("in data overrun\n")); 1080 1100 } 1081 1101 else { … … 1093 1113 1094 1114 default: 1095 LogFlow (("SB16:nport=%#x, val=%#x)\n", nport, val));1115 LogFlowFunc(("nport=%#x, val=%#x)\n", nport, val)); 1096 1116 break; 1097 1117 } … … 1125 1145 else { 1126 1146 if (s->cmd != -1) { 1127 LogFlow (("SB16:empty output buffer for command %#x\n",1147 LogFlowFunc(("empty output buffer for command %#x\n", 1128 1148 s->cmd)); 1129 1149 } … … 1138 1158 1139 1159 case 0x0d: /* timer interrupt clear */ 1140 /* dolog ("timer interrupt clear\n"); */1160 /* LogFlowFunc(("timer interrupt clear\n")); */ 1141 1161 retval = 0; 1142 1162 break; … … 1173 1193 1174 1194 if (!ack) { 1175 LogFlow (("SB16:read %#x -> %#x\n", nport, retval));1195 LogFlowFunc(("read %#x -> %#x\n", nport, retval)); 1176 1196 } 1177 1197 … … 1184 1204 1185 1205 error: 1186 LogFlow (("SB16:warning: dsp_read %#x error\n", nport));1206 LogFlowFunc(("warning: dsp_read %#x error\n", nport)); 1187 1207 #ifndef VBOX 1188 1208 return 0xff; … … 1232 1252 #endif 1233 1253 } 1254 1234 1255 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1235 uint32_t popcount (uint32_t u) 1256 uint32_t popcount (uint32_t u) /** @todo r=andy WTF? */ 1236 1257 { 1237 1258 u = ((u&0x55555555) + ((u>>1)&0x55555555)); … … 1245 1266 uint32_t lsbindex (uint32_t u) 1246 1267 { 1247 return popcount ((u&-u)-1); 1268 return popcount ((u&-u)-1); /** @todo r=andy Un/signed mismatch? */ 1248 1269 } 1249 1270 #endif … … 1256 1277 1257 1278 (void) nport; 1258 LogFlow (("SB16:mixer_write [%#x] <- %#x\n", s->mixer_nreg, val));1279 LogFlowFunc(("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val)); 1259 1280 1260 1281 switch (s->mixer_nreg) { … … 1307 1328 { 1308 1329 int irq = irq_of_magic (val); 1309 LogFlow (("SB16:setting irq to %d (val=%#x)\n", irq, val));1330 LogFlowFunc(("setting irq to %d (val=%#x)\n", irq, val)); 1310 1331 if (irq > 0) { 1311 1332 s->irq = irq; … … 1334 1355 1335 1356 case 0x82: 1336 LogFlow (("SB16:attempt to write into IRQ status register (val=%#x)\n",1357 LogFlowFunc(("attempt to write into IRQ status register (val=%#x)\n", 1337 1358 val)); 1338 1359 #ifdef VBOX … … 1342 1363 default: 1343 1364 if (s->mixer_nreg >= 0x80) { 1344 LogFlow (("SB16:attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val));1365 LogFlowFunc(("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val)); 1345 1366 } 1346 1367 break; … … 1356 1377 uint8_t lvol = s->mixer_regs[0x30]; 1357 1378 uint8_t rvol = s->mixer_regs[0x31]; 1379 1358 1380 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1359 /*@todo not passinga audmixer_Ctl values as its not used in DrvAudio.c */ 1360 s->pDrv->pfnSetVolume(s->pDrv, &mute, &lvol, &rvol); 1381 s->pDrv->pfnSetVolume(s->pDrv, RT_BOOL(mute), lvol, rvol); 1361 1382 #else 1362 1383 AUD_set_volume(AUD_MIXER_VOLUME, &mute, &lvol, &rvol); 1363 #endif 1384 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1364 1385 } 1365 1386 /* Update the voice (PCM) volume. */ … … 1369 1390 uint8_t lvol = s->mixer_regs[0x32]; 1370 1391 uint8_t rvol = s->mixer_regs[0x33]; 1392 1371 1393 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1372 s->pDrv->pfnSetVolume(s->pDrv, &mute, &lvol, &rvol);1394 s->pDrv->pfnSetVolume(s->pDrv, RT_BOOL(mute), lvol, rvol); 1373 1395 #else 1374 1396 AUD_set_volume(AUD_MIXER_PCM, &mute, &lvol, &rvol); 1375 #endif 1397 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1376 1398 } 1377 1399 #endif /* VBOX */ … … 1422 1444 #ifndef DEBUG_SB16_MOST 1423 1445 if (s->mixer_nreg != 0x82) { 1424 LogFlow (("SB16:mixer_read[%#x] -> %#x\n",1446 LogFlowFunc(("mixer_read[%#x] -> %#x\n", 1425 1447 s->mixer_nreg, s->mixer_regs[s->mixer_nreg])); 1426 1448 } 1427 1449 #else 1428 LogFlow (("SB16:mixer_read[%#x] -> %#x\n",1450 LogFlowFunc(("mixer_read[%#x] -> %#x\n", 1429 1451 s->mixer_nreg, s->mixer_regs[s->mixer_nreg])); 1430 1452 #endif … … 1441 1463 { 1442 1464 int temp, net; 1443 uint8_t tmpbuf[ 4096];1465 uint8_t tmpbuf[_4K]; 1444 1466 1445 1467 temp = len; 1446 1468 net = 0; 1447 1469 1448 while (temp) { 1470 while (temp) 1471 { 1449 1472 int left = dma_len - dma_pos; 1450 1473 #ifndef VBOX 1474 size_t to_copy; 1451 1475 int copied; 1476 #else 1452 1477 size_t to_copy; 1453 #else1454 1478 uint32_t copied; 1455 uint32_t to_copy; 1456 #endif 1457 1458 to_copy = audio_MIN (temp, left); 1459 if (to_copy > sizeof (tmpbuf)) { 1460 to_copy = sizeof (tmpbuf); 1461 } 1479 #endif 1480 1481 to_copy = RT_MIN(temp, left); 1482 if (to_copy > sizeof(tmpbuf)) 1483 to_copy = sizeof(tmpbuf); 1462 1484 1463 1485 #ifndef VBOX … … 1470 1492 1471 1493 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1472 copied = s->pDrv->pfnWrite(s->pDrv, s->voice, tmpbuf, copied); 1494 rc = s->pDrv->pfnWrite(s->pDrv, s->pGstStrmOut, tmpbuf, to_copy, &copied); 1495 if (RT_FAILURE(rc)) 1496 break; 1473 1497 #else 1474 1498 copied = AUD_write (s->voice, tmpbuf, copied); 1475 #endif 1499 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1476 1500 1477 1501 temp -= copied; … … 1479 1503 net += copied; 1480 1504 1481 if (!copied) { 1482 break; 1483 } 1505 if (!copied) 1506 break; 1484 1507 } 1485 1508 … … 1497 1520 1498 1521 if (s->block_size <= 0) { 1499 LogFlow (("SB16:invalid block size=%d nchan=%d dma_pos=%d dma_len=%d\n",1522 LogFlowFunc(("invalid block size=%d nchan=%d dma_pos=%d dma_len=%d\n", 1500 1523 s->block_size, nchan, dma_pos, dma_len)); 1501 1524 return dma_pos; … … 1506 1529 } 1507 1530 1531 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1532 if (s->pGstStrmOut) { 1533 #else 1508 1534 if (s->voice) { 1535 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1509 1536 free = s->audio_free & ~s->align; 1510 1537 if ((free <= 0) || !dma_len) { … … 1520 1547 1521 1548 #ifdef DEBUG_SB16_MOST 1522 LogFlow (("SB16:pos:%06d %d till:%d len:%d\n",1549 LogFlowFunc(("pos:%06d %d till:%d len:%d\n", 1523 1550 dma_pos, free, till, dma_len)); 1524 1551 #endif … … 1552 1579 1553 1580 #ifdef DEBUG_SB16_MOST 1554 LogFlow (("SB16:pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",1581 LogFlowFunc(("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n", 1555 1582 dma_pos, free, dma_len, s->left_till_irq, copy, written, 1556 1583 s->block_size)); … … 1564 1591 } 1565 1592 1566 static void SB_audio_callback (void *opaque, int free) 1567 { 1568 SB16State *s = (SB16State*)opaque; 1569 s->audio_free = free; 1593 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1594 static void sb16AudioCallback(void *pvContext, uint32_t cbFree) 1595 #else 1596 static void sb16AudioCallback(void *pvContext, int cbFree) 1597 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1598 { 1599 SB16State *pState = (SB16State*)pvContext; 1600 AssertPtrReturnVoid(pState); 1601 pState->audio_free = cbFree; 1570 1602 #ifdef VBOX 1571 1603 /* New space available, see if we can transfer more. There is no cyclic DMA timer in VBox. */ 1572 PDMDevHlpDMASchedule (s->pDevIns);1604 PDMDevHlpDMASchedule(pState->pDevIns); 1573 1605 #endif 1574 1606 } … … 1691 1723 qemu_get_buffer (f, s->mixer_regs, 256); 1692 1724 1693 if (s->voice) {1694 1725 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1695 s->pDrv->pfnCloseOut(s->pDrv, s->voice); 1696 #else 1697 AUD_close_out (&s->card, s->voice); 1698 #endif 1699 s->voice = NULL; 1700 } 1701 1702 if (s->dma_running) { 1703 if (s->freq) { 1704 1726 if (s->pGstStrmOut) 1727 { 1728 s->pDrv->pfnCloseOut(s->pDrv, s->pGstStrmOut); 1729 s->pGstStrmOut = NULL; 1730 } 1731 #else 1732 AUD_close_out (&s->card, s->voice); 1733 s->voice = NULL; 1734 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1735 1736 if (s->dma_running) 1737 { 1738 if (s->freq) 1739 { 1705 1740 s->audio_free = 0; 1706 1741 1707 1742 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1708 int rc; 1709 rc = s->pDrv->pfnOpenOut(s->pDrv, &s->voice, "sb16", s, SB_audio_callback, s->freq, 1 << s->fmt_stereo, s->fmt, 0); 1743 PDMAUDIOSTREAMCFG streamCfg; 1744 streamCfg.uHz = s->freq; 1745 streamCfg.cChannels = 1 << s->fmt_stereo; 1746 streamCfg.enmFormat = s->fmt; 1747 streamCfg.enmEndianness = PDMAUDIOHOSTENDIANESS; 1748 1749 int rc = s->pDrv->pfnOpenOut(s->pDrv, "sb16.out", 1750 sb16AudioCallback /* fnCallback */, s /* pvContext */, 1751 &streamCfg, 1752 &s->pGstStrmOut); 1753 AssertRC(rc); 1710 1754 #else 1711 1755 audsettings_t as; … … 1719 1763 "sb16", 1720 1764 s, 1721 SB_audio_callback,1765 sb16AudioCallback, 1722 1766 &as 1723 1767 ); 1724 #endif 1725 } 1726 1727 control 1728 speaker 1768 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 1769 } 1770 1771 control(s, 1); 1772 speaker(s, s->speaker); 1729 1773 } 1730 1774 … … 1743 1787 1744 1788 if (!audio) { 1745 LogFlow (("SB16:No audio state\n"));1789 LogFlowFunc(("No audio state\n")); 1746 1790 return -1; 1747 1791 } … … 1749 1793 s = qemu_mallocz (sizeof (*s)); 1750 1794 if (!s) { 1751 LogFlow (("SB16:Could not allocate memory for SB16 (%zu bytes)\n",1752 sizeof (*s)) );1795 LogFlowFunc(("Could not allocate memory for SB16 (%zu bytes)\n", 1796 sizeof (*s)); 1753 1797 return -1; 1754 1798 } … … 1772 1816 s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s); 1773 1817 if (!s->aux_ts) { 1774 LogFlow (("SB16:warning: Could not create auxiliary timer\n"));1818 LogFlowFunc(("warning: Could not create auxiliary timer\n")); 1775 1819 } 1776 1820 … … 1793 1837 1794 1838 register_savevm ("sb16", 0, 1, SB_save, SB_load, s); 1795 AUD_register_card (audio, "sb16" );1839 AUD_register_card (audio, "sb16", &s->card); 1796 1840 return 0; 1797 1841 } … … 1877 1921 } 1878 1922 1923 /** 1924 * @interface_method_impl{PDMDEVREG,pfnDestruct} 1925 */ 1926 static DECLCALLBACK(int) sb16Destruct(PPDMDEVINS pDevIns) 1927 { 1928 SB16State *pThis = PDMINS_2_DATA(pDevIns, SB16State *); 1929 1930 return VINF_SUCCESS; 1931 } 1932 1879 1933 static DECLCALLBACK(int) sb16Construct (PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle) 1880 1934 { … … 1992 2046 if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 1993 2047 #endif 1994 Log (("ac97:No attached driver!\n"));2048 LogFunc(("No attached driver!\n")); 1995 2049 else if (RT_FAILURE(rc)) 1996 2050 { … … 1999 2053 } 2000 2054 2055 legacy_reset(s); 2056 2001 2057 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2002 s->pDrv->pfnRegisterCard(s->pDrv, "sb16"); 2003 #else 2004 AUD_register_card("sb16", &s->card); 2005 #endif 2006 legacy_reset(s); 2007 2008 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2009 if (!s->pDrv->pfnIsHostVoiceOutOK(s->pDrv,s->voice)) 2010 #else 2011 if (!AUD_is_host_voice_out_ok(s->voice)) 2012 #endif 2058 if (!s->pDrv->pfnIsOutputOK(s->pDrv,s->pGstStrmOut)) 2013 2059 { 2014 LogRel (("SB16: WARNING: Unable to open PCM OUT!\n")); 2015 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2016 s->pDrv->pfnCloseOut(s->pDrv, s->voice ); 2017 #else 2018 AUD_close_out (&s->card, s->voice); 2019 #endif 2020 s->voice = NULL; 2021 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2060 LogRel(("SB16: WARNING: Unable to open PCM OUT!\n")); 2061 s->pDrv->pfnCloseOut(s->pDrv, s->pGstStrmOut ); 2062 s->pGstStrmOut = NULL; 2063 2022 2064 s->pDrv->pfnInitNull(s->pDrv); 2023 #else 2024 AUD_init_null(); 2025 #endif 2065 2026 2066 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", 2027 2067 N_("No audio devices could be opened. Selecting the NULL audio backend " 2028 2068 "with the consequence that no sound is audible")); 2029 2069 } 2070 #else 2071 AUD_register_card("sb16", &s->card); 2072 2073 if (!AUD_is_host_voice_out_ok(s->voice)) 2074 { 2075 LogRel (("SB16: WARNING: Unable to open PCM OUT!\n")); 2076 AUD_close_out (&s->card, s->voice); 2077 s->voice = NULL; 2078 2079 AUD_init_null(); 2080 2081 PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "HostAudioNotResponding", 2082 N_("No audio devices could be opened. Selecting the NULL audio backend " 2083 "with the consequence that no sound is audible")); 2084 } 2085 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 2086 2030 2087 return VINF_SUCCESS; 2031 2088 } … … 2054 2111 sb16Construct, 2055 2112 /* pfnDestruct */ 2056 NULL,2113 sb16Destruct, 2057 2114 /* pfnRelocate */ 2058 2115 NULL, -
trunk/src/VBox/Devices/Makefile.kmk
r53378 r53442 26 26 # Include sub-makefiles. 27 27 include $(PATH_SUB_CURRENT)/testcase/Makefile.kmk 28 ifdef VBOX_WITH_PDM_AUDIO_DRIVER 29 include $(PATH_SUB_CURRENT)/Audio/testcase/Makefile.kmk 30 endif 28 31 include $(PATH_SUB_CURRENT)/Input/testcase/Makefile.kmk 29 32 if defined(VBOX_WITH_INTEL_PXE) || defined(VBOX_ONLY_EXTPACKS) … … 165 168 Parallel/DevParallel.cpp \ 166 169 \ 167 Audio/mixeng.c \168 170 Input/DrvKeyboardQueue.cpp \ 169 171 Input/DrvMouseQueue.cpp \ … … 509 511 510 512 ifdef VBOX_WITH_PDM_AUDIO_DRIVER 511 VBoxDD_DEFS +=VBOX_WITH_PDM_AUDIO_DRIVER 512 endif 513 ifdef VBOX_WITH_PDM_AUDIO_DRIVER 514 VBoxDD_SOURCES += Audio/DrvAudio.c \ 515 Audio/DrvAudioUtil.c \ 516 Audio/DrvHostNullAudio.c 517 else 518 VBoxDD_SOURCES += Audio/audio.c \ 513 VBoxDD_DEFS += VBOX_WITH_PDM_AUDIO_DRIVER 514 VBoxDD_SOURCES += \ 515 Audio/AudioMixBuffer.cpp \ 516 Audio/AudioMixer.cpp \ 517 Audio/DrvAudio.cpp \ 518 Audio/DrvAudioCommon.cpp \ 519 Audio/DrvHostNullAudio.cpp 520 521 ## @todo Darwin CoreAudio driver missing! 522 523 ifeq ($(KBUILD_TARGET),win) 524 VBoxDD_SOURCES += \ 525 Audio/DrvHostDSound.cpp 526 VBoxDD_LIBS += \ 527 $(PATH_SDK_$(VBOX_WINDDK)_LIB)/dsound.lib 528 endif 529 530 ifeq ($(KBUILD_TARGET),linux) 531 VBoxDD_SOURCES += \ 532 Audio/DrvHostOssAudio.cpp 533 ifdef VBOX_WITH_PULSE 534 VBoxDD_DEFS += VBOX_WITH_PULSE 535 VBoxDD_SOURCES += \ 536 Audio/DrvHostPulseAudio.cpp \ 537 Audio/pulse_stubs.c 538 endif 539 540 ifdef VBOX_WITH_ALSA 541 VBoxDD_DEFS.linux += VBOX_WITH_ALSA 542 VBoxDD_SOURCES.linux += \ 543 Audio/DrvHostAlsaAudio.cpp \ 544 Audio/alsa_stubs.c 545 endif 546 endif 547 548 ifeq ($(KBUILD_TARGET),freebsd) 549 VBoxDD_SOURCES += \ 550 Audio/DrvHostOssAudio.cpp 551 ifdef VBOX_WITH_PULSE 552 VBoxDD_DEFS += VBOX_WITH_PULSE 553 VBoxDD_SOURCES += \ 554 Audio/DrvHostPulseAudio.cpp \ 555 Audio/pulse_stubs.c 556 endif 557 endif 558 559 ifeq ($(KBUILD_TARGET),solaris) 560 VBoxDD_SOURCES += \ 561 Audio/DrvHostSolAudio.cpp 562 ifdef VBOX_WITH_SOLARIS_OSS 563 VBoxDD_SOURCES += Audio/DrvHostOSSAudio.cpp 564 VBoxDD_DEFS += VBOX_WITH_SOLARIS_OSS 565 endif 566 endif 567 568 else # !VBOX_WITH_PDM_AUDIO_DRIVER 569 570 VBoxDD_SOURCES += \ 571 Audio/audio.c \ 519 572 Audio/audiosniffer.c \ 520 573 Audio/noaudio.c \ 521 Audio/filteraudio.c 522 endif 523 524 ifdef VBOX_WITH_ALSA 525 VBoxDD_DEFS.linux += VBOX_WITH_ALSA 526 ifdef VBOX_WITH_PDM_AUDIO_DRIVER 527 VBoxDD_DEFS.linux += VBOX_WITH_WITH_PDM_AUDIO_DRIVER 528 VBoxDD_SOURCES.linux += \ 529 Audio/DrvHostAlsaAudio.c \ 530 Audio/alsa_stubs.c 531 else 532 VBoxDD_SOURCES.linux += \ 574 Audio/filteraudio.c \ 575 Audio/mixeng.c 576 577 ifeq ($(KBUILD_TARGET),win) 578 VBoxDD_SOURCES += \ 579 Audio/dsoundaudio.c 580 endif 581 582 VBoxDD_SOURCES.darwin += \ 583 Audio/coreaudio.c 584 585 ifeq ($(KBUILD_TARGET),solaris) 586 VBoxDD_SOURCES += \ 587 Audio/solaudio.c 588 ifdef VBOX_WITH_SOLARIS_OSS 589 VBoxDD_DEFS += VBOX_WITH_SOLARIS_OSS 590 VBoxDD_SOURCES += \ 591 Audio/ossaudio.c 592 endif 593 endif 594 595 ifeq ($(KBUILD_TARGET),linux) 596 VBoxDD_SOURCES += \ 597 Audio/ossaudio.c 598 ifdef VBOX_WITH_PULSE 599 VBoxDD_DEFS += VBOX_WITH_PULSE 600 VBoxDD_SOURCES += \ 601 Audio/pulseaudio.c \ 602 Audio/pulse_stubs.c 603 endif 604 ifdef VBOX_WITH_ALSA 605 VBoxDD_DEFS += VBOX_WITH_ALSA 606 VBoxDD_SOURCES += \ 533 607 Audio/alsaaudio.c \ 534 608 Audio/alsa_stubs.c 535 endif 536 endif 537 538 ifdef VBOX_WITH_PULSE 539 VBoxDD_DEFS.linux += VBOX_WITH_PULSE 540 ifdef VBOX_WITH_PDM_AUDIO_DRIVER 541 VBoxDD_DEFS.linux += VBOX_WITH_PDM_AUDIO_DRIVER 542 VBoxDD_SOURCES.linux += \ 543 Audio/DrvHostPulseAudio.c \ 544 Audio/pulse_stubs.c 545 else 546 VBoxDD_SOURCES.linux += \ 609 endif 610 endif 611 612 ifeq ($(KBUILD_TARGET),freebsd) 613 VBoxDD_SOURCES += \ 614 Audio/ossaudio.c 615 ifdef VBOX_WITH_PULSE 616 VBoxDD_DEFS += VBOX_WITH_PULSE 617 VBoxDD_SOURCES += \ 547 618 Audio/pulseaudio.c \ 548 619 Audio/pulse_stubs.c 549 endif550 VBoxDD_DEFS.freebsd += VBOX_WITH_PULSE551 ifdef VBOX_WITH_PDM_AUDIO_DRIVER 552 VBoxDD_SOURCES.freebsd+= \553 Audio/DrvHostPulseAudio.c\554 Audio/pulse_stubs.c555 else556 VBoxDD_SOURCES .freebsd+= \557 Audio/pulseaudio.c \558 Audio/pulse_stubs.c559 endif 560 endif 561 620 endif 621 endif 622 623 ifeq ($(KBUILD_TARGET),solaris) 624 VBoxDD_SOURCES += \ 625 Audio/solaudio.c 626 ifdef VBOX_WITH_SOLARIS_OSS 627 VBoxDD_SOURCES += Audio/ossaudio.c 628 VBoxDD_DEFS += VBOX_WITH_SOLARIS_OSS 629 endif 630 endif 631 632 endif # VBOX_WITH_PDM_AUDIO_DRIVER 562 633 563 634 # --- WARNING! SLIRP MESS AHEAD! ;-) --- … … 673 744 ifeq ($(KBUILD_TARGET),darwin) 674 745 VBoxDD_SOURCES := \ 675 $(filter-out Storage/DrvHostRaw% Storage/DrvHostFloppy%, $(VBoxDD_SOURCES)) \ 676 Audio/coreaudio.c 746 $(filter-out Storage/DrvHostRaw% Storage/DrvHostFloppy%, $(VBoxDD_SOURCES)) 677 747 VBoxDD_SOURCES.darwin += \ 678 748 Serial/DrvHostSerial.cpp … … 680 750 681 751 ifeq ($(KBUILD_TARGET),freebsd) 682 ifdef VBOX_WITH_PDM_AUDIO_DRIVER 683 VBoxDD_SOURCES := \ 684 $(filter-out Storage/DrvHostFloppy%, $(VBoxDD_SOURCES)) \ 685 Audio/DrvHostOssAudio.c \ 686 Serial/DrvHostSerial.cpp 687 VBoxDD_SOURCES.freebsd += \ 688 Network/DrvTAP.cpp 689 else 690 VBoxDD_SOURCES := \ 691 $(filter-out Storage/DrvHostFloppy%, $(VBoxDD_SOURCES)) \ 692 Audio/ossaudio.c \ 693 Serial/DrvHostSerial.cpp 694 VBoxDD_SOURCES.freebsd += \ 695 Network/DrvTAP.cpp 696 endif 752 VBoxDD_SOURCES := \ 753 $(filter-out Storage/DrvHostFloppy%, $(VBoxDD_SOURCES)) 754 Serial/DrvHostSerial.cpp 755 VBoxDD_SOURCES.freebsd += \ 756 Network/DrvTAP.cpp 697 757 endif # freebsd 698 758 699 VBoxDD_SOURCES.linux += \759 VBoxDD_SOURCES.linux += \ 700 760 Network/DrvTAP.cpp \ 701 761 Parallel/DrvHostParallel.cpp \ 702 762 Serial/DrvHostSerial.cpp 703 763 704 ifdef VBOX_WITH_PDM_AUDIO_DRIVER705 VBoxDD_SOURCES.linux += \706 Audio/DrvHostOssAudio.c707 else708 VBoxDD_SOURCES.linux += \709 Audio/ossaudio.c710 endif711 712 764 ifeq ($(KBUILD_TARGET),os2) 713 765 VBoxDD_SOURCES := $(filter-out Storage/DrvHost%, $(VBoxDD_SOURCES)) … … 715 767 716 768 ifeq ($(KBUILD_TARGET),solaris) 717 VBoxDD_SOURCES := $(filter-out Storage/DrvHostFloppy%, $(VBoxDD_SOURCES))718 VBoxDD_SOURCES.solaris += \769 VBoxDD_SOURCES := $(filter-out Storage/DrvHostFloppy%, $(VBoxDD_SOURCES)) 770 VBoxDD_SOURCES.solaris += \ 719 771 Serial/DrvHostSerial.cpp 720 ifdef VBOX_WITH_PDM_AUDIO_DRIVER721 VBoxDD_SOURCES.solaris += \722 Audio/DrvHostSolAudio.c723 else724 VBoxDD_SOURCES.solaris += \725 Audio/solaudio.c726 endif727 ifdef VBOX_WITH_SOLARIS_OSS728 ifdef VBOX_WITH_PDM_AUDIO_DRIVER729 VBoxDD_SOURCES += Audio/DrvHostOssAudio.c730 else731 VBoxDD_SOURCES += Audio/ossaudio.c732 endif733 VBoxDD_DEFS += VBOX_WITH_SOLARIS_OSS734 endif735 772 ifdef VBOX_WITH_SUID_WRAPPER 736 VBoxDD_DEFS += VBOX_WITH_SUID_WRAPPER 737 endif 738 endif 739 740 VBoxDD_DEFS.win += VBOX_WITH_WIN_PARPORT_SUP 741 ifdef VBOX_WITH_PDM_AUDIO_DRIVER 742 VBoxDD_DEFS.win += VBOX_WITH_PDM_AUDIO_DRIVER 743 endif 744 VBoxDD_SOURCES.win += \ 745 Serial/DrvHostSerial.cpp \ 773 VBoxDD_DEFS += VBOX_WITH_SUID_WRAPPER 774 endif 775 endif 776 777 VBoxDD_DEFS.win += VBOX_WITH_WIN_PARPORT_SUP 778 VBoxDD_SOURCES.win += \ 779 Serial/DrvHostSerial.cpp \ 746 780 Parallel/DrvHostParallel.cpp 747 748 ifdef VBOX_WITH_PDM_AUDIO_DRIVER749 VBoxDD_SOURCES.win += \750 Audio/DrvHostDSound.c751 else752 VBoxDD_SOURCES.win += \753 Audio/dsoundaudio.c754 endif755 756 ifdef VBOX_WITH_VIRTUALKD757 VBoxDD_DEFS.win += VBOX_WITH_VIRTUALKD758 VBoxDD_SOURCES.win += \759 Misc/VirtualKD.cpp760 endif761 781 762 782 if defined(VBOX_WITH_NETFLT) … … 1350 1370 1351 1371 # 1352 # The Intel PXE rom.1372 # The Intel PXE ROM. 1353 1373 # 1354 1374 INSTALLS += VBoxExtPackPuelInsRoms -
trunk/src/VBox/Devices/build/VBoxDD.cpp
r52506 r53442 284 284 return rc; 285 285 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 286 rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvHostNullAudio); 287 if (RT_FAILURE(rc)) 288 return rc; 286 289 # if defined(RT_OS_WINDOWS) 287 290 rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvHostDSound); -
trunk/src/VBox/Devices/build/VBoxDD.h
r52473 r53442 119 119 extern const PDMDRVREG g_DrvAUDIO; 120 120 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 121 extern const PDMDRVREG g_DrvHostNullAudio; 121 122 # if defined(RT_OS_WINDOWS) 122 123 extern const PDMDRVREG g_DrvHostDSound; -
trunk/src/VBox/Devices/testcase/Makefile.kmk
r52259 r53442 5 5 6 6 # 7 # Copyright (C) 2006-201 2Oracle Corporation7 # Copyright (C) 2006-2014 Oracle Corporation 8 8 # 9 9 # This file is part of VirtualBox Open Source Edition (OSE), as … … 26 26 BLDDIRS += $(VBOX_DEVICES_TEST_OUT_DIR) 27 27 28 ## @todo Sort the features alphabetically! 28 29 VBOX_DEVICES_TESTS_FEATURES = \ 29 30 $(if $(VBOX_WITH_RAW_MODE),VBOX_WITH_RAW_MODE,) \ … … 44 45 $(if $(VBOX_WITH_VIDEOHWACCEL),VBOX_WITH_VIDEOHWACCEL,) \ 45 46 $(if $(VBOX_WITH_PCI_PASSTHROUGH_IMPL),VBOX_WITH_PCI_PASSTHROUGH_IMPL,) \ 46 $(if $(VBOX_WITH_VMSVGA),VBOX_WITH_VMSVGA,) 47 $(if $(VBOX_WITH_VMSVGA),VBOX_WITH_VMSVGA,) \ 48 $(if $(VBOX_WITH_PDM_AUDIO_DRIVER),VBOX_WITH_PDM_AUDIO_DRIVER,) 47 49 48 50 -
trunk/src/VBox/Devices/testcase/tstDeviceStructSize.cpp
r52817 r53442 7 7 8 8 /* 9 * Copyright (C) 2006-201 2Oracle Corporation9 * Copyright (C) 2006-2014 Oracle Corporation 10 10 * 11 11 * This file is part of VirtualBox Open Source Edition (OSE), as … … 105 105 #endif 106 106 107 #undef LOG_GROUP 107 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 108 # undef LOG_GROUP 109 # include <VBox/vmm/pdmaudioifs.h> 110 #endif 108 111 #include "../Audio/DevIchHda.cpp" 109 112 -
trunk/src/VBox/Main/Makefile.kmk
r53242 r53442 745 745 ifdef VBOX_WITH_PDM_AUDIO_DRIVER 746 746 VBoxC_SOURCES += \ 747 ../Devices/Audio/AudioMixBuffer.cpp \ 748 ../Devices/Audio/DrvAudioCommon.cpp \ 747 749 src-client/DrvAudioVRDE.cpp 748 750 else -
trunk/src/VBox/Main/include/ConsoleImpl.h
r53407 r53442 40 40 class AudioSniffer; 41 41 #endif 42 class AudioVRDE; 42 43 class Nvram; 43 44 #ifdef VBOX_WITH_USB_CARDREADER -
trunk/src/VBox/Main/src-client/AudioSnifferInterface.cpp
r51612 r53442 26 26 #include <VBox/vmm/cfgm.h> 27 27 #include <VBox/err.h> 28 29 #ifdef LOG_GROUP 30 #undef LOG_GROUP 31 #endif 32 #define LOG_GROUP LOG_GROUP_DEV_AUDIO 33 #include <VBox/log.h> 28 34 29 35 // -
trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
r53407 r53442 414 414 , mpVmm2UserMethods(NULL) 415 415 , m_pVMMDev(NULL) 416 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER 416 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 417 , mAudioVRDE(NULL) 418 #else 417 419 , mAudioSniffer(NULL) 418 420 #endif … … 596 598 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 597 599 unconst(mAudioVRDE) = new AudioVRDE(this); 598 Assert ComRCReturnRC(rc);600 AssertReturn(mAudioVRDE, E_FAIL); 599 601 #else 600 602 unconst(mAudioSniffer) = new AudioSniffer(this); 601 603 AssertReturn(mAudioSniffer, E_FAIL); 602 604 #endif 603 604 605 FirmwareType_T enmFirmwareType; 605 606 mMachine->COMGETTER(FirmwareType)(&enmFirmwareType); … … 730 731 } 731 732 #endif 732 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER 733 734 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 735 if (mAudioVRDE) 736 { 737 delete mAudioVRDE; 738 unconst(mAudioVRDE) = NULL; 739 } 740 #else 733 741 if (mAudioSniffer) 734 742 { … … 1433 1441 if (fu32Intercepted & VRDE_CLIENT_INTERCEPT_AUDIO) 1434 1442 { 1443 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1444 if (mAudioVRDE) 1445 mAudioVRDE->onVRDEInputIntercept(false /* fIntercept */); 1446 #else 1435 1447 mcAudioRefs--; 1436 1448 1437 1449 if (mcAudioRefs <= 0) 1438 1450 { 1439 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER1440 1451 if (mAudioSniffer) 1441 1452 { 1442 1453 PPDMIAUDIOSNIFFERPORT port = mAudioSniffer->getAudioSnifferPort(); 1443 1454 if (port) 1444 {1445 1455 port->pfnSetup(port, false, false); 1446 }1447 1456 } 1457 } 1448 1458 #endif 1449 }1450 1459 } 1451 1460 … … 1480 1489 AutoCaller autoCaller(this); 1481 1490 AssertComRCReturnVoid(autoCaller.rc()); 1482 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER 1483 LogFlowFunc(("mAudioSniffer %p, u32ClientId %d.\n", 1484 mAudioSniffer, u32ClientId)); 1485 NOREF(u32ClientId); 1486 #endif 1487 1491 1492 LogFlowFunc(("u32ClientId=%RU32\n", u32ClientId)); 1493 1494 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1495 if (mAudioVRDE) 1496 mAudioVRDE->onVRDEInputIntercept(true /* fIntercept */); 1497 #else 1488 1498 ++mcAudioRefs; 1489 1499 1490 1500 if (mcAudioRefs == 1) 1491 1501 { 1492 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER1493 1502 if (mAudioSniffer) 1494 1503 { 1495 1504 PPDMIAUDIOSNIFFERPORT port = mAudioSniffer->getAudioSnifferPort(); 1496 1505 if (port) 1497 {1498 1506 port->pfnSetup(port, true, true); 1499 1500 1507 } 1508 } 1501 1509 #endif 1502 }1503 1510 1504 1511 LogFlowFuncLeave(); -
trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
r53407 r53442 2612 2612 InsertConfigInteger(pCfg, "Object", (uintptr_t)pAudioSniffer); 2613 2613 #endif 2614 2615 2614 /* 2616 * AC'97 ICH / SoundBlaster16 audio / Intel HD Audio 2615 * AC'97 ICH / SoundBlaster16 audio / Intel HD Audio. 2617 2616 */ 2618 2617 BOOL fAudioEnabled = FALSE; … … 2630 2629 case AudioControllerType_AC97: 2631 2630 { 2632 /* default: ICH AC97*/2631 /* Default: ICH AC97. */ 2633 2632 InsertConfigNode(pDevices, "ichac97", &pDev); 2634 2633 InsertConfigNode(pDev, "0", &pInst); … … 2640 2639 case AudioControllerType_SB16: 2641 2640 { 2642 /* legacy SoundBlaster16*/2641 /* Legacy SoundBlaster16. */ 2643 2642 InsertConfigNode(pDevices, "sb16", &pDev); 2644 2643 InsertConfigNode(pDev, "0", &pInst); … … 2654 2653 case AudioControllerType_HDA: 2655 2654 { 2656 /* Intel HD Audio */2655 /* Intel HD Audio. */ 2657 2656 InsertConfigNode(pDevices, "hda", &pDev); 2658 2657 InsertConfigNode(pDev, "0", &pInst); … … 2663 2662 } 2664 2663 2665 /* the Audio driver*/2664 /* The audio driver. */ 2666 2665 InsertConfigNode(pInst, "LUN#0", &pLunL0); 2667 2666 InsertConfigString(pLunL0, "Driver", "AUDIO"); 2667 InsertConfigNode(pLunL0, "Config", &pCfg); 2668 2668 2669 2669 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2670 PCFGMNODE pLunL1; 2670 2671 InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1); 2671 InsertConfig String(pLunL1, "Driver", "PulseAudio");2672 InsertConfigNode(pLunL1, "Config", &pCfg); 2672 2673 #endif 2673 2674 InsertConfigNode(pLunL0, "Config", &pCfg);2675 2676 2674 AudioDriverType_T audioDriver; 2677 2675 hrc = audioAdapter->COMGETTER(AudioDriver)(&audioDriver); H(); … … 2680 2678 case AudioDriverType_Null: 2681 2679 { 2680 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2681 InsertConfigString(pLunL1, "Driver", "NullAudio"); 2682 #else 2682 2683 InsertConfigString(pCfg, "AudioDriver", "null"); 2684 #endif 2683 2685 break; 2684 2686 } 2685 2687 #ifdef RT_OS_WINDOWS 2686 # ifdef VBOX_WITH_WINMM2688 # ifdef VBOX_WITH_WINMM 2687 2689 case AudioDriverType_WinMM: 2688 2690 { 2691 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2692 #error "Port WinMM audio backend!" /** @todo Still needed? */ 2693 #else 2689 2694 InsertConfigString(pCfg, "AudioDriver", "winmm"); 2695 #endif 2690 2696 break; 2691 2697 } 2692 # endif2698 # endif 2693 2699 case AudioDriverType_DirectSound: 2694 2700 { 2695 2701 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2696 InsertConfigString(p Cfg, "AudioDriver", "DSoundAudio");2702 InsertConfigString(pLunL1, "Driver", "DSoundAudio"); 2697 2703 #else 2698 2704 InsertConfigString(pCfg, "AudioDriver", "dsound"); … … 2704 2710 case AudioDriverType_SolAudio: 2705 2711 { 2712 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2713 #error "Port Solaris audio backend!" /** @todo Port Solaris driver. */ 2714 #else 2706 2715 InsertConfigString(pCfg, "AudioDriver", "solaudio"); 2707 break;2708 }2709 #endif2710 #ifdef RT_OS_LINUX2711 # ifdef VBOX_WITH_ALSA2712 case AudioDriverType_ALSA:2713 {2714 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER2715 InsertConfigString(pCfg, "AudioDriver", "AlsaAudio");2716 #else2717 InsertConfigString(pCfg, "AudioDriver", "alsa");2718 2716 #endif 2719 2717 break; 2720 2718 } 2719 #endif 2720 #ifdef VBOX_WITH_ALSA 2721 case AudioDriverType_ALSA: 2722 { 2723 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2724 InsertConfigString(pLunL1, "Driver", "AlsaAudio"); 2725 # else 2726 InsertConfigString(pCfg, "AudioDriver", "alsa"); 2721 2727 # endif 2722 # ifdef VBOX_WITH_PULSE 2728 break; 2729 } 2730 #endif 2731 #ifdef VBOX_WITH_PULSE 2723 2732 case AudioDriverType_Pulse: 2724 2733 { 2725 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER2726 InsertConfigString(p Cfg, "AudioDriver", "PulseAudio");2727 # else2734 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2735 InsertConfigString(pLunL1, "Driver", "PulseAudio"); 2736 # else 2728 2737 InsertConfigString(pCfg, "AudioDriver", "pulse"); 2738 # endif 2739 break; 2740 } 2729 2741 #endif 2730 break;2731 }2732 # endif2733 #endif /* RT_OS_LINUX */2734 2742 #if defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD) || defined(VBOX_WITH_SOLARIS_OSS) 2735 2743 case AudioDriverType_OSS: 2736 2744 { 2737 InsertConfigString(pCfg, "AudioDriver", "oss"); 2745 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2746 #error "Port OSS audio backend!" /** @todo Port OSS driver. */ 2747 # else 2748 InsertConfigString(pCfg, "AudioDriver", "ossaudio"); 2749 # endif 2738 2750 break; 2739 2751 } 2740 #endif2741 #ifdef RT_OS_FREEBSD2742 # ifdef VBOX_WITH_PULSE2743 case AudioDriverType_Pulse:2744 {2745 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER2746 InsertConfigString(pCfg, "AudioDriver", "PulseAudio");2747 #else2748 InsertConfigString(pCfg, "AudioDriver", "pulse");2749 #endif2750 break;2751 }2752 # endif2753 2752 #endif 2754 2753 #ifdef RT_OS_DARWIN 2755 2754 case AudioDriverType_CoreAudio: 2756 2755 { 2756 # ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2757 InsertConfigString(pLunL1, "Driver", "CoreAudio"); 2758 # else 2757 2759 InsertConfigString(pCfg, "AudioDriver", "coreaudio"); 2760 # endif 2758 2761 break; 2759 2762 } 2760 2763 #endif 2761 2764 } 2765 2762 2766 hrc = pMachine->COMGETTER(Name)(bstr.asOutParam()); H(); 2763 InsertConfigString(pCfg, "StreamName", bstr); 2767 2764 2768 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2765 /* the Audio driver */ 2766 InsertConfigNode(pInst, "LUN#1", &pLunL0); 2767 InsertConfigString(pLunL0, "Driver", "AUDIO"); 2768 InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1); 2769 /* 2770 * The VRDE audio backend driver. This one always is there 2771 * and therefore is hardcoded here. 2772 */ 2773 InsertConfigNode(pInst, "LUN#1", &pLunL1); 2774 InsertConfigString(pLunL1, "Driver", "AUDIO"); 2775 2776 InsertConfigNode(pLunL1, "AttachedDriver", &pLunL1); 2769 2777 InsertConfigString(pLunL1, "Driver", "AudioVRDE"); 2770 InsertConfigNode(pLunL0, "Config", &pCfg); 2778 2779 InsertConfigNode(pLunL1, "Config", &pCfg); 2771 2780 InsertConfigString(pCfg, "AudioDriver", "AudioVRDE"); 2772 2781 InsertConfigString(pCfg, "StreamName", bstr); 2773 InsertConfig Node(pLunL1, "Config", &pCfg);2774 InsertConfigInteger(pCfg, "Object", (uintptr_t)mAudioVRDE);2775 InsertConfigInteger(pCfg, "ObjectVRDPServer", (uintptr_t)mConsoleVRDPServer); 2776 2782 InsertConfigInteger(pCfg, "Object", (uintptr_t)mAudioVRDE); 2783 InsertConfigInteger(pCfg, "ObjectVRDPServer", (uintptr_t)mConsoleVRDPServer); 2784 2785 /** @todo Add audio video recording driver here. */ 2777 2786 #endif 2778 2787 } -
trunk/src/VBox/Main/src-client/ConsoleVRDPServer.cpp
r52978 r53442 946 946 uint32_t fu32Intercepted) 947 947 { 948 ConsoleVRDPServer *server = static_cast<ConsoleVRDPServer*>(pvCallback); 949 950 server->mConsole->i_VRDPClientDisconnect(u32ClientId, fu32Intercepted); 951 952 if (ASMAtomicReadU32(&server->mu32AudioInputClientId) == u32ClientId) 953 { 954 Log(("AUDIOIN: disconnected client %u\n", u32ClientId)); 955 ASMAtomicWriteU32(&server->mu32AudioInputClientId, 0); 948 ConsoleVRDPServer *pServer = static_cast<ConsoleVRDPServer*>(pvCallback); 949 AssertPtrReturnVoid(pServer); 950 951 pServer->mConsole->i_VRDPClientDisconnect(u32ClientId, fu32Intercepted); 952 953 if (ASMAtomicReadU32(&pServer->mu32AudioInputClientId) == u32ClientId) 954 { 955 LogFunc(("Disconnected client %u\n", u32ClientId)); 956 ASMAtomicWriteU32(&pServer->mu32AudioInputClientId, 0); 956 957 957 958 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 958 server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputIntercept(false);959 pServer->mConsole->i_getAudioVRDE()->onVRDEInputIntercept(false); 959 960 #else 960 PPDMIAUDIOSNIFFERPORT pPort = server->mConsole->i_getAudioSniffer()->getAudioSnifferPort();961 PPDMIAUDIOSNIFFERPORT pPort = pServer->mConsole->i_getAudioSniffer()->getAudioSnifferPort(); 961 962 if (pPort) 962 963 { … … 970 971 } 971 972 972 int c = ASMAtomicDecS32(&server->mcClients);973 if (c == 0)973 int32_t cClients = ASMAtomicDecS32(&pServer->mcClients); 974 if (cClients == 0) 974 975 { 975 976 /* Features which should be enabled only if there is a client. */ 976 server->remote3DRedirect(false);977 pServer->remote3DRedirect(false); 977 978 } 978 979 } … … 981 982 void **ppvIntercept) 982 983 { 983 ConsoleVRDPServer * server = static_cast<ConsoleVRDPServer*>(pvCallback);984 ConsoleVRDPServer *pServer = static_cast<ConsoleVRDPServer*>(pvCallback); 984 985 985 986 LogFlowFunc(("%x\n", fu32Intercept)); … … 991 992 case VRDE_CLIENT_INTERCEPT_AUDIO: 992 993 { 993 server->mConsole->i_VRDPInterceptAudio(u32ClientId);994 pServer->mConsole->i_VRDPInterceptAudio(u32ClientId); 994 995 if (ppvIntercept) 995 996 { 996 *ppvIntercept = server;997 *ppvIntercept = pServer; 997 998 } 998 999 rc = VINF_SUCCESS; … … 1001 1002 case VRDE_CLIENT_INTERCEPT_USB: 1002 1003 { 1003 server->mConsole->i_VRDPInterceptUSB(u32ClientId, ppvIntercept);1004 pServer->mConsole->i_VRDPInterceptUSB(u32ClientId, ppvIntercept); 1004 1005 rc = VINF_SUCCESS; 1005 1006 } break; … … 1007 1008 case VRDE_CLIENT_INTERCEPT_CLIPBOARD: 1008 1009 { 1009 server->mConsole->i_VRDPInterceptClipboard(u32ClientId);1010 pServer->mConsole->i_VRDPInterceptClipboard(u32ClientId); 1010 1011 if (ppvIntercept) 1011 1012 { 1012 *ppvIntercept = server;1013 *ppvIntercept = pServer; 1013 1014 } 1014 1015 rc = VINF_SUCCESS; … … 1020 1021 * Only one client is allowed to intercept audio input. 1021 1022 */ 1022 if (ASMAtomicCmpXchgU32(& server->mu32AudioInputClientId, u32ClientId, 0) == true)1023 { 1024 Log (("AUDIOIN: connected client %u\n", u32ClientId));1023 if (ASMAtomicCmpXchgU32(&pServer->mu32AudioInputClientId, u32ClientId, 0) == true) 1024 { 1025 LogFunc(("Connected client %u\n", u32ClientId)); 1025 1026 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1026 server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputIntercept(true);1027 pServer->mConsole->i_getAudioVRDE()->onVRDEInputIntercept(true); 1027 1028 #else 1028 PPDMIAUDIOSNIFFERPORT pPort = server->mConsole->i_getAudioSniffer()->getAudioSnifferPort();1029 PPDMIAUDIOSNIFFERPORT pPort = pServer->mConsole->i_getAudioSniffer()->getAudioSnifferPort(); 1029 1030 if (pPort) 1030 1031 { 1031 1032 pPort->pfnAudioInputIntercept(pPort, true); 1032 1033 if (ppvIntercept) 1033 { 1034 *ppvIntercept = server; 1035 } 1034 *ppvIntercept = pServer; 1036 1035 } 1037 1036 else 1038 1037 { 1039 1038 AssertFailed(); 1040 ASMAtomicWriteU32(& server->mu32AudioInputClientId, 0);1039 ASMAtomicWriteU32(&pServer->mu32AudioInputClientId, 0); 1041 1040 rc = VERR_NOT_SUPPORTED; 1042 1041 } … … 1045 1044 else 1046 1045 { 1047 Log(("AUDIOIN: ignored client %u, active client %u\n", u32ClientId, server->mu32AudioInputClientId));1046 Log(("AUDIOIN: ignored client %u, active client %u\n", u32ClientId, pServer->mu32AudioInputClientId)); 1048 1047 rc = VERR_NOT_SUPPORTED; 1049 1048 } … … 1306 1305 uint32_t cbData) 1307 1306 { 1308 ConsoleVRDPServer *server = static_cast<ConsoleVRDPServer*>(pvCallback); 1307 ConsoleVRDPServer *pServer = static_cast<ConsoleVRDPServer*>(pvCallback); 1308 AssertPtrReturnVoid(pServer); 1309 1309 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER 1310 PPDMIAUDIOSNIFFERPORT pPort = server->mConsole->i_getAudioSniffer()->getAudioSnifferPort();1310 PPDMIAUDIOSNIFFERPORT pPort = pServer->mConsole->i_getAudioSniffer()->getAudioSnifferPort(); 1311 1311 #endif 1312 1312 … … 1315 1315 case VRDE_AUDIOIN_BEGIN: 1316 1316 { 1317 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1318 pServer->mConsole->i_getAudioVRDE()->onVRDEInputBegin(pvCtx, (PVRDEAUDIOINBEGIN)pvData); 1319 #else 1317 1320 const VRDEAUDIOINBEGIN *pParms = (const VRDEAUDIOINBEGIN *)pvData; 1318 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER1319 server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputEventBegin(pvCtx,1320 VRDE_AUDIO_FMT_SAMPLE_FREQ(pParms->fmt),1321 VRDE_AUDIO_FMT_CHANNELS(pParms->fmt),1322 VRDE_AUDIO_FMT_BITS_PER_SAMPLE(pParms->fmt),1323 VRDE_AUDIO_FMT_SIGNED(pParms->fmt)1324 );1325 #else1326 1321 pPort->pfnAudioInputEventBegin (pPort, pvCtx, 1327 1322 VRDE_AUDIO_FMT_SAMPLE_FREQ(pParms->fmt), … … 1331 1326 ); 1332 1327 #endif 1333 } break; 1328 break; 1329 } 1334 1330 1335 1331 case VRDE_AUDIOIN_DATA: 1336 {1337 1332 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1338 server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputEventData(pvCtx, pvData, cbData);1333 pServer->mConsole->i_getAudioVRDE()->onVRDEInputData(pvCtx, pvData, cbData); 1339 1334 #else 1340 1335 pPort->pfnAudioInputEventData (pPort, pvCtx, pvData, cbData); 1341 1336 #endif 1342 }break;1337 break; 1343 1338 1344 1339 case VRDE_AUDIOIN_END: 1345 {1346 1340 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1347 server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputEventEnd(pvCtx);1341 pServer->mConsole->i_getAudioVRDE()->onVRDEInputEnd(pvCtx); 1348 1342 #else 1349 1343 pPort->pfnAudioInputEventEnd (pPort, pvCtx); 1350 1344 #endif 1351 }break;1345 break; 1352 1346 1353 1347 default: 1354 return; 1355 } 1356 } 1357 1348 break; 1349 } 1350 } 1358 1351 1359 1352 ConsoleVRDPServer::ConsoleVRDPServer(Console *console) … … 3906 3899 } 3907 3900 3908 /* @todo rc not needed? */3909 3901 int ConsoleVRDPServer::SendAudioInputBegin(void **ppvUserCtx, 3910 3902 void *pvContext, … … 3914 3906 uint32_t cBits) 3915 3907 { 3916 if (mpEntryPoints && mhServer && mpEntryPoints->VRDEAudioInOpen) 3908 if ( mhServer 3909 && mpEntryPoints && mpEntryPoints->VRDEAudioInOpen) 3917 3910 { 3918 3911 uint32_t u32ClientId = ASMAtomicReadU32(&mu32AudioInputClientId); … … 3920 3913 { 3921 3914 VRDEAUDIOFORMAT audioFormat = VRDE_AUDIO_FMT_MAKE(iSampleHz, cChannels, cBits, 0); 3922 mpEntryPoints->VRDEAudioInOpen (mhServer, 3923 pvContext, 3924 u32ClientId, 3925 audioFormat, 3926 cSamples); 3927 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 3928 //*ppvUserCtx = NULL; 3929 #else 3930 *ppvUserCtx = NULL; /* This is the ConsoleVRDPServer context. 3931 - * Currently not used because only one client is allowed to 3932 - * do audio input and the client id is saved by the ConsoleVRDPServer. 3933 - */ 3934 #endif 3935 3915 mpEntryPoints->VRDEAudioInOpen(mhServer, 3916 pvContext, 3917 u32ClientId, 3918 audioFormat, 3919 cSamples); 3920 if (ppvUserCtx) 3921 *ppvUserCtx = NULL; /* This is the ConsoleVRDPServer context. 3922 * Currently not used because only one client is allowed to 3923 * do audio input and the client ID is saved by the ConsoleVRDPServer. 3924 */ 3936 3925 return VINF_SUCCESS; 3937 3926 } 3938 3927 } 3928 3929 /* 3930 * Not supported or no client connected. 3931 */ 3939 3932 return VERR_NOT_SUPPORTED; 3940 3933 } … … 3951 3944 } 3952 3945 } 3953 3954 3946 3955 3947 void ConsoleVRDPServer::QueryInfo(uint32_t index, void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut) const -
trunk/src/VBox/Main/src-client/DrvAudioVRDE.cpp
r51096 r53442 1 1 /* $Id$ */ 2 2 /** @file 3 * 4 * VBox Audio VRDE backend 3 * VRDE audio backend for Main. 5 4 */ 6 5 7 6 /* 8 * Copyright (C) 20 06-2010Oracle Corporation7 * Copyright (C) 2013-2014 Oracle Corporation 9 8 * 10 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 22 21 #include "Logging.h" 23 22 23 #include "../../Devices/Audio/DrvAudio.h" 24 #include "../../Devices/Audio/AudioMixBuffer.h" 25 26 #include <iprt/mem.h> 27 #include <iprt/cdefs.h> 28 #include <iprt/circbuf.h> 29 24 30 #include <VBox/vmm/pdmaudioifs.h> 25 31 #include <VBox/vmm/pdmdrv.h> … … 27 33 #include <VBox/vmm/cfgm.h> 28 34 #include <VBox/err.h> 29 #include <iprt/mem.h> 30 #include <iprt/cdefs.h> 31 32 33 /******************************************************************************* 34 * 35 * IO Ring Buffer section 36 * 37 ******************************************************************************/ 38 39 /* Implementation of a lock free ring buffer which could be used in a multi 40 * threaded environment. Note that only the acquire, release and getter 41 * functions are threading aware. So don't use reset if the ring buffer is 42 * still in use. */ 43 typedef struct IORINGBUFFER 44 { 45 /* The current read position in the buffer */ 46 uint32_t uReadPos; 47 /* The current write position in the buffer */ 48 uint32_t uWritePos; 49 /* How much space of the buffer is currently in use */ 50 volatile uint32_t cBufferUsed; 51 /* How big is the buffer */ 52 uint32_t cBufSize; 53 /* The buffer itself */ 54 char *pBuffer; 55 } IORINGBUFFER; 56 /* Pointer to an ring buffer structure */ 57 typedef IORINGBUFFER* PIORINGBUFFER; 58 59 PPDMDRVINS gpDrvIns; //@todo handle this bad programming; 60 61 static void IORingBufferCreate(PIORINGBUFFER *ppBuffer, uint32_t cSize) 62 { 63 PIORINGBUFFER pTmpBuffer; 64 65 AssertPtr(ppBuffer); 66 67 *ppBuffer = NULL; 68 pTmpBuffer = RTMemAllocZ(sizeof(IORINGBUFFER)); 69 if (pTmpBuffer) 70 { 71 pTmpBuffer->pBuffer = RTMemAlloc(cSize); 72 if(pTmpBuffer->pBuffer) 73 { 74 pTmpBuffer->cBufSize = cSize; 75 *ppBuffer = pTmpBuffer; 76 } 77 else 78 RTMemFree(pTmpBuffer); 79 } 80 } 81 82 static void IORingBufferDestroy(PIORINGBUFFER pBuffer) 83 { 84 if (pBuffer) 85 { 86 if (pBuffer->pBuffer) 87 RTMemFree(pBuffer->pBuffer); 88 RTMemFree(pBuffer); 89 } 90 } 91 92 DECL_FORCE_INLINE(void) IORingBufferReset(PIORINGBUFFER pBuffer) 93 { 94 AssertPtr(pBuffer); 95 96 pBuffer->uReadPos = 0; 97 pBuffer->uWritePos = 0; 98 pBuffer->cBufferUsed = 0; 99 } 100 101 DECL_FORCE_INLINE(uint32_t) IORingBufferFree(PIORINGBUFFER pBuffer) 102 { 103 AssertPtr(pBuffer); 104 return pBuffer->cBufSize - ASMAtomicReadU32(&pBuffer->cBufferUsed); 105 } 106 107 DECL_FORCE_INLINE(uint32_t) IORingBufferUsed(PIORINGBUFFER pBuffer) 108 { 109 AssertPtr(pBuffer); 110 return ASMAtomicReadU32(&pBuffer->cBufferUsed); 111 } 112 113 DECL_FORCE_INLINE(uint32_t) IORingBufferSize(PIORINGBUFFER pBuffer) 114 { 115 AssertPtr(pBuffer); 116 return pBuffer->cBufSize; 117 } 118 119 static void IORingBufferAquireReadBlock(PIORINGBUFFER pBuffer, uint32_t cReqSize, char **ppStart, uint32_t *pcSize) 120 { 121 uint32_t uUsed = 0; 122 uint32_t uSize = 0; 123 124 AssertPtr(pBuffer); 125 126 *ppStart = 0; 127 *pcSize = 0; 128 129 /* How much is in use? */ 130 uUsed = ASMAtomicReadU32(&pBuffer->cBufferUsed); 131 if (uUsed > 0) 132 { 133 /* Get the size out of the requested size, the read block till the end 134 * of the buffer & the currently used size. */ 135 uSize = RT_MIN(cReqSize, RT_MIN(pBuffer->cBufSize - pBuffer->uReadPos, uUsed)); 136 if (uSize > 0) 137 { 138 /* Return the pointer address which point to the current read 139 * position. */ 140 *ppStart = pBuffer->pBuffer + pBuffer->uReadPos; 141 *pcSize = uSize; 142 } 143 } 144 } 145 146 DECL_FORCE_INLINE(void) IORingBufferReleaseReadBlock(PIORINGBUFFER pBuffer, uint32_t cSize) 147 { 148 AssertPtr(pBuffer); 149 150 /* Split at the end of the buffer. */ 151 pBuffer->uReadPos = (pBuffer->uReadPos + cSize) % pBuffer->cBufSize; 152 ASMAtomicSubU32(&pBuffer->cBufferUsed, cSize); 153 } 154 155 static void IORingBufferAquireWriteBlock(PIORINGBUFFER pBuffer, uint32_t cReqSize, char **ppStart, uint32_t *pcSize) 156 { 157 uint32_t uFree; 158 uint32_t uSize; 159 160 AssertPtr(pBuffer); 161 162 *ppStart = 0; 163 *pcSize = 0; 164 165 /* How much is free? */ 166 uFree = pBuffer->cBufSize - ASMAtomicReadU32(&pBuffer->cBufferUsed); 167 if (uFree > 0) 168 { 169 /* Get the size out of the requested size, the write block till the end 170 * of the buffer & the currently free size. */ 171 uSize = RT_MIN(cReqSize, RT_MIN(pBuffer->cBufSize - pBuffer->uWritePos, uFree)); 172 if (uSize > 0) 173 { 174 /* Return the pointer address which point to the current write 175 * position. */ 176 *ppStart = pBuffer->pBuffer + pBuffer->uWritePos; 177 *pcSize = uSize; 178 } 179 } 180 } 181 182 DECL_FORCE_INLINE(void) IORingBufferReleaseWriteBlock(PIORINGBUFFER pBuffer, uint32_t cSize) 183 { 184 AssertPtr(pBuffer); 185 186 /* Split at the end of the buffer. */ 187 pBuffer->uWritePos = (pBuffer->uWritePos + cSize) % pBuffer->cBufSize; 188 189 ASMAtomicAddU32(&pBuffer->cBufferUsed, cSize); 190 } 191 192 /****************** Ring Buffer Function Ends *****************/ 193 194 //@todo need to see if they need to move to pdmifs.h 195 #define AUDIO_HOST_ENDIANNESS 0 196 #define VOICE_ENABLE 1 197 #define VOICE_DISABLE 2 198 199 200 /* Initialization status indicator used for the recreation of the AudioUnits. */ 201 #define CA_STATUS_UNINIT UINT32_C(0) /* The device is uninitialized */ 202 #define CA_STATUS_IN_INIT UINT32_C(1) /* The device is currently initializing */ 203 #define CA_STATUS_INIT UINT32_C(2) /* The device is initialized */ 204 #define CA_STATUS_IN_UNINIT UINT32_C(3) /* The device is currently uninitializing */ 205 206 //@todo move t_sample as a PDM interface 207 //typedef struct { int mute; uint32_t r; uint32_t l; } volume_t; 208 209 #define INT_MAX 0x7fffffff 210 volume_t nominal_volume = { 211 0, 212 INT_MAX, 213 INT_MAX 214 }; 215 216 /* The desired buffer length in milliseconds. Will be the target total stream 217 * latency on newer version of pulse. Apparent latency can be less (or more.) 218 * In case its need to be used. Currently its not used. 219 */ 220 #if 0 221 static struct 222 { 223 int buffer_msecs_out; 224 int buffer_msecs_in; 225 } confAudioVRDE 226 = 227 { 228 INIT_FIELD (.buffer_msecs_out = ) 100, 229 INIT_FIELD (.buffer_msecs_in = ) 100, 230 }; 35 36 #ifdef LOG_GROUP 37 #undef LOG_GROUP 231 38 #endif 39 #define LOG_GROUP LOG_GROUP_DEV_AUDIO 40 #include <VBox/log.h> 41 232 42 /** 233 43 * Audio VRDE driver instance data. 234 *235 * @extends PDMIAUDIOSNIFFERCONNECTOR236 44 */ 237 45 typedef struct DRVAUDIOVRDE 238 46 { 239 /** Pointer to audio VRDE object */47 /** Pointer to audio VRDE object. */ 240 48 AudioVRDE *pAudioVRDE; 241 PPDMDRVINS pDrvIns;49 PPDMDRVINS pDrvIns; 242 50 /** Pointer to the driver instance structure. */ 243 PDMIHOSTAUDIO IHostAudioR3;244 ConsoleVRDPServer *pConsoleVRDPServer;51 PDMIHOSTAUDIO IHostAudioR3; 52 ConsoleVRDPServer *pConsoleVRDPServer; 245 53 /** Pointer to the DrvAudio port interface that is above it. */ 246 PPDMIAUDIOCONNECTOR pUpPort;54 PPDMIAUDIOCONNECTOR pDrvAudio; 247 55 } DRVAUDIOVRDE, *PDRVAUDIOVRDE; 248 typedef struct PDMHOSTVOICEOUT PDMHOSTVOICEOUT; 249 typedef PDMHOSTVOICEOUT *PPDMHOSTVOICEOUT; 250 251 typedef struct VRDEVoice 252 { 253 /* Audio and audio details for recording */ 254 PDMHOSTVOICEIN pHostVoiceIn; 255 void * pvUserCtx; 256 /* Number of bytes per frame (bitsPerSample * channels) of the actual input format. */ 257 uint32_t cBytesPerFrame; 258 /* Frequency of the actual audio format. */ 259 uint32_t uFrequency; 260 /* If the actual format frequence differs from the requested format, this is not NULL. */ 261 void *rate; 262 /* Temporary buffer for st_sample_t representation of the input audio data. */ 263 void *pvSamplesBuffer; 264 /* buffer for bytes of samples (not rate converted) */ 265 uint32_t cbSamplesBufferAllocated; 266 /* Temporary buffer for frequency conversion. */ 267 void *pvRateBuffer; 268 /* buffer for bytes rate converted samples */ 269 uint32_t cbRateBufferAllocated; 270 /* A ring buffer for transferring data to the playback thread */ 271 PIORINGBUFFER pRecordedVoiceBuf; 272 t_sample * convAudioDevFmtToStSampl; 273 uint32_t fIsInit; 274 uint32_t status; 275 }; 276 typedef VRDEVoice *PVRDEVoice; 277 278 typedef struct VRDEVoiceOut 279 { 280 PDMHOSTVOICEOUT pHostVoiceOut; 56 57 typedef struct VRDESTREAMIN 58 { 59 /** Associated host input stream. */ 60 PDMAUDIOHSTSTRMIN HstStrmIn; 61 /** Number of samples captured asynchronously in the 62 * onVRDEInputXXX callbacks. */ 63 uint32_t cSamplesCaptured; 64 /** Critical section. */ 65 RTCRITSECT CritSect; 66 67 } VRDESTREAMIN, *PVRDESTREAMIN; 68 69 typedef struct VRDESTREAMOUT 70 { 71 /** Associated host output stream. */ 72 PDMAUDIOHSTSTRMOUT HstStrmOut; 281 73 uint64_t old_ticks; 282 74 uint64_t cSamplesSentPerSec; 283 }; 284 typedef VRDEVoiceOut * PVRDEVoiceOut; 285 286 AudioVRDE::AudioVRDE(Console *console) 287 : mpDrv(NULL), 288 mParent(console) 289 { 290 } 291 292 AudioVRDE::~AudioVRDE() 293 { 294 if (mpDrv) 295 { 296 mpDrv->pAudioVRDE = NULL; 297 mpDrv = NULL; 298 } 299 } 300 301 PPDMIAUDIOCONNECTOR AudioVRDE::getDrvAudioPort() 302 { 303 Assert(mpDrv); 304 return mpDrv->pUpPort; 305 } 306 307 void AudioVRDE::handleVRDESvrCmdAudioInputIntercept(bool fIntercept) 308 { 309 LogFlow(("AudioVRDE: handleVRDPCmdInputIntercept\n")); 310 } 311 312 static DECLCALLBACK(void *) drvAudioVRDEInit(PPDMIHOSTAUDIO pInterface) 313 { 314 LogFlow(("drvAudioVRDEInit \n")); 315 return 1; 316 } 317 318 static void drvAudioVRDEPcmInitInfo(PDMPCMPROPERTIES * pProps, audsettings_t *as) 319 { 320 int bits = 8, sign = 0, shift = 0; 321 LogFlow(("AudioVRDE: PcmInitInfo \n")); 322 323 switch (as->fmt) { 324 case AUD_FMT_S8: 325 sign = 1; 326 case AUD_FMT_U8: 327 break; 328 329 case AUD_FMT_S16: 330 sign = 1; 331 case AUD_FMT_U16: 332 bits = 16; 333 shift = 1; 334 break; 335 336 case AUD_FMT_S32: 337 sign = 1; 338 case AUD_FMT_U32: 339 bits = 32; 340 shift = 2; 341 break; 342 } 343 344 pProps->uFrequency = as->freq; 345 pProps->cBits = bits; 346 pProps->fSigned = sign; 347 pProps->cChannels = as->nchannels; 348 pProps->cShift = (as->nchannels == 2) + shift; 349 pProps->fAlign = (1 << pProps->cShift) - 1; 350 pProps->cbPerSec = pProps->uFrequency << pProps->cShift; 351 pProps->fSwapEndian = (as->endianness != AUDIO_HOST_ENDIANNESS); 352 } 353 354 /* 355 * Hard voice (playback) 356 */ 357 static int audio_pcm_hw_find_min_out (PPDMHOSTVOICEOUT hw, int *nb_livep) 358 { 359 PPDMGSTVOICEOUT sw; 360 PPDMGSTVOICEOUT pIter; 361 int m = INT_MAX; 362 int nb_live = 0; 363 LogFlow(("Hard Voice Playback \n")); 364 365 RTListForEach(&hw->HeadGstVoiceOut, pIter, PDMGSTVOICEOUT, ListGstVoiceOut) 366 { 367 sw = pIter; 368 if (sw->State.fActive || !sw->State.fEmpty) 369 { 370 m = audio_MIN (m, sw->cSamplesMixed); 371 nb_live += 1; 372 } 373 } 374 375 *nb_livep = nb_live; 376 return m; 377 } 378 379 int audio_pcm_hw_get_live_out2 (PPDMHOSTVOICEOUT hw, int *nb_live) 380 { 381 int smin; 382 383 smin = audio_pcm_hw_find_min_out (hw, nb_live); 384 385 if (!*nb_live) { 386 return 0; 75 } VRDESTREAMOUT, *PVRDESTREAMOUT; 76 77 static DECLCALLBACK(int) drvAudioVRDEInit(PPDMIHOSTAUDIO pInterface) 78 { 79 LogFlowFuncEnter(); 80 81 return VINF_SUCCESS; 82 } 83 84 static DECLCALLBACK(int) drvAudioVRDEInitOut(PPDMIHOSTAUDIO pInterface, 85 PPDMAUDIOHSTSTRMOUT pHstStrmOut, PPDMAUDIOSTREAMCFG pCfg, 86 uint32_t *pcSamples) 87 { 88 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3); 89 AssertPtrReturn(pDrv, VERR_INVALID_POINTER); 90 91 LogFlowFunc(("pHstStrmOut=%p, pCfg=%p\n", pHstStrmOut, pCfg)); 92 93 PVRDESTREAMOUT pVRDEStrmOut = (PVRDESTREAMOUT)pHstStrmOut; 94 AssertPtrReturn(pVRDEStrmOut, VERR_INVALID_POINTER); 95 96 if (pcSamples) 97 *pcSamples = _4K; /** @todo Make this configurable. */ 98 99 return drvAudioStreamCfgToProps(pCfg, &pVRDEStrmOut->HstStrmOut.Props); 100 } 101 102 static DECLCALLBACK(int) drvAudioVRDEInitIn(PPDMIHOSTAUDIO pInterface, 103 PPDMAUDIOHSTSTRMIN pHstStrmIn, PPDMAUDIOSTREAMCFG pCfg, 104 PDMAUDIORECSOURCE enmRecSource, 105 uint32_t *pcSamples) 106 { 107 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3); 108 AssertPtrReturn(pDrv, VERR_INVALID_POINTER); 109 110 PVRDESTREAMIN pVRDEStrmIn = (PVRDESTREAMIN)pHstStrmIn; 111 AssertPtrReturn(pVRDEStrmIn, VERR_INVALID_POINTER); 112 113 if (pcSamples) 114 *pcSamples = _4K; /** @todo Make this configurable. */ 115 116 return drvAudioStreamCfgToProps(pCfg, &pVRDEStrmIn->HstStrmIn.Props); 117 } 118 119 /** 120 * Transfers audio input formerly sent by a connected RDP client / VRDE backend 121 * (using the onVRDEInputXXX methods) over to the VRDE host (VM). The audio device 122 * emulation then will read and send the data to the guest. 123 * 124 * @return IPRT status code. 125 * @param pInterface 126 * @param pHstStrmIn 127 * @param pcSamplesCaptured 128 */ 129 static DECLCALLBACK(int) drvAudioVRDECaptureIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMIN pHstStrmIn, 130 uint32_t *pcSamplesCaptured) 131 { 132 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 133 AssertPtrReturn(pHstStrmIn, VERR_INVALID_POINTER); 134 AssertPtrReturn(pcSamplesCaptured, VERR_INVALID_POINTER); 135 136 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3); 137 AssertPtrReturn(pDrv, VERR_INVALID_POINTER); 138 139 PVRDESTREAMIN pVRDEStrmIn = (PVRDESTREAMIN)pHstStrmIn; 140 AssertPtrReturn(pVRDEStrmIn, VERR_INVALID_POINTER); 141 142 /** @todo Use CritSect! */ 143 144 int rc; 145 146 uint32_t cProcessed = 0; 147 if (pVRDEStrmIn->cSamplesCaptured) 148 { 149 rc = audioMixBufMixToParent(&pVRDEStrmIn->HstStrmIn.MixBuf, pVRDEStrmIn->cSamplesCaptured, 150 &cProcessed); 387 151 } 388 152 else 389 { 390 int live = smin; 391 392 if (live < 0 || live > hw->cSamples) 393 { 394 LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples)); 395 return 0; 396 } 397 return live; 398 } 399 } 400 401 402 int audio_pcm_hw_get_live_out (PPDMHOSTVOICEOUT hw) 403 { 404 int nb_live; 405 int live; 406 407 live = audio_pcm_hw_get_live_out2 (hw, &nb_live); 408 if (live < 0 || live > hw->cSamples) 409 { 410 LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples)); 411 return 0; 412 } 413 return live; 414 } 415 416 /* 417 * Hard voice (capture) 418 */ 419 static int audio_pcm_hw_find_min_in (PPDMHOSTVOICEIN hw) 420 { 421 PPDMGSTVOICEIN pIter; 422 int m = hw->cSamplesCaptured; 423 424 RTListForEach(&hw->HeadGstVoiceIn, pIter, PDMGSTVOICEIN, ListGstVoiceIn) 425 { 426 if (pIter->State.fActive) 427 { 428 m = audio_MIN (m, pIter->cHostSamplesAcquired); 429 } 430 } 431 return m; 432 } 433 434 int audio_pcm_hw_get_live_in (PPDMHOSTVOICEIN hw) 435 { 436 int live = hw->cSamplesCaptured - audio_pcm_hw_find_min_in (hw); 437 if (live < 0 || live > hw->cSamples) 438 { 439 LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples)); 440 return 0; 441 } 442 return live; 443 } 444 445 static inline void *advance (void *p, int incr) 446 { 447 uint8_t *d = (uint8_t*)p; 448 return (d + incr); 449 } 450 451 uint64_t audio_get_ticks_per_sec (void) 452 { 453 return PDMDrvHlpTMGetVirtualFreq (gpDrvIns); 454 } 455 456 uint64_t audio_get_clock (void) 457 { 458 return PDMDrvHlpTMGetVirtualTime (gpDrvIns); 459 } 460 461 void VRDEReallocSampleBuf(PVRDEVoice pVRDEVoice, uint32_t cSamples) 462 { 463 uint32_t cbBuffer = cSamples * sizeof(PDMHOSTSTEREOSAMPLE); 464 if (cbBuffer > pVRDEVoice->cbSamplesBufferAllocated) 465 { 466 if (pVRDEVoice->pvSamplesBuffer) 467 { 468 RTMemFree(pVRDEVoice->pvSamplesBuffer); 469 pVRDEVoice->pvSamplesBuffer = NULL; 470 } 471 pVRDEVoice->pvSamplesBuffer = RTMemAlloc(cbBuffer); 472 if (pVRDEVoice->pvSamplesBuffer) 473 pVRDEVoice->cbSamplesBufferAllocated = cbBuffer; 474 else 475 pVRDEVoice->cbSamplesBufferAllocated = 0; 476 } 477 478 } 479 480 void VRDEReallocRateAdjSampleBuf(PVRDEVoice pVRDEVoice, uint32_t cSamples) 481 { 482 uint32_t cbBuffer = cSamples * sizeof(PDMHOSTSTEREOSAMPLE); 483 if (cbBuffer > pVRDEVoice->cbRateBufferAllocated) 484 { 485 RTMemFree(pVRDEVoice->pvRateBuffer); 486 pVRDEVoice->pvRateBuffer = RTMemAlloc(cbBuffer); 487 if (pVRDEVoice->pvRateBuffer) 488 pVRDEVoice->cbRateBufferAllocated = cbBuffer; 489 else 490 pVRDEVoice->cbRateBufferAllocated = 0; 491 } 492 } 493 494 /******************************************************************************* 153 rc = VINF_SUCCESS; 154 155 if (RT_SUCCESS(rc)) 156 { 157 *pcSamplesCaptured = cProcessed; 158 159 Assert(pVRDEStrmIn->cSamplesCaptured >= cProcessed); 160 pVRDEStrmIn->cSamplesCaptured -= cProcessed; 161 } 162 163 LogFlowFunc(("cSamplesCaptured=%RU32, cProcessed=%RU32\n", 164 pVRDEStrmIn->cSamplesCaptured, cProcessed, rc)); 165 return rc; 166 } 167 168 /** 169 * Transfers VM audio output over to the VRDE instance for playing remotely 170 * on the client. 495 171 * 496 * AudioVRDE input section 497 * 498 ******************************************************************************/ 499 500 /* 501 * Callback to feed audio input buffer. Samples format is be the same as 502 * in the voice. The caller prepares st_sample_t. 503 * 504 * @param cbSamples Size of pvSamples array in bytes. 505 * @param pvSamples Points to an array of samples. 506 * 507 * @return IPRT status code. 508 */ 509 static int fltRecordingCallback(PVRDEVoice pVRDEVoice, uint32_t cbSamples, const void *pvSamples) 510 { 511 int rc = VINF_SUCCESS; 512 uint32_t csAvail = 0; 513 uint32_t csToWrite = 0; 514 uint32_t cbToWrite = 0; 515 uint32_t csWritten = 0; 516 char *pcDst = NULL; 517 518 LogFlow(("audio-filter: fltRecordingCallback\n")); 519 520 Assert((cbSamples % sizeof(PDMHOSTSTEREOSAMPLE)) == 0); 521 522 if (!pVRDEVoice->fIsInit) 523 return VINF_SUCCESS; 524 525 /* If nothing is pending return immediately. */ 526 if (cbSamples == 0) 527 return VINF_SUCCESS; 528 529 /* How much space is free in the ring buffer? */ 530 PPDMHOSTSTEREOSAMPLE psSrc; 531 csAvail = IORingBufferFree(pVRDEVoice->pRecordedVoiceBuf) / sizeof(PDMHOSTSTEREOSAMPLE); /* bytes -> samples */ 532 533 /* How much space is used in the audio buffer. Use the smaller size of the too. */ 534 csAvail = RT_MIN(csAvail, cbSamples / sizeof(PDMHOSTSTEREOSAMPLE)); 535 536 /* Iterate as long as data is available */ 537 while(csWritten < csAvail) 538 { 539 /* How much is left? */ 540 csToWrite = csAvail - csWritten; 541 cbToWrite = csToWrite * sizeof(PDMHOSTSTEREOSAMPLE); 542 543 /* Try to acquire the necessary space from the ring buffer. */ 544 IORingBufferAquireWriteBlock(pVRDEVoice->pRecordedVoiceBuf, cbToWrite, &pcDst, &cbToWrite); 545 546 /* How much do we get? */ 547 csToWrite = cbToWrite / sizeof(PDMHOSTSTEREOSAMPLE); 548 549 /* Break if nothing is free anymore. */ 550 if (RT_UNLIKELY(csToWrite == 0)) 551 break; 552 553 /* Copy the data from the audio buffer to the ring buffer in PVRDEVoice. */ 554 memcpy(pcDst, (uint8_t *)pvSamples + (csWritten * sizeof(PDMHOSTSTEREOSAMPLE)), cbToWrite); 555 556 /* Release the ring buffer, so the main thread could start reading this data. */ 557 IORingBufferReleaseWriteBlock(pVRDEVoice->pRecordedVoiceBuf, cbToWrite); 558 559 csWritten += csToWrite; 560 } 561 562 LogFlow(("AudioVRDE: [Input] Finished writing buffer with %RU32 samples (%RU32 bytes)\n", 563 csWritten, csWritten * sizeof(PDMHOSTSTEREOSAMPLE))); 564 565 return rc; 566 } 567 568 569 STDMETHODIMP AudioVRDE::handleVRDESvrCmdAudioInputEventBegin(void *pvContext, int iSampleHz, int cChannels, 570 int cBits, bool fUnsigned) 571 { 572 int bitIdx; 573 PVRDEVoice pVRDEVoice = (PVRDEVoice)pvContext; 574 LogFlow(("AudioVRDE: handleVRDPCmdInputEventBegin\n")); 575 /* Prepare a format convertion for the actually used format. */ 576 pVRDEVoice->cBytesPerFrame = ((cBits + 7) / 8) * cChannels; 577 if (cBits == 16) 578 { 579 bitIdx = 1; 580 } 581 else if (cBits == 32) 582 { 583 bitIdx = 2; 584 } 585 else 586 { 587 bitIdx = 0; 588 } 589 //PPDMIAUDIOCONNECTOR pPort = server->mConsole->getAudioVRDE()->getDrvAudioPort(); 590 /* Call DrvAudio interface to get the t_sample type conversion function */ 591 pVRDEVoice->convAudioDevFmtToStSampl = mpDrv->pUpPort->pfnConvDevFmtToStSample(mpDrv->pUpPort, 592 (cChannels == 2) ? 1 : 0, 593 !fUnsigned, 0, bitIdx 594 ); 595 if (pVRDEVoice->convAudioDevFmtToStSampl) 596 { 597 LogFlow(("AudioVRDE: Failed to get the conversion function \n")); 598 } 599 LogFlow(("AudioVRDE: Required freq as requested by VRDP Server = %d\n", iSampleHz)); 600 //if (iSampleHz && iSampleHz != pVRDEVoice->pHostVoiceIn.Props.uFrequency) 601 { 602 /* @todo if the above condition is false then pVRDEVoice->uFrequency will remain 0 */ 603 pVRDEVoice->rate = mpDrv->pUpPort->pfnPrepareAudioConversion(mpDrv->pUpPort, iSampleHz, 604 pVRDEVoice->pHostVoiceIn.Props.uFrequency); 605 pVRDEVoice->uFrequency = iSampleHz; 606 LogFlow(("AudioVRDE: pVRDEVoice assigned requested freq =%d\n", pVRDEVoice->uFrequency)); 607 } 608 return VINF_SUCCESS; 609 } 610 611 /* 612 * pvContext: pointer to VRDP voice returned by the VRDP server. The is same pointer that we initialized in 613 * drvAudioVRDEDisableEnableIn VOICE_ENABLE case. 614 */ 615 void AudioVRDE::handleVRDESvrCmdAudioInputEventData(void *pvContext, const void *pvData, uint32_t cbData) 616 { 617 PVRDEVoice pVRDEVoice = (PVRDEVoice)pvContext; 618 PPDMHOSTSTEREOSAMPLE pHostStereoSampleBuf; /* target sample buffer */ 619 PPDMHOSTSTEREOSAMPLE pConvertedSampleBuf; /* samples adjusted for rate */ 620 uint32_t cSamples = cbData / pVRDEVoice->cBytesPerFrame; /* Count of samples */ 621 void * pTmpSampleBuf = NULL; 622 uint32_t cConvertedSamples; /* samples adjusted for rate */ 623 uint32_t cbSamples; /* count of bytes occupied by samples */ 624 uint32_t rc; 625 LogFlow(("AudioVRDE: handleVRDPCmdInputEventData cbData = %d, bytesperfram=%d\n", 626 cbData, pVRDEVoice->cBytesPerFrame)); 627 628 VRDEReallocSampleBuf(pVRDEVoice, cSamples); 629 pHostStereoSampleBuf = (PPDMHOSTSTEREOSAMPLE)pVRDEVoice->pvSamplesBuffer; 630 pVRDEVoice->convAudioDevFmtToStSampl(pHostStereoSampleBuf, pvData, cSamples, &nominal_volume); 631 632 /* count of rate adjusted samples */ 633 pVRDEVoice->uFrequency = 22100; /* @todo handle this. How pVRDEVoice will get proper value */ 634 cConvertedSamples = (cSamples * pVRDEVoice->pHostVoiceIn.Props.uFrequency) / pVRDEVoice->uFrequency; 635 VRDEReallocRateAdjSampleBuf(pVRDEVoice, cConvertedSamples); 636 637 pConvertedSampleBuf = (PPDMHOSTSTEREOSAMPLE)pVRDEVoice->pvRateBuffer; 638 639 if (pConvertedSampleBuf) 640 { 641 uint32_t cSampleSrc = cSamples; 642 uint32_t cSampleDst = cConvertedSamples; 643 mpDrv->pUpPort->pfnDoRateConversion(mpDrv->pUpPort, pVRDEVoice->rate, pHostStereoSampleBuf, 644 pConvertedSampleBuf, &cSampleSrc, &cConvertedSamples); 645 pTmpSampleBuf = pConvertedSampleBuf; 646 cbSamples = cConvertedSamples * sizeof(PDMHOSTSTEREOSAMPLE); 647 } 648 649 if (cbSamples) 650 { 651 rc = fltRecordingCallback(pVRDEVoice, cbSamples, pTmpSampleBuf); 652 } 653 } 654 655 /* 656 * pvContext: pointer to VRDP voice returned by the VRDP server. The is same pointer that we initialized in 657 * drvAudioVRDEDisableEnableIn VOICE_ENABLE case. 658 */ 659 void AudioVRDE::handleVRDESvrCmdAudioInputEventEnd(void *pvContext) 660 { 661 PVRDEVoice pVRDEVoice = (PVRDEVoice)pvContext; 662 LogFlow(("AudioVRDE: handleVRDPCmdInputEventEnd\n")); 663 /* The caller will not use this context anymore. */ 664 if (pVRDEVoice->rate) 665 { 666 mpDrv->pUpPort->pfnEndAudioConversion(mpDrv->pUpPort, pVRDEVoice->rate); 667 } 668 669 if (pVRDEVoice->pvSamplesBuffer) 670 { 671 RTMemFree(pVRDEVoice->pvSamplesBuffer); 672 pVRDEVoice->pvSamplesBuffer = NULL; 673 } 674 if(pVRDEVoice->pvRateBuffer) 675 { 676 RTMemFree(pVRDEVoice->pvRateBuffer); 677 pVRDEVoice->pvRateBuffer = NULL; 678 } 679 } 680 681 static DECLCALLBACK(int) drvAudioVRDEInitOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT pHostVoiceOut, audsettings_t *as) 682 { 683 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3); 684 685 PVRDEVoiceOut pVRDEVoiceOut = (PVRDEVoiceOut)pHostVoiceOut; 686 LogFlow(("DrvAudioVRDEInitOut: audio input begin cShift=%d\n", pHostVoiceOut->Props.cShift)); 687 pHostVoiceOut->cSamples = 6174; 688 drvAudioVRDEPcmInitInfo(&pVRDEVoiceOut->pHostVoiceOut.Props, as); 689 return VINF_SUCCESS; 690 691 } 692 693 static DECLCALLBACK(int) drvAudioVRDEInitIn (PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN pHostVoiceIn, audsettings_t *as) 694 { 695 LogFlow(("DrvAudioVRDE: drvAudioVRDEInitIn \n")); 696 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3); 697 PVRDEVoice pVRDEVoice = (PVRDEVoice)pHostVoiceIn; 698 pHostVoiceIn->cSamples = 6174; 699 drvAudioVRDEPcmInitInfo(&pVRDEVoice->pHostVoiceIn.Props, as); 700 return VINF_SUCCESS; 701 } 702 703 static DECLCALLBACK(int) drvAudioVRDEPlayIn(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN pHostVoiceIn) 704 { 705 uint32_t cbAvlblRingBuffer = 0; 706 uint32_t cSamplesRingBuffer = 0; 707 uint32_t cSamplesToRead = 0; 708 uint32_t cSamplesRead = 0; 709 uint32_t cbToRead; 710 char *pcSrc; 711 PDMHOSTSTEREOSAMPLE * psDst; 712 //@todo take care of the size of the buffer allocated to pHostVoiceIn 713 PVRDEVoice pVRDEVoice = (PVRDEVoice)pHostVoiceIn; 714 LogFlow(("DrvAudioVRDE: drvAudioVRDEPlayIn \n")); 715 716 /* use this from DrvHostCoreAudio.c */ 717 if (ASMAtomicReadU32(&pVRDEVoice->status) != CA_STATUS_INIT) 718 { 719 LogFlow(("AudioVRDE: VRDE voice not initialized \n")); 720 return 0; 721 } 722 723 /* how much space is used in the ring buffer in pRecordedVocieBuf with pAudioVRDE . Bytes-> samples*/ 724 cSamplesRingBuffer = IORingBufferUsed(pVRDEVoice->pRecordedVoiceBuf) / sizeof(PDMHOSTSTEREOSAMPLE); 725 726 /* How much space is available in the mix buffer. Use the smaller size of the too. */ 727 cSamplesRingBuffer = RT_MIN(cSamplesRingBuffer, (uint32_t)(pVRDEVoice->pHostVoiceIn.cSamples - 728 audio_pcm_hw_get_live_in (&pVRDEVoice->pHostVoiceIn))); 729 LogFlow(("AudioVRDE: [Input] Start reading buffer with %d samples (%d bytes)\n", cSamplesRingBuffer, 730 cSamplesRingBuffer * sizeof(PDMHOSTSTEREOSAMPLE))); 731 732 /* Iterate as long as data is available */ 733 while (cSamplesRead < cSamplesRingBuffer) 734 { 735 /* How much is left? Split request at the end of our samples buffer. */ 736 cSamplesToRead = RT_MIN(cSamplesRingBuffer - cSamplesRead, 737 (uint32_t)(pVRDEVoice->pHostVoiceIn.cSamples - pVRDEVoice->pHostVoiceIn.offWrite)); 738 cbToRead = cSamplesToRead * sizeof(PDMHOSTSTEREOSAMPLE); 739 LogFlow(("AudioVRDE: [Input] Try reading %RU32 samples (%RU32 bytes)\n", cSamplesToRead, cbToRead)); 740 741 /* Try to acquire the necessary block from the ring buffer. Remeber in fltRecrodCallback we 742 * we are filling this buffer with the audio data available from VRDP. Here we are reading it 743 */ 744 /*todo do I need to introduce a thread to fill the buffer in fltRecordcallback. So that 745 * filling is in separate thread and the reading of that buffer is in separate thread 746 */ 747 IORingBufferAquireReadBlock(pVRDEVoice->pRecordedVoiceBuf, cbToRead, &pcSrc, &cbToRead); 748 749 /* How much to we get? */ 750 cSamplesToRead = cbToRead / sizeof(PDMHOSTSTEREOSAMPLE); 751 LogFlow(("AuderVRDE: [Input] There are %d samples (%d bytes) available\n", cSamplesToRead, cbToRead)); 752 753 /* Break if nothing is used anymore. */ 754 if (cSamplesToRead == 0) 755 { 756 LogFlow(("AudioVRDE: Nothing to read \n")); 757 break; 758 } 759 760 /* Copy the data from our ring buffer to the mix buffer. */ 761 psDst = pVRDEVoice->pHostVoiceIn.pConversionBuf + pVRDEVoice->pHostVoiceIn.offWrite; 762 memcpy(psDst, pcSrc, cbToRead); 763 764 /* Release the read buffer, so it could be used for new data. */ 765 IORingBufferReleaseReadBlock(pVRDEVoice->pRecordedVoiceBuf, cbToRead); 766 767 pVRDEVoice->pHostVoiceIn.offWrite = (pVRDEVoice->pHostVoiceIn.offWrite + cSamplesToRead) 768 % pVRDEVoice->pHostVoiceIn.cSamples; 769 770 /* How much have we reads so far. */ 771 cSamplesRead += cSamplesToRead; 772 } 773 LogFlow(("AudioVRDE: [Input] Finished reading buffer with %d samples (%d bytes)\n", 774 cSamplesRead, cSamplesRead * sizeof(PDMHOSTSTEREOSAMPLE))); 775 776 return cSamplesRead; 777 } 778 779 static DECLCALLBACK(int) drvAudioVRDEPlayOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT pHostVoiceOut) 780 { 781 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3); 782 PVRDEVoiceOut pVRDEVoiceOut = (PVRDEVoiceOut)pHostVoiceOut; 783 int live; 784 uint8_t *pu8Dst; 785 int cSamplesPlayed; 786 int cSamplesToSend = 0; 172 * @return IPRT status code. 173 * @param pInterface 174 * @param pHstStrmOut 175 * @param pcSamplesPlayed 176 */ 177 static DECLCALLBACK(int) drvAudioVRDEPlayOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMOUT pHstStrmOut, 178 uint32_t *pcSamplesPlayed) 179 { 180 AssertPtrReturn(pInterface, VERR_INVALID_POINTER); 181 AssertPtrReturn(pHstStrmOut, VERR_INVALID_POINTER); 182 /* pcSamplesPlayed is optional. */ 183 184 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3); 185 AssertPtrReturn(pDrv, VERR_INVALID_POINTER); 186 PVRDESTREAMOUT pVRDEStrmOut = (PVRDESTREAMOUT)pHstStrmOut; 187 AssertPtrReturn(pVRDEStrmOut, VERR_INVALID_POINTER); 188 787 189 /* 788 190 * Just call the VRDP server with the data. 789 191 */ 790 live = audio_pcm_hw_get_live_out (pHostVoiceOut); 791 uint64_t now = audio_get_clock(); 792 uint64_t ticks = now - pVRDEVoiceOut->old_ticks; 793 uint64_t ticks_per_second = audio_get_ticks_per_sec(); 794 cSamplesPlayed = (int)((2 * ticks * pHostVoiceOut->Props.uFrequency + ticks_per_second) / ticks_per_second / 2); 795 if (cSamplesPlayed < 0) 192 uint32_t live = drvAudioHstOutSamplesLive(pHstStrmOut, NULL /* pcStreamsLive */); 193 uint64_t now = PDMDrvHlpTMGetVirtualTime(pDrv->pDrvIns); 194 uint64_t ticks = now - pVRDEStrmOut->old_ticks; 195 uint64_t ticks_per_second = PDMDrvHlpTMGetVirtualFreq(pDrv->pDrvIns); 196 197 uint32_t cSamplesPlayed = (int)((2 * ticks * pHstStrmOut->Props.uHz + ticks_per_second) / ticks_per_second / 2); 198 if (!cSamplesPlayed) 796 199 cSamplesPlayed = live; 797 pHostVoiceOut->Props.cBits = 128; 798 VRDEAUDIOFORMAT format = VRDE_AUDIO_FMT_MAKE(pHostVoiceOut->Props.uFrequency, 799 pHostVoiceOut->Props.cChannels, 800 pHostVoiceOut->Props.cBits, /* bits per sample */ 801 !pHostVoiceOut->Props.fSigned); 802 LogFlow(("DrvAudioVRDE: send audio sample freq=%d, chan=%d, cBits = %d, fsigned = %d, cSamples=%d format=%d \n", 803 pHostVoiceOut->Props.uFrequency, pHostVoiceOut->Props.cChannels, 804 pHostVoiceOut->Props.cBits, pHostVoiceOut->Props.fSigned, 805 pHostVoiceOut->cSamples, format) 806 ); 807 pVRDEVoiceOut->old_ticks = now; 808 cSamplesToSend = RT_MIN(live, cSamplesPlayed); 809 if (pHostVoiceOut->offRead + cSamplesToSend > pHostVoiceOut->cSamples) 810 { 811 /* send the samples till the end of pHostStereoSampleBuf */ 812 pDrv->pConsoleVRDPServer->SendAudioSamples(&pHostVoiceOut->pHostSterioSampleBuf[pHostVoiceOut->offRead], 813 (pHostVoiceOut->cSamples - pHostVoiceOut->offRead), format); 814 /*pHostStereoSampleBuff already has the samples which exceeded its space. They have overwriten the old 815 * played sampled starting from offset 0. So based on the number of samples that we had to play, 816 * read the number of samples from offset 0 . 817 */ 818 pDrv->pConsoleVRDPServer->SendAudioSamples(&pHostVoiceOut->pHostSterioSampleBuf[0], 819 (cSamplesToSend - (pHostVoiceOut->cSamples - 820 pHostVoiceOut->offRead)), 821 format); 822 } 823 else 824 { 825 pDrv->pConsoleVRDPServer->SendAudioSamples(&pHostVoiceOut->pHostSterioSampleBuf[pHostVoiceOut->offRead], 826 cSamplesToSend, format); 827 } 828 pHostVoiceOut->offRead = (pHostVoiceOut->offRead + cSamplesToSend) % pHostVoiceOut->cSamples; 829 return cSamplesToSend; 830 } 831 832 static DECLCALLBACK(void) drvAudioVRDEFiniIn(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN hw) 833 { 834 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3); 835 LogFlow(("DrvAudioVRDE: drvAudioVRDEFiniIn \n")); 836 pDrv->pConsoleVRDPServer->SendAudioInputEnd(NULL); 837 } 838 839 static DECLCALLBACK(void) drvAudioVRDEFiniOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT pHostVoiceOut) 840 { 841 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3); 842 LogFlow(("DrvAudioVRDE: audio input end\n")); 843 } 844 845 static DECLCALLBACK(int) drvAudioVRDEDisableEnableOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT hw, int cmd) 846 { 847 LogFlow(("DrvAudioVRDE: drvAudioVRDEDisableEnableOut \n")); 848 return VINF_SUCCESS; 849 } 850 851 static DECLCALLBACK(int) drvAudioVRDEDisableEnableIn(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN pHostVoiceIn, int cmd) 852 { 853 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3); 854 855 /* Initialize VRDEVoice and return to VRDP server which returns this struct back to us 856 * in the form void * pvContext 857 */ 858 PVRDEVoice pVRDEVoice = (PVRDEVoice)pHostVoiceIn; 859 LogFlow(("DrvAudioVRDE: drvAudioVRDEDisableEnableIn \n")); 860 /* initialize only if not already done */ 861 if (cmd == VOICE_ENABLE) 862 { 863 //@todo if (!pVRDEVoice->fIsInit) 864 // IORingBufferReset(pVRDEVoice->pRecordedVoiceBuf); 865 LogFlow(("DrvAudioVRDE: Intializing the VRDE params and buffer \n")); 866 pVRDEVoice->fIsInit = 1; 867 pVRDEVoice->pHostVoiceIn = *pHostVoiceIn; 868 pVRDEVoice->cBytesPerFrame =1 ; 869 pVRDEVoice->uFrequency = 0; 870 pVRDEVoice->rate = NULL; 871 pVRDEVoice->cbSamplesBufferAllocated = 0; 872 pVRDEVoice->pvRateBuffer = NULL; 873 pVRDEVoice->cbRateBufferAllocated = 0; 874 875 pVRDEVoice->pHostVoiceIn.cSamples = 2048; 876 /* Initialize the hardware info section with the audio settings */ 877 878 ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_IN_INIT); 879 880 /* Create the internal ring buffer. */ 881 IORingBufferCreate(&pVRDEVoice->pRecordedVoiceBuf, 882 pVRDEVoice->pHostVoiceIn.cSamples * sizeof(PDMHOSTSTEREOSAMPLE)); 883 884 if (!RT_VALID_PTR(pVRDEVoice->pRecordedVoiceBuf)) 200 201 VRDEAUDIOFORMAT format = VRDE_AUDIO_FMT_MAKE(pHstStrmOut->Props.uHz, 202 pHstStrmOut->Props.cChannels, 203 pHstStrmOut->Props.cBits, 204 pHstStrmOut->Props.fSigned); 205 206 LogFlowFunc(("hz=%d, chan=%d, cBits=%d, fSigned=%RTbool, format=%ld\n", 207 pHstStrmOut->Props.uHz, pHstStrmOut->Props.cChannels, 208 pHstStrmOut->Props.cBits, pHstStrmOut->Props.fSigned, 209 format)); 210 211 pVRDEStrmOut->old_ticks = now; 212 int cSamplesToSend = RT_MIN(live, cSamplesPlayed); 213 214 uint32_t cReadTotal = 0; 215 216 PPDMAUDIOSAMPLE pSamples; 217 uint32_t cRead; 218 int rc = audioMixBufAcquire(&pHstStrmOut->MixBuf, cSamplesToSend, 219 &pSamples, &cRead); 220 if (RT_SUCCESS(rc)) 221 { 222 cReadTotal = cRead; 223 pDrv->pConsoleVRDPServer->SendAudioSamples(pSamples, cRead, format); 224 225 if (rc == VINF_TRY_AGAIN) 885 226 { 886 LogRel(("AudioVRDE: [Input] Failed to create internal ring buffer\n")); 887 return VERR_NO_MEMORY; 227 rc = audioMixBufAcquire(&pHstStrmOut->MixBuf, cSamplesToSend - cRead, 228 &pSamples, &cRead); 229 if (RT_SUCCESS(rc)) 230 { 231 cReadTotal += cRead; 232 pDrv->pConsoleVRDPServer->SendAudioSamples(pSamples, cRead, format); 233 } 888 234 } 889 890 ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_INIT); 891 return pDrv->pConsoleVRDPServer->SendAudioInputBegin(NULL, pVRDEVoice, pHostVoiceIn->cSamples, 892 pHostVoiceIn->Props.uFrequency, 893 pHostVoiceIn->Props.cChannels, pHostVoiceIn->Props.cBits); 894 } 895 else if (cmd == VOICE_DISABLE) 896 { 897 LogFlow(("DrvAudioVRDE: Cmd to disable VRDE \n")); 898 pVRDEVoice->fIsInit = 0; 899 ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_IN_UNINIT); 900 IORingBufferDestroy(pVRDEVoice->pRecordedVoiceBuf); 901 pVRDEVoice->pRecordedVoiceBuf = NULL; 902 ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_UNINIT); 235 } 236 237 audioMixBufFinish(&pHstStrmOut->MixBuf, cReadTotal); 238 239 if (pcSamplesPlayed) 240 *pcSamplesPlayed = cReadTotal; 241 242 LogFlowFunc(("cSamplesToSend=%RU32, rc=%Rrc\n", cSamplesToSend, rc)); 243 return rc; 244 } 245 246 static DECLCALLBACK(int) drvAudioVRDEFiniIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMIN pHstStrmIn) 247 { 248 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3); 249 AssertPtrReturn(pDrv, VERR_INVALID_POINTER); 250 251 if (pDrv->pConsoleVRDPServer) 903 252 pDrv->pConsoleVRDPServer->SendAudioInputEnd(NULL); 904 } 905 return VINF_SUCCESS; 906 } 907 908 static DECLCALLBACK(void) drvAudioVRDEGetConf(PPDMIBASE pInterface, PPDMAUDIOCONF pAudioConf) 909 { 910 LogFlow(("drvAudioVRDE: drvAudioVRDEGetConf \n")); 911 /* @todo check if szHostVoiceOut = sizeof VRDEVoice works. VRDEVoice doesn't contain HOSTVOICEOUT. */ 912 pAudioConf->szHostVoiceOut = sizeof(VRDEVoice); 913 pAudioConf->szHostVoiceIn = sizeof(VRDEVoice); 914 pAudioConf->MaxHostVoicesOut = 1; 915 pAudioConf->MaxHostVoicesIn = 1; 253 254 return VINF_SUCCESS; 255 } 256 257 static DECLCALLBACK(int) drvAudioVRDEFiniOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMOUT pHstStrmOut) 258 { 259 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3); 260 AssertPtrReturn(pDrv, VERR_INVALID_POINTER); 261 262 return VINF_SUCCESS; 263 } 264 265 static DECLCALLBACK(int) drvAudioVRDEControlOut(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMOUT pHstStrmOut, 266 PDMAUDIOSTREAMCMD enmStreamCmd) 267 { 268 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3); 269 AssertPtrReturn(pDrv, VERR_INVALID_POINTER); 270 271 LogFlowFunc(("enmStreamCmd=%ld\n", enmStreamCmd)); 272 273 return VINF_SUCCESS; 274 } 275 276 static DECLCALLBACK(int) drvAudioVRDEControlIn(PPDMIHOSTAUDIO pInterface, PPDMAUDIOHSTSTRMIN pHstStrmIn2, /** @todo Fix param types! */ 277 PDMAUDIOSTREAMCMD enmStreamCmd) 278 { 279 PDRVAUDIOVRDE pDrv = RT_FROM_MEMBER(pInterface, DRVAUDIOVRDE, IHostAudioR3); 280 AssertPtrReturn(pDrv, VERR_INVALID_POINTER); 281 282 PVRDESTREAMIN pVRDEStrmIn = (PVRDESTREAMIN)pHstStrmIn2; 283 AssertPtrReturn(pVRDEStrmIn, VERR_INVALID_POINTER); 284 285 PPDMAUDIOHSTSTRMIN pHstStrmIn = &pVRDEStrmIn->HstStrmIn; 286 287 LogFlowFunc(("enmStreamCmd=%ld\n", enmStreamCmd)); 288 289 /* Initialize only if not already done. */ 290 if (enmStreamCmd == PDMAUDIOSTREAMCMD_ENABLE) 291 { 292 int rc2 = pDrv->pConsoleVRDPServer->SendAudioInputBegin(NULL, pVRDEStrmIn, audioMixBufSize(&pHstStrmIn->MixBuf), 293 pHstStrmIn->Props.uHz, 294 pHstStrmIn->Props.cChannels, pHstStrmIn->Props.cBits); 295 #ifdef DEBUG 296 if (rc2 == VERR_NOT_SUPPORTED) 297 LogFlowFunc(("No RDP client connected, so no input recording supported\n")); 298 #endif 299 } 300 else if (enmStreamCmd == PDMAUDIOSTREAMCMD_DISABLE) 301 pDrv->pConsoleVRDPServer->SendAudioInputEnd(NULL /* pvUserCtx */); 302 303 return VINF_SUCCESS; 304 } 305 306 static DECLCALLBACK(int) drvAudioVRDEGetConf(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDCFG pCfg) 307 { 308 pCfg->cbStreamOut = sizeof(VRDESTREAMOUT); 309 pCfg->cbStreamIn = sizeof(VRDESTREAMIN); 310 pCfg->cMaxHstStrmsOut = 1; 311 pCfg->cMaxHstStrmsIn = 2; /* Microphone in + line in. */ 312 313 return VINF_SUCCESS; 916 314 } 917 315 … … 922 320 { 923 321 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface); 924 PDRVAUDIOVRDE pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOVRDE); 322 PDRVAUDIOVRDE pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOVRDE); 323 925 324 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase); 926 325 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIHOSTAUDIO, &pThis->IHostAudioR3); … … 928 327 } 929 328 930 931 static DECLCALLBACK(void) drvAudioVRDEDestruct(PPDMDRVINS pDrvIns) 932 { 933 } 934 935 /** 936 * Construct a DirectSound Audio driver instance. 329 AudioVRDE::AudioVRDE(Console *pConsole) 330 : mpDrv(NULL), 331 mParent(pConsole) 332 { 333 } 334 335 AudioVRDE::~AudioVRDE(void) 336 { 337 if (mpDrv) 338 { 339 mpDrv->pAudioVRDE = NULL; 340 mpDrv = NULL; 341 } 342 } 343 344 int AudioVRDE::onVRDEInputIntercept(bool fIntercept) 345 { 346 LogFlowThisFunc(("fIntercept=%RTbool\n", fIntercept)); 347 return VINF_SUCCESS; /* Never veto. */ 348 } 349 350 /** 351 * Marks the beginning of sending captured audio data from a connected 352 * RDP client. 353 * 354 * @return IPRT status code. 355 * @param pvContext The context; in this case a pointer to a 356 * VRDESTREAMIN structure. 357 * @param pVRDEAudioBegin Pointer to a VRDEAUDIOINBEGIN structure. 358 */ 359 int AudioVRDE::onVRDEInputBegin(void *pvContext, PVRDEAUDIOINBEGIN pVRDEAudioBegin) 360 { 361 AssertPtrReturn(pvContext, VERR_INVALID_POINTER); 362 AssertPtrReturn(pVRDEAudioBegin, VERR_INVALID_POINTER); 363 364 PVRDESTREAMIN pVRDEStrmIn = (PVRDESTREAMIN)pvContext; 365 AssertPtrReturn(pVRDEStrmIn, VERR_INVALID_POINTER); 366 367 VRDEAUDIOFORMAT audioFmt = pVRDEAudioBegin->fmt; 368 369 int iSampleHz = VRDE_AUDIO_FMT_SAMPLE_FREQ(audioFmt); 370 int cChannels = VRDE_AUDIO_FMT_CHANNELS(audioFmt); 371 int cBits = VRDE_AUDIO_FMT_BITS_PER_SAMPLE(audioFmt); 372 bool fUnsigned = VRDE_AUDIO_FMT_SIGNED(audioFmt); 373 374 /*pVRDEStrmIn->cbSample = VRDE_AUDIO_FMT_BYTES_PER_SAMPLE(audioFmt); 375 pVRDEStrmIn->uHz = iSampleHz;*/ 376 377 LogFlowFunc(("cbSample=%RU32, iSampleHz=%d, cChannels=%d, cBits=%d, fUnsigned=%RTbool\n", 378 VRDE_AUDIO_FMT_BYTES_PER_SAMPLE(audioFmt), iSampleHz, cChannels, cBits, fUnsigned)); 379 380 return VINF_SUCCESS; 381 } 382 383 int AudioVRDE::onVRDEInputData(void *pvContext, const void *pvData, uint32_t cbData) 384 { 385 PVRDESTREAMIN pVRDEStrmIn = (PVRDESTREAMIN)pvContext; 386 AssertPtrReturn(pVRDEStrmIn, VERR_INVALID_POINTER); 387 388 PPDMAUDIOHSTSTRMIN pHstStrmIn = &pVRDEStrmIn->HstStrmIn; 389 AssertPtrReturn(pHstStrmIn, VERR_INVALID_POINTER); 390 391 /** @todo Use CritSect! */ 392 393 uint32_t cWritten; 394 int rc = audioMixBufWriteCirc(&pHstStrmIn->MixBuf, pvData, cbData, &cWritten); 395 if (RT_SUCCESS(rc)) 396 pVRDEStrmIn->cSamplesCaptured += cWritten; 397 398 LogFlowFunc(("cbData=%RU32, cWritten=%RU32, cSamplesCaptured=%RU32, rc=%Rrc\n", 399 cbData, cWritten, pVRDEStrmIn->cSamplesCaptured, rc)); 400 return rc; 401 } 402 403 int AudioVRDE::onVRDEInputEnd(void *pvContext) 404 { 405 NOREF(pvContext); 406 407 return VINF_SUCCESS; 408 } 409 410 /** 411 * Construct a VRDE audio driver instance. 937 412 * 938 413 * @copydoc FNPDMDRVCONSTRUCT 939 414 */ 940 DECLCALLBACK(int) AudioVRDE::drvAudioVRDEConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags) 415 /* static */ 416 DECLCALLBACK(int) AudioVRDE::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags) 941 417 { 942 418 PDRVAUDIOVRDE pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOVRDE); 943 LogRel(("drvAudioVRDEConstruct\n")); 944 945 /* we save the address of AudioVRDE in Object node in CFGM tree and address of VRDP server in 946 * ObjectVRDPServer node. So presence of both is necessary. 947 */ 948 //if (!CFGMR3AreValuesValid(pCfg, "Object\0") || !CFGMR3AreValuesValid(pCfg, "ObjectVRDPServer\0")) 949 // return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES; 419 LogRel(("Audio: Initializing VRDE driver\n")); 420 LogFlowFunc(("fFlags=0x%x\n", fFlags)); 421 950 422 AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER, 951 423 ("Configuration error: Not possible to attach anything to this driver!\n"), … … 955 427 * Init the static parts. 956 428 */ 957 pThis->pDrvIns = pDrvIns; 958 gpDrvIns = pDrvIns; 429 pThis->pDrvIns = pDrvIns; 959 430 /* IBase */ 960 pDrvIns->IBase.pfnQueryInterface 961 pThis->IHostAudioR3.pfnInitIn 962 pThis->IHostAudioR3.pfnInitOut 963 pThis->IHostAudioR3.pfn DisableEnableOut = drvAudioVRDEDisableEnableOut;964 pThis->IHostAudioR3.pfn DisableEnableIn = drvAudioVRDEDisableEnableIn;965 pThis->IHostAudioR3.pfnFiniIn 966 pThis->IHostAudioR3.pfnFiniOut 967 pThis->IHostAudioR3.pfn PlayIn = drvAudioVRDEPlayIn;968 pThis->IHostAudioR3.pfnPlayOut 969 pThis->IHostAudioR3.pfnGetConf 970 pThis->IHostAudioR3.pfnInit 971 972 /* Get VRDPServer pointer */973 void *pv ;974 int rc = CFGMR3QueryPtr(pCfg, "ObjectVRDPServer", &pv );431 pDrvIns->IBase.pfnQueryInterface = drvAudioVRDEQueryInterface; 432 pThis->IHostAudioR3.pfnInitIn = drvAudioVRDEInitIn; 433 pThis->IHostAudioR3.pfnInitOut = drvAudioVRDEInitOut; 434 pThis->IHostAudioR3.pfnControlOut = drvAudioVRDEControlOut; 435 pThis->IHostAudioR3.pfnControlIn = drvAudioVRDEControlIn; 436 pThis->IHostAudioR3.pfnFiniIn = drvAudioVRDEFiniIn; 437 pThis->IHostAudioR3.pfnFiniOut = drvAudioVRDEFiniOut; 438 pThis->IHostAudioR3.pfnCaptureIn = drvAudioVRDECaptureIn; 439 pThis->IHostAudioR3.pfnPlayOut = drvAudioVRDEPlayOut; 440 pThis->IHostAudioR3.pfnGetConf = drvAudioVRDEGetConf; 441 pThis->IHostAudioR3.pfnInit = drvAudioVRDEInit; 442 443 /* Get VRDPServer pointer. */ 444 void *pvUser; 445 int rc = CFGMR3QueryPtr(pCfg, "ObjectVRDPServer", &pvUser); 975 446 if (RT_FAILURE(rc)) 976 447 { 977 AssertMsgFailed((" DrvAudioVRDE Confguration error: No/bad \"Object\" value!rc=%Rrc\n", rc));448 AssertMsgFailed(("Confguration error: No/bad \"ObjectVRDPServer\" value, rc=%Rrc\n", rc)); 978 449 return rc; 979 450 } 980 /* CFGM tree saves the pointer to ConsoleVRDPServer in the Object node of AudioVRDE */ 981 pThis->pConsoleVRDPServer = (ConsoleVRDPServer *)pv; 982 pv = NULL; 983 984 rc = CFGMR3QueryPtr(pCfg, "Object", &pv); 451 452 /* CFGM tree saves the pointer to ConsoleVRDPServer in the Object node of AudioVRDE. */ 453 pThis->pConsoleVRDPServer = (ConsoleVRDPServer *)pvUser; 454 455 pvUser = NULL; 456 rc = CFGMR3QueryPtr(pCfg, "Object", &pvUser); 985 457 if (RT_FAILURE(rc)) 986 458 { 987 AssertMsgFailed((" DrvAudioVRDE Confguration error: No/bad \"Object\" value!rc=%Rrc\n", rc));459 AssertMsgFailed(("Confguration error: No/bad \"Object\" value, rc=%Rrc\n", rc)); 988 460 return rc; 989 461 } 990 pThis->pAudioVRDE = (AudioVRDE *)pv; 462 463 pThis->pAudioVRDE = (AudioVRDE *)pvUser; 991 464 pThis->pAudioVRDE->mpDrv = pThis; 465 992 466 /* 993 * Get the interface for the above driver (DrvAudio) to make mixer/conversion calls 467 * Get the interface for the above driver (DrvAudio) to make mixer/conversion calls. 994 468 * Described in CFGM tree. 995 469 */ 996 pThis->p UpPort= PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIAUDIOCONNECTOR);997 if (!pThis->p UpPort)998 { 999 AssertMsgFailed(("Configuration error: No Audio Sniffer port interface above!\n"));470 pThis->pDrvAudio = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIAUDIOCONNECTOR); 471 if (!pThis->pDrvAudio) 472 { 473 AssertMsgFailed(("Configuration error: No upper interface specified!\n")); 1000 474 return VERR_PDM_MISSING_INTERFACE_ABOVE; 1001 475 } … … 1004 478 } 1005 479 1006 1007 /** 1008 * Char driver registration record. 1009 */ 1010 const PDMDRVREG g_DrvAudioVRDE = 1011 { 1012 PDM_DRVREG_VERSION, 1013 /* szName */ 480 /* static */ 481 DECLCALLBACK(void) AudioVRDE::drvDestruct(PPDMDRVINS pDrvIns) 482 { 483 LogFlowFuncEnter(); 484 } 485 486 /** 487 * VRDE audio driver registration record. 488 */ 489 const PDMDRVREG AudioVRDE::DrvReg = 490 { 491 PDM_DRVREG_VERSION, 492 /* szName */ 1014 493 "AudioVRDE", 1015 494 /* szRCMod */ … … 1018 497 "", 1019 498 /* pszDescription */ 1020 "Audio VRDE",499 "Audio driver for VRDE backend", 1021 500 /* fFlags */ 1022 501 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT, … … 1028 507 sizeof(DRVAUDIOVRDE), 1029 508 /* pfnConstruct */ 1030 AudioVRDE::drv AudioVRDEConstruct,509 AudioVRDE::drvConstruct, 1031 510 /* pfnDestruct */ 1032 drvAudioVRDEDestruct,511 AudioVRDE::drvDestruct, 1033 512 /* pfnRelocate */ 1034 513 NULL, … … 1055 534 }; 1056 535 1057 1058 -
trunk/src/VBox/Main/src-client/VBoxDriversRegister.cpp
r50686 r53442 71 71 if (RT_FAILURE(rc)) 72 72 return rc; 73 73 74 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 74 rc = pCallbacks->pfnRegister(pCallbacks, & g_DrvAudioVRDE);75 rc = pCallbacks->pfnRegister(pCallbacks, &AudioVRDE::DrvReg); 75 76 #else 76 77 rc = pCallbacks->pfnRegister(pCallbacks, &AudioSniffer::DrvReg); -
trunk/src/VBox/VMM/VMMR3/PDM.cpp
r52670 r53442 5 5 6 6 /* 7 * Copyright (C) 2006-201 3Oracle Corporation7 * Copyright (C) 2006-2014 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 38 38 * will call the entry point 'VBoxDevicesRegister' when loading a device module. 39 39 * The device module will then use the supplied callback table to check the VMM 40 * version and to register its devices. Each device ha vean unique (for the40 * version and to register its devices. Each device has an unique (for the 41 41 * configured VM) name. The name is not only used in PDM but also in CFGM (to 42 42 * organize device and device instance settings) and by anyone who wants to talk … … 52 52 * Some devices are trusted devices, most are not. The trusted devices are an 53 53 * integrated part of the VM and can obtain the VM handle from their device 54 * instance handles, thus enabling them to call any VM api. Untrusted devices54 * instance handles, thus enabling them to call any VM API. Untrusted devices 55 55 * can only use the callbacks provided during device instantiation. 56 56 * … … 64 64 * A device can provide a ring-0 and/or a raw-mode context extension to improve 65 65 * the VM performance by handling exits and traps (respectively) without 66 * requiring context switches (to ring-3). Callbacks for MMIO and I/O ports can67 * need sto be registered specifically for the additional contexts for this to66 * requiring context switches (to ring-3). Callbacks for MMIO and I/O ports 67 * need to be registered specifically for the additional contexts for this to 68 68 * make sense. Also, the device has to be trusted to be loaded into R0/RC 69 69 * because of the extra privilege it entails. Note that raw-mode code and data … … 104 104 * The way USB devices work differs greatly from other devices though since they 105 105 * aren't attaches directly to the PCI/ISA/whatever system buses but via a 106 * USB host control (OHCI, UHCI or EHCI). USB devices handle sUSB requests106 * USB host control (OHCI, UHCI or EHCI). USB devices handle USB requests 107 107 * (URBs) and does not register I/O ports, MMIO ranges or PCI bus 108 108 * devices/functions. … … 120 120 * controller, an ATA controller or a SATA controller. The basics of the DVD/CD 121 121 * drive implementation remains the same - eject, insert, read, seek, and such. 122 * (For the scsi case, you might wannaspeak SCSI directly to, but that can of122 * (For the scsi SCSCI, you might want to speak SCSI directly to, but that can of 123 123 * course be fixed - see SCSI passthru.) So, it 124 124 * makes much sense to have a generic CD/DVD driver which implements this. … … 136 136 * 137 137 * It is possible to configure many levels of drivers inserting filters, loggers, 138 * or whatever you desire into the chain. We're using this for network sniffing 138 * or whatever you desire into the chain. We're using this for network sniffing, 139 139 * for instance. 140 140 * 141 * The drivers are loaded in a similar manner to that of thedevice, namely by141 * The drivers are loaded in a similar manner to that of a device, namely by 142 142 * iterating a keyspace in CFGM, load the modules listed there and call 143 143 * 'VBoxDriversRegister' with a callback table. … … 148 148 * @section sec_pdm_ifs Interfaces 149 149 * 150 * The pluggable drivers and devices expose sone standard interface (callback150 * The pluggable drivers and devices expose one standard interface (callback 151 151 * table) which is used to construct, destruct, attach, detach,( ++,) and query 152 152 * other interfaces. A device will query the interfaces required for it's … … 155 155 * 156 156 * An interface here means a function table contained within the device or 157 * driver instance data. Its method are invoked with the function table pointer157 * driver instance data. Its methods are invoked with the function table pointer 158 158 * as the first argument and they will calculate the address of the device or 159 159 * driver instance data from it. (This is one of the aspects which *might* have
Note:
See TracChangeset
for help on using the changeset viewer.