Changeset 50686 in vbox for trunk/src/VBox/Main
- Timestamp:
- Mar 4, 2014 7:21:18 PM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 92630
- Location:
- trunk/src/VBox/Main
- Files:
-
- 6 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/Makefile.kmk
r50560 r50686 282 282 $(if $(VBOX_WITH_S3),VBOX_WITH_S3,) \ 283 283 $(if $(VBOX_WITH_PCI_PASSTHROUGH),VBOX_WITH_PCI_PASSTHROUGH,) \ 284 $(if $(VBOX_WITH_PDM_AUDIO_DRIVER),VBOX_WITH_PDM_AUDIO_DRIVER,) \ 284 285 $(if $(VBOX_WITH_NAT_SERVICE),VBOX_WITH_NAT_SERVICE,) \ 285 286 $(if $(VBOX_WITH_CROGL),VBOX_WITH_CROGL,) \ … … 615 616 $(if $(VBOX_WITH_EXTPACK),VBOX_WITH_EXTPACK,) \ 616 617 $(if $(VBOX_WITH_PCI_PASSTHROUGH),VBOX_WITH_PCI_PASSTHROUGH,) \ 617 $(if $(VBOX_WITH_VPX),VBOX_WITH_VPX,) 618 $(if $(VBOX_WITH_VPX),VBOX_WITH_VPX,) \ 619 $(if $(VBOX_WITH_PDM_AUDIO_DRIVER),VBOX_WITH_PDM_AUDIO_DRIVER,) 618 620 ifdef VBOX_WITH_CRHGSMI 619 621 VBoxC_DEFS += VBOX_WITH_CRHGSMI … … 693 695 src-client/Nvram.cpp \ 694 696 src-client/AdditionsFacilityImpl.cpp \ 695 src-client/AudioSnifferInterface.cpp \696 697 src-client/BusAssignmentManager.cpp \ 697 698 $(if $(VBOX_WITH_PCI_PASSTHROUGH),src-client/PCIRawDevImpl.cpp,) \ … … 721 722 $(VBOX_AUTOGEN_EVENT_CPP) \ 722 723 $(VBOX_XML_SCHEMADEFS_CPP) 724 ifdef VBOX_WITH_PDM_AUDIO_DRIVER 725 VBoxC_SOURCES += \ 726 src-client/DrvAudioVRDE.cpp 727 else 728 VBoxC_SOURCES += \ 729 src-client/AudioSnifferInterface.cpp 730 endif 723 731 VBoxC_SOURCES.win = \ 724 732 src-client/win/dllmain.cpp \ -
trunk/src/VBox/Main/include/ConsoleImpl.h
r49983 r50686 34 34 class VRDEServerInfo; 35 35 class EmulatedUSB; 36 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 37 class AudioVRDE; 38 #else 36 39 class AudioSniffer; 40 #endif 37 41 class Nvram; 38 42 #ifdef VBOX_WITH_USB_CARDREADER … … 190 194 Display *getDisplay() const { return mDisplay; } 191 195 MachineDebugger *getMachineDebugger() const { return mDebugger; } 196 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 197 AudioVRDE *getAudioVRDE() const { return mAudioVRDE; } 198 #else 192 199 AudioSniffer *getAudioSniffer() const { return mAudioSniffer; } 200 #endif 193 201 194 202 const ComPtr<IMachine> &machine() const { return mMachine; } … … 235 243 int hgcmLoadService(const char *pszServiceLibrary, const char *pszServiceName); 236 244 VMMDev *getVMMDev() { return m_pVMMDev; } 245 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 246 AudioVRDE *getAudioVRDE() { return mAudioVRDE; } 247 #else 237 248 AudioSniffer *getAudioSniffer() { return mAudioSniffer; } 249 #endif 250 238 251 #ifdef VBOX_WITH_EXTPACK 239 252 ExtPackManager *getExtPackManager(); … … 825 838 826 839 VMMDev * m_pVMMDev; 840 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 841 AudioVRDE * const mAudioVRDE; 842 #else 827 843 AudioSniffer * const mAudioSniffer; 844 #endif 828 845 Nvram * const mNvram; 829 846 #ifdef VBOX_WITH_USB_CARDREADER -
trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
r50544 r50686 56 56 #include "RemoteUSBDeviceImpl.h" 57 57 #include "SharedFolderImpl.h" 58 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 59 #include "DrvAudioVRDE.h" 60 #else 58 61 #include "AudioSnifferInterface.h" 62 #endif 59 63 #include "Nvram.h" 60 64 #ifdef VBOX_WITH_USB_CARDREADER … … 404 408 , mpVmm2UserMethods(NULL) 405 409 , m_pVMMDev(NULL) 410 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER 406 411 , mAudioSniffer(NULL) 412 #endif 407 413 , mNvram(NULL) 408 414 #ifdef VBOX_WITH_USB_CARDREADER … … 564 570 // AssertReturn(mVMMDev, E_FAIL); 565 571 572 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 573 unconst(mAudioVRDE) = new AudioVRDE(this); 574 AssertComRCReturnRC(rc); 575 #else 566 576 unconst(mAudioSniffer) = new AudioSniffer(this); 567 577 AssertReturn(mAudioSniffer, E_FAIL); 578 #endif 568 579 569 580 FirmwareType_T enmFirmwareType; … … 683 694 } 684 695 #endif 685 696 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER 686 697 if (mAudioSniffer) 687 698 { … … 689 700 unconst(mAudioSniffer) = NULL; 690 701 } 702 #endif 691 703 692 704 // if the VM had a VMMDev with an HGCM thread, then remove that here … … 1389 1401 if (mcAudioRefs <= 0) 1390 1402 { 1403 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER 1391 1404 if (mAudioSniffer) 1392 1405 { … … 1397 1410 } 1398 1411 } 1412 #endif 1399 1413 } 1400 1414 } … … 1430 1444 AutoCaller autoCaller(this); 1431 1445 AssertComRCReturnVoid(autoCaller.rc()); 1432 1446 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER 1433 1447 LogFlowFunc(("mAudioSniffer %p, u32ClientId %d.\n", 1434 1448 mAudioSniffer, u32ClientId)); 1435 1449 NOREF(u32ClientId); 1450 #endif 1436 1451 1437 1452 ++mcAudioRefs; … … 1439 1454 if (mcAudioRefs == 1) 1440 1455 { 1456 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER 1441 1457 if (mAudioSniffer) 1442 1458 { … … 1447 1463 } 1448 1464 } 1465 #endif 1449 1466 } 1450 1467 -
trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
r50585 r50686 2503 2503 attachStatusDriver(pInst, &mapSharedFolderLed, 0, 0, NULL, NULL, 0); 2504 2504 2505 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER 2505 2506 /* 2506 2507 * Audio Sniffer Device … … 2516 2517 AudioSniffer *pAudioSniffer = mAudioSniffer; 2517 2518 InsertConfigInteger(pCfg, "Object", (uintptr_t)pAudioSniffer); 2519 #endif 2518 2520 2519 2521 /* … … 2569 2571 /* the Audio driver */ 2570 2572 InsertConfigNode(pInst, "LUN#0", &pLunL0); 2571 InsertConfigString(pLunL0, "Driver", "AUDIO"); 2573 InsertConfigString(pLunL0, "Driver", "AUDIO"); 2574 2575 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2576 InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1); 2577 InsertConfigString(pLunL1, "Driver", "PulseAudio"); 2578 #endif 2579 2572 2580 InsertConfigNode(pLunL0, "Config", &pCfg); 2573 2581 … … 2591 2599 case AudioDriverType_DirectSound: 2592 2600 { 2601 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2602 InsertConfigString(pCfg, "AudioDriver", "DSoundAudio"); 2603 #else 2593 2604 InsertConfigString(pCfg, "AudioDriver", "dsound"); 2605 #endif 2594 2606 break; 2595 2607 } … … 2606 2618 case AudioDriverType_ALSA: 2607 2619 { 2620 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2621 InsertConfigString(pCfg, "AudioDriver", "AlsaAudio"); 2622 #else 2608 2623 InsertConfigString(pCfg, "AudioDriver", "alsa"); 2624 #endif 2609 2625 break; 2610 2626 } … … 2613 2629 case AudioDriverType_Pulse: 2614 2630 { 2631 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2632 InsertConfigString(pCfg, "AudioDriver", "PulseAudio"); 2633 #else 2615 2634 InsertConfigString(pCfg, "AudioDriver", "pulse"); 2635 #endif 2616 2636 break; 2617 2637 } … … 2629 2649 case AudioDriverType_Pulse: 2630 2650 { 2651 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2652 InsertConfigString(pCfg, "AudioDriver", "PulseAudio"); 2653 #else 2631 2654 InsertConfigString(pCfg, "AudioDriver", "pulse"); 2655 #endif 2632 2656 break; 2633 2657 } … … 2644 2668 hrc = pMachine->COMGETTER(Name)(bstr.asOutParam()); H(); 2645 2669 InsertConfigString(pCfg, "StreamName", bstr); 2670 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2671 /* the Audio driver */ 2672 InsertConfigNode(pInst, "LUN#1", &pLunL0); 2673 InsertConfigString(pLunL0, "Driver", "AUDIO"); 2674 InsertConfigNode(pLunL0, "AttachedDriver", &pLunL1); 2675 InsertConfigString(pLunL1, "Driver", "AudioVRDE"); 2676 InsertConfigNode(pLunL0, "Config", &pCfg); 2677 InsertConfigString(pCfg, "AudioDriver", "AudioVRDE"); 2678 InsertConfigString(pCfg, "StreamName", bstr); 2679 InsertConfigNode(pLunL1, "Config", &pCfg); 2680 InsertConfigInteger(pCfg, "Object", (uintptr_t)mAudioVRDE); 2681 InsertConfigInteger(pCfg, "ObjectVRDPServer", (uintptr_t)mConsoleVRDPServer); 2682 2683 #endif 2646 2684 } 2647 2685 -
trunk/src/VBox/Main/src-client/ConsoleVRDPServer.cpp
r50319 r50686 21 21 #include "KeyboardImpl.h" 22 22 #include "MouseImpl.h" 23 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 24 #include "DrvAudioVRDE.h" 25 #else 23 26 #include "AudioSnifferInterface.h" 27 #endif 24 28 #ifdef VBOX_WITH_EXTPACK 25 29 # include "ExtPackManagerImpl.h" … … 947 951 ASMAtomicWriteU32(&server->mu32AudioInputClientId, 0); 948 952 953 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 954 server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputIntercept(false); 955 #else 949 956 PPDMIAUDIOSNIFFERPORT pPort = server->mConsole->getAudioSniffer()->getAudioSnifferPort(); 950 957 if (pPort) … … 956 963 AssertFailed(); 957 964 } 965 #endif 958 966 } 959 967 … … 1010 1018 { 1011 1019 Log(("AUDIOIN: connected client %u\n", u32ClientId)); 1012 1020 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1021 server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputIntercept(true); 1022 #else 1013 1023 PPDMIAUDIOSNIFFERPORT pPort = server->mConsole->getAudioSniffer()->getAudioSnifferPort(); 1014 1024 if (pPort) … … 1026 1036 rc = VERR_NOT_SUPPORTED; 1027 1037 } 1038 #endif 1028 1039 } 1029 1040 else … … 1294 1305 { 1295 1306 ConsoleVRDPServer *server = static_cast<ConsoleVRDPServer*>(pvCallback); 1296 1307 #ifndef VBOX_WITH_PDM_AUDIO_DRIVER 1297 1308 PPDMIAUDIOSNIFFERPORT pPort = server->mConsole->getAudioSniffer()->getAudioSnifferPort(); 1309 #endif 1298 1310 1299 1311 switch (u32Event) … … 1302 1314 { 1303 1315 const VRDEAUDIOINBEGIN *pParms = (const VRDEAUDIOINBEGIN *)pvData; 1304 1316 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1317 server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputEventBegin(pvCtx, 1318 VRDE_AUDIO_FMT_SAMPLE_FREQ(pParms->fmt), 1319 VRDE_AUDIO_FMT_CHANNELS(pParms->fmt), 1320 VRDE_AUDIO_FMT_BITS_PER_SAMPLE(pParms->fmt), 1321 VRDE_AUDIO_FMT_SIGNED(pParms->fmt) 1322 ); 1323 #else 1305 1324 pPort->pfnAudioInputEventBegin (pPort, pvCtx, 1306 1325 VRDE_AUDIO_FMT_SAMPLE_FREQ(pParms->fmt), … … 1309 1328 VRDE_AUDIO_FMT_SIGNED(pParms->fmt) 1310 1329 ); 1330 #endif 1311 1331 } break; 1312 1332 1313 1333 case VRDE_AUDIOIN_DATA: 1314 1334 { 1335 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1336 server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputEventData(pvCtx, pvData, cbData); 1337 #else 1315 1338 pPort->pfnAudioInputEventData (pPort, pvCtx, pvData, cbData); 1339 #endif 1316 1340 } break; 1317 1341 1318 1342 case VRDE_AUDIOIN_END: 1319 1343 { 1344 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 1345 server->mConsole->getAudioVRDE()->handleVRDESvrCmdAudioInputEventEnd(pvCtx); 1346 #else 1320 1347 pPort->pfnAudioInputEventEnd (pPort, pvCtx); 1348 #endif 1321 1349 } break; 1322 1350 … … 1336 1364 mcClipboardRefs = 0; 1337 1365 mpfnClipboardCallback = NULL; 1338 1339 1366 #ifdef VBOX_WITH_USB 1340 1367 mUSBBackends.pHead = NULL; … … 3880 3907 audioFormat, 3881 3908 cSamples); 3909 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 3910 //*ppvUserCtx = NULL; 3911 #else 3882 3912 *ppvUserCtx = NULL; /* This is the ConsoleVRDPServer context. 3883 * Currently not used because only one client is allowed to 3884 * do audio input and the client id is saved by the ConsoleVRDPServer. 3885 */ 3913 - * Currently not used because only one client is allowed to 3914 - * do audio input and the client id is saved by the ConsoleVRDPServer. 3915 - */ 3916 #endif 3886 3917 3887 3918 return VINF_SUCCESS; -
trunk/src/VBox/Main/src-client/DrvAudioVRDE.cpp
r50177 r50686 1 1 /* $Id$ */ 2 2 /** @file 3 * VirtualBox Driver Interface to Audio Sniffer device 3 * 4 * VBox Audio VRDE backend 4 5 */ 5 6 6 7 /* 7 * Copyright (C) 2006-201 2Oracle Corporation8 * Copyright (C) 2006-2010 Oracle Corporation 8 9 * 9 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 15 16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. 16 17 */ 17 18 #include "AudioSnifferInterface.h" 18 #include "DrvAudioVRDE.h" 19 19 #include "ConsoleImpl.h" 20 20 #include "ConsoleVRDPServer.h" … … 22 22 #include "Logging.h" 23 23 24 #include <VBox/vmm/pdmaudioifs.h> 24 25 #include <VBox/vmm/pdmdrv.h> 25 26 #include <VBox/RemoteDesktop/VRDE.h> 26 27 #include <VBox/vmm/cfgm.h> 27 28 #include <VBox/err.h> 28 29 // 30 // defines 31 // 32 33 34 // 35 // globals 36 // 37 38 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 }; 231 #endif 39 232 /** 40 * Audio Snifferdriver instance data.233 * Audio VRDE driver instance data. 41 234 * 42 235 * @extends PDMIAUDIOSNIFFERCONNECTOR 43 236 */ 44 typedef struct DRVAUDIO SNIFFER45 { 46 /** Pointer to the Audio Sniffer object.*/47 Audio Sniffer *pAudioSniffer;48 237 typedef struct DRVAUDIOVRDE 238 { 239 /** Pointer to audio VRDE object */ 240 AudioVRDE *pAudioVRDE; 241 PPDMDRVINS pDrvIns; 49 242 /** Pointer to the driver instance structure. */ 50 PPDMDRVINS pDrvIns; 51 52 /** Pointer to the AudioSniffer port interface of the driver/device above us. */ 53 PPDMIAUDIOSNIFFERPORT pUpPort; 54 /** Our VMM device connector interface. */ 55 PDMIAUDIOSNIFFERCONNECTOR Connector; 56 57 } DRVAUDIOSNIFFER, *PDRVAUDIOSNIFFER; 58 59 /** Converts PDMIAUDIOSNIFFERCONNECTOR pointer to a DRVAUDIOSNIFFER pointer. */ 60 #define PDMIAUDIOSNIFFERCONNECTOR_2_MAINAUDIOSNIFFER(pInterface) RT_FROM_MEMBER(pInterface, DRVAUDIOSNIFFER, Connector) 61 62 63 // 64 // constructor / destructor 65 // 66 AudioSniffer::AudioSniffer(Console *console) 243 PDMIHOSTAUDIO IHostAudioR3; 244 ConsoleVRDPServer *pConsoleVRDPServer; 245 /** Pointer to the DrvAudio port interface that is above it. */ 246 PPDMIAUDIOCONNECTOR pUpPort; 247 } 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; 281 uint64_t old_ticks; 282 uint64_t cSamplesSentPerSec; 283 }; 284 typedef VRDEVoiceOut * PVRDEVoiceOut; 285 286 /** Makes a PDRVBLOCK out of a PPDMIBLOCK. */ 287 #define PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface) ( (PDRVAUDIOVRDE)((uintptr_t)pInterface - RT_OFFSETOF(DRVAUDIOVRDE, IHostAudioR3)) ) 288 289 AudioVRDE::AudioVRDE(Console *console) 67 290 : mpDrv(NULL), 68 291 mParent(console) … … 70 293 } 71 294 72 Audio Sniffer::~AudioSniffer()295 AudioVRDE::~AudioVRDE() 73 296 { 74 297 if (mpDrv) 75 298 { 76 mpDrv->pAudio Sniffer= NULL;299 mpDrv->pAudioVRDE = NULL; 77 300 mpDrv = NULL; 78 301 } 79 302 } 80 303 81 PPDMIAUDIO SNIFFERPORT AudioSniffer::getAudioSnifferPort()304 PPDMIAUDIOCONNECTOR AudioVRDE::getDrvAudioPort() 82 305 { 83 306 Assert(mpDrv); … … 85 308 } 86 309 87 88 89 // 90 // public methods 91 // 92 93 DECLCALLBACK(void) iface_AudioSamplesOut (PPDMIAUDIOSNIFFERCONNECTOR pInterface, void *pvSamples, uint32_t cSamples, 94 int samplesPerSec, int nChannels, int bitsPerSample, bool fUnsigned) 95 { 96 PDRVAUDIOSNIFFER pDrv = PDMIAUDIOSNIFFERCONNECTOR_2_MAINAUDIOSNIFFER(pInterface); 97 310 void AudioVRDE::handleVRDESvrCmdAudioInputIntercept(bool fIntercept) 311 { 312 LogFlow(("AudioVRDE: handleVRDPCmdInputIntercept\n")); 313 } 314 315 static DECLCALLBACK(void *) drvAudioVRDEInit(PPDMIHOSTAUDIO pInterface) 316 { 317 LogFlow(("drvAudioVRDEInit \n")); 318 return 1; 319 } 320 321 static void drvAudioVRDEPcmInitInfo(PDMPCMPROPERTIES * pProps, audsettings_t *as) 322 { 323 int bits = 8, sign = 0, shift = 0; 324 LogFlow(("AudioVRDE: PcmInitInfo \n")); 325 326 switch (as->fmt) { 327 case AUD_FMT_S8: 328 sign = 1; 329 case AUD_FMT_U8: 330 break; 331 332 case AUD_FMT_S16: 333 sign = 1; 334 case AUD_FMT_U16: 335 bits = 16; 336 shift = 1; 337 break; 338 339 case AUD_FMT_S32: 340 sign = 1; 341 case AUD_FMT_U32: 342 bits = 32; 343 shift = 2; 344 break; 345 } 346 347 pProps->uFrequency = as->freq; 348 pProps->cBits = bits; 349 pProps->fSigned = sign; 350 pProps->cChannels = as->nchannels; 351 pProps->cShift = (as->nchannels == 2) + shift; 352 pProps->fAlign = (1 << pProps->cShift) - 1; 353 pProps->cbPerSec = pProps->uFrequency << pProps->cShift; 354 pProps->fSwapEndian = (as->endianness != AUDIO_HOST_ENDIANNESS); 355 } 356 357 /* 358 * Hard voice (playback) 359 */ 360 static int audio_pcm_hw_find_min_out (PPDMHOSTVOICEOUT hw, int *nb_livep) 361 { 362 PPDMGSTVOICEOUT sw; 363 PPDMGSTVOICEOUT pIter; 364 int m = INT_MAX; 365 int nb_live = 0; 366 LogFlow(("Hard Voice Playback \n")); 367 368 RTListForEach(&hw->HeadGstVoiceOut, pIter, PDMGSTVOICEOUT, ListGstVoiceOut) 369 { 370 sw = pIter; 371 if (sw->State.fActive || !sw->State.fEmpty) 372 { 373 m = audio_MIN (m, sw->cSamplesMixed); 374 nb_live += 1; 375 } 376 } 377 378 *nb_livep = nb_live; 379 return m; 380 } 381 382 int audio_pcm_hw_get_live_out2 (PPDMHOSTVOICEOUT hw, int *nb_live) 383 { 384 int smin; 385 386 smin = audio_pcm_hw_find_min_out (hw, nb_live); 387 388 if (!*nb_live) { 389 return 0; 390 } 391 else 392 { 393 int live = smin; 394 395 if (live < 0 || live > hw->cSamples) 396 { 397 LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples)); 398 return 0; 399 } 400 return live; 401 } 402 } 403 404 405 int audio_pcm_hw_get_live_out (PPDMHOSTVOICEOUT hw) 406 { 407 int nb_live; 408 int live; 409 410 live = audio_pcm_hw_get_live_out2 (hw, &nb_live); 411 if (live < 0 || live > hw->cSamples) 412 { 413 LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples)); 414 return 0; 415 } 416 return live; 417 } 418 419 /* 420 * Hard voice (capture) 421 */ 422 static int audio_pcm_hw_find_min_in (PPDMHOSTVOICEIN hw) 423 { 424 PPDMGSTVOICEIN pIter; 425 int m = hw->cSamplesCaptured; 426 427 RTListForEach(&hw->HeadGstVoiceIn, pIter, PDMGSTVOICEIN, ListGstVoiceIn) 428 { 429 if (pIter->State.fActive) 430 { 431 m = audio_MIN (m, pIter->cHostSamplesAcquired); 432 } 433 } 434 return m; 435 } 436 437 int audio_pcm_hw_get_live_in (PPDMHOSTVOICEIN hw) 438 { 439 int live = hw->cSamplesCaptured - audio_pcm_hw_find_min_in (hw); 440 if (live < 0 || live > hw->cSamples) 441 { 442 LogFlow(("Error: live=%d hw->samples=%d\n", live, hw->cSamples)); 443 return 0; 444 } 445 return live; 446 } 447 448 static inline void *advance (void *p, int incr) 449 { 450 uint8_t *d = (uint8_t*)p; 451 return (d + incr); 452 } 453 454 uint64_t audio_get_ticks_per_sec (void) 455 { 456 return PDMDrvHlpTMGetVirtualFreq (gpDrvIns); 457 } 458 459 uint64_t audio_get_clock (void) 460 { 461 return PDMDrvHlpTMGetVirtualTime (gpDrvIns); 462 } 463 464 void VRDEReallocSampleBuf(PVRDEVoice pVRDEVoice, uint32_t cSamples) 465 { 466 uint32_t cbBuffer = cSamples * sizeof(PDMHOSTSTEREOSAMPLE); 467 if (cbBuffer > pVRDEVoice->cbSamplesBufferAllocated) 468 { 469 if (pVRDEVoice->pvSamplesBuffer) 470 { 471 RTMemFree(pVRDEVoice->pvSamplesBuffer); 472 pVRDEVoice->pvSamplesBuffer = NULL; 473 } 474 pVRDEVoice->pvSamplesBuffer = RTMemAlloc(cbBuffer); 475 if (pVRDEVoice->pvSamplesBuffer) 476 pVRDEVoice->cbSamplesBufferAllocated = cbBuffer; 477 else 478 pVRDEVoice->cbSamplesBufferAllocated = 0; 479 } 480 481 } 482 483 void VRDEReallocRateAdjSampleBuf(PVRDEVoice pVRDEVoice, uint32_t cSamples) 484 { 485 uint32_t cbBuffer = cSamples * sizeof(PDMHOSTSTEREOSAMPLE); 486 if (cbBuffer > pVRDEVoice->cbRateBufferAllocated) 487 { 488 RTMemFree(pVRDEVoice->pvRateBuffer); 489 pVRDEVoice->pvRateBuffer = RTMemAlloc(cbBuffer); 490 if (pVRDEVoice->pvRateBuffer) 491 pVRDEVoice->cbRateBufferAllocated = cbBuffer; 492 else 493 pVRDEVoice->cbRateBufferAllocated = 0; 494 } 495 } 496 497 /******************************************************************************* 498 * 499 * AudioVRDE input section 500 * 501 ******************************************************************************/ 502 503 /* 504 * Callback to feed audio input buffer. Samples format is be the same as 505 * in the voice. The caller prepares st_sample_t. 506 * 507 * @param cbSamples Size of pvSamples array in bytes. 508 * @param pvSamples Points to an array of samples. 509 * 510 * @return IPRT status code. 511 */ 512 static int fltRecordingCallback(PVRDEVoice pVRDEVoice, uint32_t cbSamples, const void *pvSamples) 513 { 514 int rc = VINF_SUCCESS; 515 uint32_t csAvail = 0; 516 uint32_t csToWrite = 0; 517 uint32_t cbToWrite = 0; 518 uint32_t csWritten = 0; 519 char *pcDst = NULL; 520 521 LogFlow(("audio-filter: fltRecordingCallback\n")); 522 523 Assert((cbSamples % sizeof(PDMHOSTSTEREOSAMPLE)) == 0); 524 525 if (!pVRDEVoice->fIsInit) 526 return VINF_SUCCESS; 527 528 /* If nothing is pending return immediately. */ 529 if (cbSamples == 0) 530 return VINF_SUCCESS; 531 532 /* How much space is free in the ring buffer? */ 533 PPDMHOSTSTEREOSAMPLE psSrc; 534 csAvail = IORingBufferFree(pVRDEVoice->pRecordedVoiceBuf) / sizeof(PDMHOSTSTEREOSAMPLE); /* bytes -> samples */ 535 536 /* How much space is used in the audio buffer. Use the smaller size of the too. */ 537 csAvail = RT_MIN(csAvail, cbSamples / sizeof(PDMHOSTSTEREOSAMPLE)); 538 539 /* Iterate as long as data is available */ 540 while(csWritten < csAvail) 541 { 542 /* How much is left? */ 543 csToWrite = csAvail - csWritten; 544 cbToWrite = csToWrite * sizeof(PDMHOSTSTEREOSAMPLE); 545 546 /* Try to acquire the necessary space from the ring buffer. */ 547 IORingBufferAquireWriteBlock(pVRDEVoice->pRecordedVoiceBuf, cbToWrite, &pcDst, &cbToWrite); 548 549 /* How much do we get? */ 550 csToWrite = cbToWrite / sizeof(PDMHOSTSTEREOSAMPLE); 551 552 /* Break if nothing is free anymore. */ 553 if (RT_UNLIKELY(csToWrite == 0)) 554 break; 555 556 /* Copy the data from the audio buffer to the ring buffer in PVRDEVoice. */ 557 memcpy(pcDst, (uint8_t *)pvSamples + (csWritten * sizeof(PDMHOSTSTEREOSAMPLE)), cbToWrite); 558 559 /* Release the ring buffer, so the main thread could start reading this data. */ 560 IORingBufferReleaseWriteBlock(pVRDEVoice->pRecordedVoiceBuf, cbToWrite); 561 562 csWritten += csToWrite; 563 } 564 565 LogFlow(("AudioVRDE: [Input] Finished writing buffer with %RU32 samples (%RU32 bytes)\n", 566 csWritten, csWritten * sizeof(PDMHOSTSTEREOSAMPLE))); 567 568 return rc; 569 } 570 571 572 STDMETHODIMP AudioVRDE::handleVRDESvrCmdAudioInputEventBegin(void *pvContext, int iSampleHz, int cChannels, int cBits, bool fUnsigned) 573 { 574 int bitIdx; 575 PVRDEVoice pVRDEVoice = (PVRDEVoice)pvContext; 576 LogFlow(("AudioVRDE: handleVRDPCmdInputEventBegin\n")); 577 /* Prepare a format convertion for the actually used format. */ 578 pVRDEVoice->cBytesPerFrame = ((cBits + 7) / 8) * cChannels; 579 if (cBits == 16) 580 { 581 bitIdx = 1; 582 } 583 else if (cBits == 32) 584 { 585 bitIdx = 2; 586 } 587 else 588 { 589 bitIdx = 0; 590 } 591 //PPDMIAUDIOCONNECTOR pPort = server->mConsole->getAudioVRDE()->getDrvAudioPort(); 592 /* Call DrvAudio interface to get the t_sample type conversion function */ 593 pVRDEVoice->convAudioDevFmtToStSampl = mpDrv->pUpPort->pfnConvDevFmtToStSample(mpDrv->pUpPort, 594 (cChannels == 2) ? 1 : 0, 595 !fUnsigned, 0, bitIdx 596 ); 597 if (pVRDEVoice->convAudioDevFmtToStSampl) 598 { 599 LogFlow(("AudioVRDE: Failed to get the conversion function \n")); 600 } 601 LogFlow(("AudioVRDE: Required freq as requested by VRDP Server = %d\n", iSampleHz)); 602 //if (iSampleHz && iSampleHz != pVRDEVoice->pHostVoiceIn.Props.uFrequency) 603 { 604 /* @todo if the above condition is false then pVRDEVoice->uFrequency will remain 0 */ 605 pVRDEVoice->rate = mpDrv->pUpPort->pfnPrepareAudioConversion(mpDrv->pUpPort, iSampleHz, 606 pVRDEVoice->pHostVoiceIn.Props.uFrequency); 607 pVRDEVoice->uFrequency = iSampleHz; 608 LogFlow(("AudioVRDE: pVRDEVoice assigned requested freq =%d\n", pVRDEVoice->uFrequency)); 609 } 610 return VINF_SUCCESS; 611 } 612 613 /* 614 * pvContext: pointer to VRDP voice returned by the VRDP server. The is same pointer that we initialized in 615 * drvAudioVRDEDisableEnableIn VOICE_ENABLE case. 616 */ 617 void AudioVRDE::handleVRDESvrCmdAudioInputEventData(void *pvContext, const void *pvData, uint32_t cbData) 618 { 619 PVRDEVoice pVRDEVoice = (PVRDEVoice)pvContext; 620 PPDMHOSTSTEREOSAMPLE pHostStereoSampleBuf; /* target sample buffer */ 621 PPDMHOSTSTEREOSAMPLE pConvertedSampleBuf; /* samples adjusted for rate */ 622 uint32_t cSamples = cbData / pVRDEVoice->cBytesPerFrame; /* Count of samples */ 623 void * pTmpSampleBuf = NULL; 624 uint32_t cConvertedSamples; /* samples adjusted for rate */ 625 uint32_t cbSamples; /* count of bytes occupied by samples */ 626 uint32_t rc; 627 LogFlow(("AudioVRDE: handleVRDPCmdInputEventData cbData = %d, bytesperfram=%d\n", 628 cbData, pVRDEVoice->cBytesPerFrame)); 629 630 VRDEReallocSampleBuf(pVRDEVoice, cSamples); 631 pHostStereoSampleBuf = (PPDMHOSTSTEREOSAMPLE)pVRDEVoice->pvSamplesBuffer; 632 pVRDEVoice->convAudioDevFmtToStSampl(pHostStereoSampleBuf, pvData, cSamples, &nominal_volume); 633 634 /* count of rate adjusted samples */ 635 pVRDEVoice->uFrequency = 22100; /* @todo handle this. How pVRDEVoice will get proper value */ 636 cConvertedSamples = (cSamples * pVRDEVoice->pHostVoiceIn.Props.uFrequency) / pVRDEVoice->uFrequency; 637 VRDEReallocRateAdjSampleBuf(pVRDEVoice, cConvertedSamples); 638 639 pConvertedSampleBuf = (PPDMHOSTSTEREOSAMPLE)pVRDEVoice->pvRateBuffer; 640 641 if (pConvertedSampleBuf) 642 { 643 uint32_t cSampleSrc = cSamples; 644 uint32_t cSampleDst = cConvertedSamples; 645 mpDrv->pUpPort->pfnDoRateConversion(mpDrv->pUpPort, pVRDEVoice->rate, pHostStereoSampleBuf, 646 pConvertedSampleBuf, &cSampleSrc, &cConvertedSamples); 647 pTmpSampleBuf = pConvertedSampleBuf; 648 cbSamples = cConvertedSamples * sizeof(PDMHOSTSTEREOSAMPLE); 649 } 650 651 if (cbSamples) 652 { 653 rc = fltRecordingCallback(pVRDEVoice, cbSamples, pTmpSampleBuf); 654 } 655 } 656 657 /* 658 * pvContext: pointer to VRDP voice returned by the VRDP server. The is same pointer that we initialized in 659 * drvAudioVRDEDisableEnableIn VOICE_ENABLE case. 660 */ 661 void AudioVRDE::handleVRDESvrCmdAudioInputEventEnd(void *pvContext) 662 { 663 PVRDEVoice pVRDEVoice = (PVRDEVoice)pvContext; 664 LogFlow(("AudioVRDE: handleVRDPCmdInputEventEnd\n")); 665 /* The caller will not use this context anymore. */ 666 if (pVRDEVoice->rate) 667 { 668 mpDrv->pUpPort->pfnEndAudioConversion(mpDrv->pUpPort, pVRDEVoice->rate); 669 } 670 671 if (pVRDEVoice->pvSamplesBuffer) 672 { 673 RTMemFree(pVRDEVoice->pvSamplesBuffer); 674 pVRDEVoice->pvSamplesBuffer = NULL; 675 } 676 if(pVRDEVoice->pvRateBuffer) 677 { 678 RTMemFree(pVRDEVoice->pvRateBuffer); 679 pVRDEVoice->pvRateBuffer = NULL; 680 } 681 } 682 683 static DECLCALLBACK(int) drvAudioVRDEInitOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT pHostVoiceOut, audsettings_t *as) 684 { 685 PDRVAUDIOVRDE pDrv = PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface); 686 PVRDEVoiceOut pVRDEVoiceOut = (PVRDEVoiceOut)pHostVoiceOut; 687 LogFlow(("DrvAudioVRDEInitOut: audio input begin cShift=%d\n", pHostVoiceOut->Props.cShift)); 688 pHostVoiceOut->cSamples = 6174; 689 drvAudioVRDEPcmInitInfo(&pVRDEVoiceOut->pHostVoiceOut.Props, as); 690 return VINF_SUCCESS; 691 692 } 693 694 static DECLCALLBACK(int) drvAudioVRDEInitIn (PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN pHostVoiceIn, audsettings_t *as) 695 { 696 LogFlow(("DrvAudioVRDE: drvAudioVRDEInitIn \n")); 697 PDRVAUDIOVRDE pDrv = PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface); 698 PVRDEVoice pVRDEVoice = (PVRDEVoice)pHostVoiceIn; 699 pHostVoiceIn->cSamples = 6174; 700 drvAudioVRDEPcmInitInfo(&pVRDEVoice->pHostVoiceIn.Props, as); 701 return VINF_SUCCESS; 702 } 703 704 static DECLCALLBACK(int) drvAudioVRDEPlayIn(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN pHostVoiceIn) 705 { 706 uint32_t cbAvlblRingBuffer = 0; 707 uint32_t cSamplesRingBuffer = 0; 708 uint32_t cSamplesToRead = 0; 709 uint32_t cSamplesRead = 0; 710 uint32_t cbToRead; 711 char *pcSrc; 712 PDMHOSTSTEREOSAMPLE * psDst; 713 //@todo take care of the size of the buffer allocated to pHostVoiceIn 714 PVRDEVoice pVRDEVoice = (PVRDEVoice)pHostVoiceIn; 715 LogFlow(("DrvAudioVRDE: drvAudioVRDEPlayIn \n")); 716 717 /* use this from DrvHostCoreAudio.c */ 718 if (ASMAtomicReadU32(&pVRDEVoice->status) != CA_STATUS_INIT) 719 { 720 LogFlow(("AudioVRDE: VRDE voice not initialized \n")); 721 return 0; 722 } 723 724 /* how much space is used in the ring buffer in pRecordedVocieBuf with pAudioVRDE . Bytes-> samples*/ 725 cSamplesRingBuffer = IORingBufferUsed(pVRDEVoice->pRecordedVoiceBuf) / sizeof(PDMHOSTSTEREOSAMPLE); 726 727 /* How much space is available in the mix buffer. Use the smaller size of the too. */ 728 cSamplesRingBuffer = RT_MIN(cSamplesRingBuffer, (uint32_t)(pVRDEVoice->pHostVoiceIn.cSamples - 729 audio_pcm_hw_get_live_in (&pVRDEVoice->pHostVoiceIn))); 730 LogFlow(("AudioVRDE: [Input] Start reading buffer with %d samples (%d bytes)\n", cSamplesRingBuffer, 731 cSamplesRingBuffer * sizeof(PDMHOSTSTEREOSAMPLE))); 732 733 /* Iterate as long as data is available */ 734 while (cSamplesRead < cSamplesRingBuffer) 735 { 736 /* How much is left? Split request at the end of our samples buffer. */ 737 cSamplesToRead = RT_MIN(cSamplesRingBuffer - cSamplesRead, 738 (uint32_t)(pVRDEVoice->pHostVoiceIn.cSamples - pVRDEVoice->pHostVoiceIn.offWrite)); 739 cbToRead = cSamplesToRead * sizeof(PDMHOSTSTEREOSAMPLE); 740 LogFlow(("AudioVRDE: [Input] Try reading %RU32 samples (%RU32 bytes)\n", cSamplesToRead, cbToRead)); 741 742 /* Try to acquire the necessary block from the ring buffer. Remeber in fltRecrodCallback we 743 * we are filling this buffer with the audio data available from VRDP. Here we are reading it 744 */ 745 /*todo do I need to introduce a thread to fill the buffer in fltRecordcallback. So that 746 * filling is in separate thread and the reading of that buffer is in separate thread 747 */ 748 IORingBufferAquireReadBlock(pVRDEVoice->pRecordedVoiceBuf, cbToRead, &pcSrc, &cbToRead); 749 750 /* How much to we get? */ 751 cSamplesToRead = cbToRead / sizeof(PDMHOSTSTEREOSAMPLE); 752 LogFlow(("AuderVRDE: [Input] There are %d samples (%d bytes) available\n", cSamplesToRead, cbToRead)); 753 754 /* Break if nothing is used anymore. */ 755 if (cSamplesToRead == 0) 756 { 757 LogFlow(("AudioVRDE: Nothing to read \n")); 758 break; 759 } 760 761 /* Copy the data from our ring buffer to the mix buffer. */ 762 psDst = pVRDEVoice->pHostVoiceIn.pConversionBuf + pVRDEVoice->pHostVoiceIn.offWrite; 763 memcpy(psDst, pcSrc, cbToRead); 764 765 /* Release the read buffer, so it could be used for new data. */ 766 IORingBufferReleaseReadBlock(pVRDEVoice->pRecordedVoiceBuf, cbToRead); 767 768 pVRDEVoice->pHostVoiceIn.offWrite = (pVRDEVoice->pHostVoiceIn.offWrite + cSamplesToRead) 769 % pVRDEVoice->pHostVoiceIn.cSamples; 770 771 /* How much have we reads so far. */ 772 cSamplesRead += cSamplesToRead; 773 } 774 LogFlow(("AudioVRDE: [Input] Finished reading buffer with %d samples (%d bytes)\n", 775 cSamplesRead, cSamplesRead * sizeof(PDMHOSTSTEREOSAMPLE))); 776 777 return cSamplesRead; 778 } 779 780 static DECLCALLBACK(int) drvAudioVRDEPlayOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT pHostVoiceOut) 781 { 782 PDRVAUDIOVRDE pDrv = PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface); 783 PVRDEVoiceOut pVRDEVoiceOut = (PVRDEVoiceOut)pHostVoiceOut; 784 int live; 785 uint8_t *pu8Dst; 786 int cSamplesPlayed; 787 int cSamplesToSend = 0; 98 788 /* 99 789 * Just call the VRDP server with the data. 100 790 */ 101 VRDEAUDIOFORMAT format = VRDE_AUDIO_FMT_MAKE(samplesPerSec, nChannels, bitsPerSample, !fUnsigned); 102 pDrv->pAudioSniffer->getParent()->consoleVRDPServer()->SendAudioSamples(pvSamples, cSamples, format); 103 } 104 105 DECLCALLBACK(void) iface_AudioVolumeOut (PPDMIAUDIOSNIFFERCONNECTOR pInterface, uint16_t left, uint16_t right) 106 { 107 PDRVAUDIOSNIFFER pDrv = PDMIAUDIOSNIFFERCONNECTOR_2_MAINAUDIOSNIFFER(pInterface); 108 109 /* 110 * Just call the VRDP server with the data. 791 live = audio_pcm_hw_get_live_out (pHostVoiceOut); 792 uint64_t now = audio_get_clock(); 793 uint64_t ticks = now - pVRDEVoiceOut->old_ticks; 794 uint64_t ticks_per_second = audio_get_ticks_per_sec(); 795 cSamplesPlayed = (int)((2 * ticks * pHostVoiceOut->Props.uFrequency + ticks_per_second) / ticks_per_second / 2); 796 if (cSamplesPlayed < 0) 797 cSamplesPlayed = live; 798 pHostVoiceOut->Props.cBits = 128; 799 VRDEAUDIOFORMAT format = VRDE_AUDIO_FMT_MAKE(pHostVoiceOut->Props.uFrequency, 800 pHostVoiceOut->Props.cChannels, 801 pHostVoiceOut->Props.cBits, /* bits per sample */ 802 !pHostVoiceOut->Props.fSigned); 803 LogFlow(("DrvAudioVRDE: send audio sample freq=%d, chan=%d, cBits = %d, fsigned = %d, cSamples=%d format=%d \n", 804 pHostVoiceOut->Props.uFrequency, pHostVoiceOut->Props.cChannels, 805 pHostVoiceOut->Props.cBits, pHostVoiceOut->Props.fSigned, 806 pHostVoiceOut->cSamples, format) 807 ); 808 pVRDEVoiceOut->old_ticks = now; 809 cSamplesToSend = RT_MIN(live, cSamplesPlayed); 810 if (pHostVoiceOut->offRead + cSamplesToSend > pHostVoiceOut->cSamples) 811 { 812 /* send the samples till the end of pHostStereoSampleBuf */ 813 pDrv->pConsoleVRDPServer->SendAudioSamples(&pHostVoiceOut->pHostSterioSampleBuf[pHostVoiceOut->offRead], 814 (pHostVoiceOut->cSamples - pHostVoiceOut->offRead), format); 815 /*pHostStereoSampleBuff already has the samples which exceeded its space. They have overwriten the old 816 * played sampled starting from offset 0. So based on the number of samples that we had to play, 817 * read the number of samples from offset 0 . 818 */ 819 pDrv->pConsoleVRDPServer->SendAudioSamples(&pHostVoiceOut->pHostSterioSampleBuf[0], 820 (cSamplesToSend - (pHostVoiceOut->cSamples - 821 pHostVoiceOut->offRead)), 822 format); 823 } 824 else 825 { 826 pDrv->pConsoleVRDPServer->SendAudioSamples(&pHostVoiceOut->pHostSterioSampleBuf[pHostVoiceOut->offRead], 827 cSamplesToSend, format); 828 } 829 pHostVoiceOut->offRead = (pHostVoiceOut->offRead + cSamplesToSend) % pHostVoiceOut->cSamples; 830 return cSamplesToSend; 831 } 832 833 static DECLCALLBACK(void) drvAudioVRDEFiniIn(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN hw) 834 { 835 PDRVAUDIOVRDE pDrv = PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface); 836 LogFlow(("DrvAudioVRDE: drvAudioVRDEFiniIn \n")); 837 pDrv->pConsoleVRDPServer->SendAudioInputEnd(NULL); 838 } 839 840 static DECLCALLBACK(void) drvAudioVRDEFiniOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT pHostVoiceOut) 841 { 842 PDRVAUDIOVRDE pDrv = PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface); 843 LogFlow(("DrvAudioVRDE: audio input end\n")); 844 } 845 846 static DECLCALLBACK(int) drvAudioVRDEDisableEnableOut(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEOUT hw, int cmd) 847 { 848 LogFlow(("DrvAudioVRDE: drvAudioVRDEDisableEnableOut \n")); 849 return VINF_SUCCESS; 850 } 851 852 static DECLCALLBACK(int) drvAudioVRDEDisableEnableIn(PPDMIHOSTAUDIO pInterface, PPDMHOSTVOICEIN pHostVoiceIn, int cmd) 853 { 854 PDRVAUDIOVRDE pDrv = PDMIHOSTAUDIO_2_DRVAUDIOVRDE(pInterface); 855 856 /* Initialize VRDEVoice and return to VRDP server which returns this struct back to us 857 * in the form void * pvContext 111 858 */ 112 pDrv->pAudioSniffer->getParent()->consoleVRDPServer()->SendAudioVolume(left, right); 113 } 114 115 DECLCALLBACK(int) iface_AudioInputBegin (PPDMIAUDIOSNIFFERCONNECTOR pInterface, 116 void **ppvUserCtx, 117 void *pvContext, 118 uint32_t cSamples, 119 uint32_t iSampleHz, 120 uint32_t cChannels, 121 uint32_t cBits) 122 { 123 PDRVAUDIOSNIFFER pDrv = PDMIAUDIOSNIFFERCONNECTOR_2_MAINAUDIOSNIFFER(pInterface); 124 125 return pDrv->pAudioSniffer->getParent()->consoleVRDPServer()->SendAudioInputBegin(ppvUserCtx, 126 pvContext, 127 cSamples, 128 iSampleHz, 129 cChannels, 130 cBits); 131 } 132 133 DECLCALLBACK(void) iface_AudioInputEnd (PPDMIAUDIOSNIFFERCONNECTOR pInterface, 134 void *pvUserCtx) 135 { 136 PDRVAUDIOSNIFFER pDrv = PDMIAUDIOSNIFFERCONNECTOR_2_MAINAUDIOSNIFFER(pInterface); 137 138 pDrv->pAudioSniffer->getParent()->consoleVRDPServer()->SendAudioInputEnd(pvUserCtx); 139 } 140 859 PVRDEVoice pVRDEVoice = (PVRDEVoice)pHostVoiceIn; 860 LogFlow(("DrvAudioVRDE: drvAudioVRDEDisableEnableIn \n")); 861 /* initialize only if not already done */ 862 if (cmd == VOICE_ENABLE) 863 { 864 //@todo if (!pVRDEVoice->fIsInit) 865 // IORingBufferReset(pVRDEVoice->pRecordedVoiceBuf); 866 LogFlow(("DrvAudioVRDE: Intializing the VRDE params and buffer \n")); 867 pVRDEVoice->fIsInit = 1; 868 pVRDEVoice->pHostVoiceIn = *pHostVoiceIn; 869 pVRDEVoice->cBytesPerFrame =1 ; 870 pVRDEVoice->uFrequency = 0; 871 pVRDEVoice->rate = NULL; 872 pVRDEVoice->cbSamplesBufferAllocated = 0; 873 pVRDEVoice->pvRateBuffer = NULL; 874 pVRDEVoice->cbRateBufferAllocated = 0; 875 876 pVRDEVoice->pHostVoiceIn.cSamples = 2048; 877 /* Initialize the hardware info section with the audio settings */ 878 879 ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_IN_INIT); 880 881 /* Create the internal ring buffer. */ 882 IORingBufferCreate(&pVRDEVoice->pRecordedVoiceBuf, 883 pVRDEVoice->pHostVoiceIn.cSamples * sizeof(PDMHOSTSTEREOSAMPLE)); 884 885 if (!RT_VALID_PTR(pVRDEVoice->pRecordedVoiceBuf)) 886 { 887 LogRel(("AudioVRDE: [Input] Failed to create internal ring buffer\n")); 888 return VERR_NO_MEMORY; 889 } 890 891 ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_INIT); 892 return pDrv->pConsoleVRDPServer->SendAudioInputBegin(NULL, pVRDEVoice, pHostVoiceIn->cSamples, 893 pHostVoiceIn->Props.uFrequency, 894 pHostVoiceIn->Props.cChannels, pHostVoiceIn->Props.cBits); 895 } 896 else if (cmd == VOICE_DISABLE) 897 { 898 LogFlow(("DrvAudioVRDE: Cmd to disable VRDE \n")); 899 pVRDEVoice->fIsInit = 0; 900 ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_IN_UNINIT); 901 IORingBufferDestroy(pVRDEVoice->pRecordedVoiceBuf); 902 pVRDEVoice->pRecordedVoiceBuf = NULL; 903 ASMAtomicWriteU32(&pVRDEVoice->status, CA_STATUS_UNINIT); 904 pDrv->pConsoleVRDPServer->SendAudioInputEnd(NULL); 905 } 906 return VINF_SUCCESS; 907 } 908 909 static DECLCALLBACK(void) drvAudioVRDEGetConf(PPDMIBASE pInterface, PPDMAUDIOCONF pAudioConf) 910 { 911 LogFlow(("drvAudioVRDE: drvAudioVRDEGetConf \n")); 912 /* @todo check if szHostVoiceOut = sizeof VRDEVoice works. VRDEVoice doesn't contain HOSTVOICEOUT. */ 913 pAudioConf->szHostVoiceOut = sizeof(VRDEVoice); 914 pAudioConf->szHostVoiceIn = sizeof(VRDEVoice); 915 pAudioConf->MaxHostVoicesOut = 1; 916 pAudioConf->MaxHostVoicesIn = 1; 917 } 141 918 142 919 /** 143 920 * @interface_method_impl{PDMIBASE,pfnQueryInterface} 144 921 */ 145 DECLCALLBACK(void *) AudioSniffer::drvQueryInterface(PPDMIBASE pInterface, const char *pszIID)922 static DECLCALLBACK(void *) drvAudioVRDEQueryInterface(PPDMIBASE pInterface, const char *pszIID) 146 923 { 147 924 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface); 148 PDRVAUDIO SNIFFER pDrv = PDMINS_2_DATA(pDrvIns, PDRVAUDIOSNIFFER);925 PDRVAUDIOVRDE pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOVRDE); 149 926 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase); 150 PDMIBASE_RETURN_INTERFACE(pszIID, PDMI AUDIOSNIFFERCONNECTOR, &pDrv->Connector);927 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIHOSTAUDIO, &pThis->IHostAudioR3); 151 928 return NULL; 152 929 } 153 930 154 931 932 static DECLCALLBACK(void) drvAudioVRDEDestruct(PPDMDRVINS pDrvIns) 933 { 934 } 935 155 936 /** 156 * Destruct a Audio Sniffer driver instance. 157 * 158 * @returns VBox status. 159 * @param pDrvIns The driver instance data. 160 */ 161 DECLCALLBACK(void) AudioSniffer::drvDestruct(PPDMDRVINS pDrvIns) 162 { 163 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns); 164 PDRVAUDIOSNIFFER pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOSNIFFER); 165 LogFlow(("AudioSniffer::drvDestruct: iInstance=%d\n", pDrvIns->iInstance)); 166 167 if (pThis->pAudioSniffer) 168 { 169 pThis->pAudioSniffer->mpDrv = NULL; 170 } 171 } 172 173 174 /** 175 * Construct a AudioSniffer driver instance. 937 * Construct a DirectSound Audio driver instance. 176 938 * 177 939 * @copydoc FNPDMDRVCONSTRUCT 178 940 */ 179 DECLCALLBACK(int) AudioSniffer::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags) 180 { 181 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns); 182 PDRVAUDIOSNIFFER pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOSNIFFER); 183 184 LogFlow(("AudioSniffer::drvConstruct: iInstance=%d\n", pDrvIns->iInstance)); 185 186 /* 187 * Validate configuration. 941 DECLCALLBACK(int) AudioVRDE::drvAudioVRDEConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags) 942 { 943 PDRVAUDIOVRDE pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOVRDE); 944 LogRel(("drvAudioVRDEConstruct\n")); 945 946 /* we save the address of AudioVRDE in Object node in CFGM tree and address of VRDP server in 947 * ObjectVRDPServer node. So presence of both is necessary. 188 948 */ 189 if (!CFGMR3AreValuesValid(pCfg, "Object\0"))190 949 //if (!CFGMR3AreValuesValid(pCfg, "Object\0") || !CFGMR3AreValuesValid(pCfg, "ObjectVRDPServer\0")) 950 // return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES; 191 951 AssertMsgReturn(PDMDrvHlpNoAttach(pDrvIns) == VERR_PDM_NO_ATTACHED_DRIVER, 192 952 ("Configuration error: Not possible to attach anything to this driver!\n"), … … 194 954 195 955 /* 196 * I Base.956 * Init the static parts. 197 957 */ 198 pDrvIns->IBase.pfnQueryInterface = AudioSniffer::drvQueryInterface; 199 200 /* Audio Sniffer connector. */ 201 pThis->Connector.pfnAudioSamplesOut = iface_AudioSamplesOut; 202 pThis->Connector.pfnAudioVolumeOut = iface_AudioVolumeOut; 203 pThis->Connector.pfnAudioInputBegin = iface_AudioInputBegin; 204 pThis->Connector.pfnAudioInputEnd = iface_AudioInputEnd; 205 958 pThis->pDrvIns = pDrvIns; 959 gpDrvIns = pDrvIns; 960 /* IBase */ 961 pDrvIns->IBase.pfnQueryInterface = drvAudioVRDEQueryInterface; 962 pThis->IHostAudioR3.pfnInitIn = drvAudioVRDEInitIn; 963 pThis->IHostAudioR3.pfnInitOut = drvAudioVRDEInitOut; 964 pThis->IHostAudioR3.pfnDisableEnableOut = drvAudioVRDEDisableEnableOut; 965 pThis->IHostAudioR3.pfnDisableEnableIn = drvAudioVRDEDisableEnableIn; 966 pThis->IHostAudioR3.pfnFiniIn = drvAudioVRDEFiniIn; 967 pThis->IHostAudioR3.pfnFiniOut = drvAudioVRDEFiniOut; 968 pThis->IHostAudioR3.pfnPlayIn = drvAudioVRDEPlayIn; 969 pThis->IHostAudioR3.pfnPlayOut = drvAudioVRDEPlayOut; 970 pThis->IHostAudioR3.pfnGetConf = drvAudioVRDEGetConf; 971 pThis->IHostAudioR3.pfnInit = drvAudioVRDEInit; 972 973 /* Get VRDPServer pointer */ 974 void *pv; 975 int rc = CFGMR3QueryPtr(pCfg, "ObjectVRDPServer", &pv); 976 if (RT_FAILURE(rc)) 977 { 978 AssertMsgFailed(("DrvAudioVRDE Confguration error: No/bad \"Object\" value! rc=%Rrc\n", rc)); 979 return rc; 980 } 981 /* CFGM tree saves the pointer to ConsoleVRDPServer in the Object node of AudioVRDE */ 982 pThis->pConsoleVRDPServer = (ConsoleVRDPServer *)pv; 983 pv = NULL; 984 985 rc = CFGMR3QueryPtr(pCfg, "Object", &pv); 986 if (RT_FAILURE(rc)) 987 { 988 AssertMsgFailed(("DrvAudioVRDE Confguration error: No/bad \"Object\" value! rc=%Rrc\n", rc)); 989 return rc; 990 } 991 pThis->pAudioVRDE = (AudioVRDE *)pv; 992 pThis->pAudioVRDE->mpDrv = pThis; 206 993 /* 207 * Get the Audio Sniffer Port interface of the above driver/device. 994 * Get the interface for the above driver (DrvAudio) to make mixer/conversion calls . 995 * Described in CFGM tree. 208 996 */ 209 pThis->pUpPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIAUDIO SNIFFERPORT);997 pThis->pUpPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIAUDIOCONNECTOR); 210 998 if (!pThis->pUpPort) 211 999 { … … 214 1002 } 215 1003 216 /*217 * Get the Console object pointer and update the mpDrv member.218 */219 void *pv;220 int rc = CFGMR3QueryPtr(pCfg, "Object", &pv);221 if (RT_FAILURE(rc))222 {223 AssertMsgFailed(("Configuration error: No/bad \"Object\" value! rc=%Rrc\n", rc));224 return rc;225 }226 pThis->pAudioSniffer = (AudioSniffer *)pv; /** @todo Check this cast! */227 pThis->pAudioSniffer->mpDrv = pThis;228 229 1004 return VINF_SUCCESS; 230 1005 } … … 232 1007 233 1008 /** 234 * Audio Sniffer driver registration record. 235 */ 236 const PDMDRVREG AudioSniffer::DrvReg = 237 { 238 /* u32Version */ 239 PDM_DRVREG_VERSION, 240 /* szName */ 241 "MainAudioSniffer", 1009 * Char driver registration record. 1010 */ 1011 const PDMDRVREG g_DrvAudioVRDE = 1012 { 1013 PDM_DRVREG_VERSION, 1014 /* szName */ 1015 "AudioVRDE", 242 1016 /* szRCMod */ 243 1017 "", … … 245 1019 "", 246 1020 /* pszDescription */ 247 " Main Audio Sniffer driver (Main as in the API).",1021 "Audio VRDE", 248 1022 /* fFlags */ 249 1023 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT, … … 253 1027 ~0U, 254 1028 /* cbInstance */ 255 sizeof(DRVAUDIO SNIFFER),1029 sizeof(DRVAUDIOVRDE), 256 1030 /* pfnConstruct */ 257 Audio Sniffer::drvConstruct,1031 AudioVRDE::drvAudioVRDEConstruct, 258 1032 /* pfnDestruct */ 259 AudioSniffer::drvDestruct,1033 drvAudioVRDEDestruct, 260 1034 /* pfnRelocate */ 261 1035 NULL, … … 281 1055 PDM_DRVREG_VERSION 282 1056 }; 283 /* vi: set tabstop=4 shiftwidth=4 expandtab: */ 1057 1058 1059 -
trunk/src/VBox/Main/src-client/VBoxDriversRegister.cpp
r48406 r50686 24 24 #include "DisplayImpl.h" 25 25 #include "VMMDev.h" 26 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 27 #include "DrvAudioVRDE.h" 28 #else 26 29 #include "AudioSnifferInterface.h" 30 #endif 27 31 #include "Nvram.h" 28 32 #include "UsbWebcamInterface.h" … … 67 71 if (RT_FAILURE(rc)) 68 72 return rc; 69 73 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 74 rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvAudioVRDE); 75 #else 70 76 rc = pCallbacks->pfnRegister(pCallbacks, &AudioSniffer::DrvReg); 77 #endif 71 78 if (RT_FAILURE(rc)) 72 79 return rc;
Note:
See TracChangeset
for help on using the changeset viewer.