- Timestamp:
- Jul 27, 2016 9:52:15 AM (8 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 1 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DrvAudio.cpp
r62327 r62580 2180 2180 PDM_DRVREG_CLASS_AUDIO, 2181 2181 /* cMaxInstances */ 2182 2,2182 UINT32_MAX, 2183 2183 /* cbInstance */ 2184 2184 sizeof(DRVAUDIO), -
trunk/src/VBox/Devices/Audio/DrvAudio.h
r62327 r62580 48 48 #include <iprt/circbuf.h> 49 49 #include <iprt/critsect.h> 50 #include <iprt/file.h> 51 #include <iprt/path.h> 50 52 51 53 #include <VBox/vmm/pdmdev.h> … … 138 140 const char *DrvAudioHlpAudFmtToStr(PDMAUDIOFMT enmFmt); 139 141 void DrvAudioHlpClearBuf(PPDMPCMPROPS pPCMInfo, void *pvBuf, size_t cbBuf, uint32_t cSamples); 142 uint32_t DrvAudioHlpCalcBitrate(uint8_t cBits, uint32_t uHz, uint8_t cChannels); 143 uint32_t DrvAudioHlpCalcBitrate(PPDMAUDIOSTREAMCFG pCfg); 140 144 bool DrvAudioHlpPCMPropsAreEqual(PPDMPCMPROPS pPCMProps1, PPDMPCMPROPS pPCMProps2); 141 145 bool DrvAudioHlpPCMPropsAreEqual(PPDMPCMPROPS pPCMProps, PPDMAUDIOSTREAMCFG pCfg); … … 147 151 PDMAUDIOFMT DrvAudioHlpStrToAudFmt(const char *pszFmt); 148 152 153 int DrvAudioHlpSanitizeFileName(char *pszPath, size_t cbPath); 154 int DrvAudioHlpGetFileName(char *pszFile, size_t cchFile, const char *pszPath, const char *pszName, PDMAUDIOFILETYPE enmType); 155 156 int DrvAudioHlpWAVFileOpen(PPDMAUDIOFILE pFile, const char *pszFile, uint32_t fOpen, PPDMPCMPROPS pProps, PDMAUDIOFILEFLAGS fFlags); 157 int DrvAudioHlpWAVFileClose(PPDMAUDIOFILE pFile); 158 size_t DrvAudioHlpWAVFileGetDataSize(PPDMAUDIOFILE pFile); 159 int DrvAudioHlpWAVFileWrite(PPDMAUDIOFILE pFile, const void *pvBuf, size_t cbBuf, uint32_t fFlags); 160 161 #define AUDIO_MAKE_FOURCC(c0, c1, c2, c3) RT_H2LE_U32_C(RT_MAKE_U32_FROM_U8(c0, c1, c2, c3)) 162 149 163 #endif /* DRV_AUDIO_H */ 150 164 -
trunk/src/VBox/Devices/Audio/DrvAudioCommon.cpp
r62372 r62580 42 42 * THE SOFTWARE. 43 43 */ 44 #define LOG_GROUP LOG_GROUP_DRV_AUDIO 45 #include <VBox/log.h> 44 #include <iprt/alloc.h> 46 45 #include <iprt/asm-math.h> 47 46 #include <iprt/assert.h> 47 #include <iprt/dir.h> 48 #include <iprt/file.h> 49 #include <iprt/string.h> 48 50 #include <iprt/uuid.h> 49 #include <iprt/string.h>50 #include <iprt/alloc.h>51 51 52 52 #include <VBox/vmm/pdmdev.h> … … 61 61 #include "AudioMixBuffer.h" 62 62 63 #pragma pack(1) 64 /** 65 * Structure for building up a .WAV file header. 66 */ 67 typedef struct AUDIOWAVFILEHDR 68 { 69 uint32_t u32RIFF; 70 uint32_t u32Size; 71 uint32_t u32WAVE; 72 73 uint32_t u32Fmt; 74 uint32_t u32Size1; 75 uint16_t u16AudioFormat; 76 uint16_t u16NumChannels; 77 uint32_t u32SampleRate; 78 uint32_t u32ByteRate; 79 uint16_t u16BlockAlign; 80 uint16_t u16BitsPerSample; 81 82 uint32_t u32ID2; 83 uint32_t u32Size2; 84 } AUDIOWAVFILEHDR, *PAUDIOWAVFILEHDR; 85 #pragma pack() 86 87 /** 88 * Structure for keeeping the internal .WAV file data 89 */ 90 typedef struct AUDIOWAVFILEDATA 91 { 92 /** The file header/footer. */ 93 AUDIOWAVFILEHDR Hdr; 94 } AUDIOWAVFILEDATA, *PAUDIOWAVFILEDATA; 63 95 64 96 /** … … 334 366 bool fEqual = pProps->uHz == pCfg->uHz 335 367 && pProps->cChannels == pCfg->cChannels 368 && pProps->cbBitrate == pCfg->cbBitrate 336 369 && pProps->fSigned == fSigned 337 370 && pProps->cBits == cBits … … 345 378 AssertPtrReturn(pProps2, false); 346 379 380 if (pProps1 == pProps2) 381 return true; 382 347 383 return pProps1->uHz == pProps2->uHz 348 384 && pProps1->cChannels == pProps2->cChannels 385 && pProps1->cbBitrate == pProps2->cbBitrate 349 386 && pProps1->fSigned == pProps2->fSigned 350 387 && pProps1->cBits == pProps2->cBits … … 366 403 pCfg->uHz = pPCMProps->uHz; 367 404 pCfg->cChannels = pPCMProps->cChannels; 405 pCfg->cbBitrate = DrvAudioHlpCalcBitrate(pPCMProps->cBits, pPCMProps->uHz, pPCMProps->cChannels) / 8; 368 406 pCfg->enmFormat = DrvAudioAudFmtBitsToAudFmt(pPCMProps->cBits, pPCMProps->fSigned); 369 407 … … 401 439 } 402 440 441 fValid |= pCfg->uHz > 0; 403 442 /** @todo Check for defined frequencies supported. */ 404 fValid |= pCfg-> uHz> 0;443 fValid |= pCfg->cbBitrate > 0; 405 444 406 445 return fValid; … … 456 495 pProps->cBits = cBits; 457 496 pProps->fSigned = fSigned; 497 pProps->cShift = (pCfg->cChannels == 2) + cShift; 458 498 pProps->cChannels = pCfg->cChannels; 459 pProps->cShift = (pCfg->cChannels == 2) + cShift;460 499 pProps->uAlign = (1 << pProps->cShift) - 1; 461 pProps->cbBitrate = (pProps->cBits * pProps->uHz * pProps->cChannels) / 8;500 pProps->cbBitrate = DrvAudioHlpCalcBitrate(pCfg) / 8; 462 501 pProps->fSwapEndian = pCfg->enmEndianness != PDMAUDIOHOSTENDIANNESS; 463 502 } … … 497 536 } 498 537 538 LogFlow((", bitrate=%RU32", pCfg->cbBitrate)); 539 499 540 LogFlow((", endianness=")); 500 541 switch (pCfg->enmEndianness) … … 512 553 } 513 554 555 uint32_t DrvAudioHlpCalcBitrate(uint8_t cBits, uint32_t uHz, uint8_t cChannels) 556 { 557 return (cBits * uHz * cChannels); 558 } 559 560 uint32_t DrvAudioHlpCalcBitrate(PPDMAUDIOSTREAMCFG pCfg) 561 { 562 return DrvAudioHlpCalcBitrate(DrvAudioHlpAudFmtToBits(pCfg->enmFormat), pCfg->uHz, pCfg->cChannels); 563 } 564 565 /** 566 * Sanitizes the file name component so that unsupported characters 567 * will be replaced by an underscore ("_"). 568 * 569 * @return IPRT status code. 570 * @param pszPath Path to sanitize. 571 * @param cbPath Size (in bytes) of path to sanitize. 572 */ 573 int DrvAudioHlpSanitizeFileName(char *pszPath, size_t cbPath) 574 { 575 int rc = VINF_SUCCESS; 576 #ifdef RT_OS_WINDOWS 577 /* Filter out characters not allowed on Windows platforms, put in by 578 RTTimeSpecToString(). */ 579 /** @todo Use something like RTPathSanitize() when available. Later. */ 580 RTUNICP aCpSet[] = 581 { ' ', ' ', '(', ')', '-', '.', '0', '9', 'A', 'Z', 'a', 'z', '_', '_', 582 0xa0, 0xd7af, '\0' }; 583 ssize_t cReplaced = RTStrPurgeComplementSet(pszPath, aCpSet, '_' /* Replacement */); 584 if (cReplaced < 0) 585 rc = VERR_INVALID_UTF8_ENCODING; 586 #endif 587 return rc; 588 } 589 590 /** 591 * Constructs an unique file name, based on the given path and the audio file type. 592 * 593 * @returns IPRT status code. 594 * @param pszFile Where to store the constructed file name. 595 * @param cchFile Size (in characters) of the file name buffer. 596 * @param pszPath Base path to use. 597 * @param pszName A name for better identifying the file. Optional. 598 * @param enmType Audio file type to construct file name for. 599 */ 600 int DrvAudioHlpGetFileName(char *pszFile, size_t cchFile, const char *pszPath, const char *pszName, PDMAUDIOFILETYPE enmType) 601 { 602 AssertPtrReturn(pszFile, VERR_INVALID_POINTER); 603 AssertReturn(cchFile, VERR_INVALID_PARAMETER); 604 AssertPtrReturn(pszPath, VERR_INVALID_POINTER); 605 /* pszName is optional. */ 606 607 int rc; 608 609 do 610 { 611 char szFilePath[RTPATH_MAX]; 612 size_t cchFilePath = RTStrPrintf(szFilePath, sizeof(szFilePath), "%s", pszPath); 613 614 /* Create it when necessary. */ 615 if (!RTDirExists(szFilePath)) 616 { 617 rc = RTDirCreateFullPath(szFilePath, RTFS_UNIX_IRWXU); 618 if (RT_FAILURE(rc)) 619 break; 620 } 621 622 /* The actually drop directory consist of the current time stamp and a 623 * unique number when necessary. */ 624 char pszTime[64]; 625 RTTIMESPEC time; 626 if (!RTTimeSpecToString(RTTimeNow(&time), pszTime, sizeof(pszTime))) 627 { 628 rc = VERR_BUFFER_OVERFLOW; 629 break; 630 } 631 632 rc = DrvAudioHlpSanitizeFileName(pszTime, sizeof(pszTime)); 633 if (RT_FAILURE(rc)) 634 break; 635 636 rc = RTPathAppend(szFilePath, sizeof(szFilePath), pszTime); 637 if (RT_FAILURE(rc)) 638 break; 639 640 if (pszName) /* Optional name given? */ 641 { 642 rc = RTStrCat(szFilePath, sizeof(szFilePath), "-"); 643 if (RT_FAILURE(rc)) 644 break; 645 646 rc = RTStrCat(szFilePath, sizeof(szFilePath), pszName); 647 if (RT_FAILURE(rc)) 648 break; 649 } 650 651 switch (enmType) 652 { 653 case PDMAUDIOFILETYPE_WAV: 654 rc = RTStrCat(szFilePath, sizeof(szFilePath), ".wav"); 655 break; 656 657 default: 658 AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED); 659 } 660 661 if (RT_FAILURE(rc)) 662 break; 663 664 RTStrPrintf(pszFile, cchFile, "%s", szFilePath); 665 666 } while (0); 667 668 LogFlowFuncLeaveRC(rc); 669 return rc; 670 } 671 672 int DrvAudioHlpWAVFileOpen(PPDMAUDIOFILE pFile, const char *pszFile, uint32_t fOpen, PPDMPCMPROPS pProps, 673 PDMAUDIOFILEFLAGS fFlags) 674 { 675 AssertPtrReturn(pFile, VERR_INVALID_POINTER); 676 AssertPtrReturn(pszFile, VERR_INVALID_POINTER); 677 /** @todo Validate fOpen flags. */ 678 AssertPtrReturn(pProps, VERR_INVALID_POINTER); 679 /** @todo Validate fFlags flags. */ 680 681 Assert(pProps->cChannels); 682 Assert(pProps->uHz); 683 Assert(pProps->cbBitrate); 684 Assert(pProps->cBits); 685 686 pFile->pvData = (PAUDIOWAVFILEDATA)RTMemAllocZ(sizeof(AUDIOWAVFILEDATA)); 687 if (!pFile->pvData) 688 return VERR_NO_MEMORY; 689 pFile->cbData = sizeof(PAUDIOWAVFILEDATA); 690 691 PAUDIOWAVFILEDATA pData = (PAUDIOWAVFILEDATA)pFile->pvData; 692 AssertPtr(pData); 693 694 /* Header. */ 695 pData->Hdr.u32RIFF = AUDIO_MAKE_FOURCC('R','I','F','F'); 696 pData->Hdr.u32Size = 36; 697 pData->Hdr.u32WAVE = AUDIO_MAKE_FOURCC('W','A','V','E'); 698 699 pData->Hdr.u32Fmt = AUDIO_MAKE_FOURCC('f','m','t',' '); 700 pData->Hdr.u32Size1 = 16; /* Means PCM. */ 701 pData->Hdr.u16AudioFormat = 1; /* PCM, linear quantization. */ 702 pData->Hdr.u16NumChannels = pProps->cChannels; 703 pData->Hdr.u32SampleRate = pProps->uHz; 704 pData->Hdr.u32ByteRate = pProps->cbBitrate / 8; 705 pData->Hdr.u16BlockAlign = pProps->cChannels * pProps->cBits / 8; 706 pData->Hdr.u16BitsPerSample = pProps->cBits; 707 708 /* Data chunk. */ 709 pData->Hdr.u32ID2 = AUDIO_MAKE_FOURCC('d','a','t','a'); 710 pData->Hdr.u32Size2 = 0; 711 712 int rc = RTFileOpen(&pFile->hFile, pszFile, fOpen); 713 if (RT_SUCCESS(rc)) 714 { 715 rc = RTFileWrite(pFile->hFile, &pData->Hdr, sizeof(pData->Hdr), NULL); 716 if (RT_FAILURE(rc)) 717 { 718 RTFileClose(pFile->hFile); 719 pFile->hFile = NIL_RTFILE; 720 } 721 } 722 723 if (RT_SUCCESS(rc)) 724 { 725 pFile->enmType = PDMAUDIOFILETYPE_WAV; 726 727 RTStrPrintf(pFile->szName, RT_ELEMENTS(pFile->szName), "%s", pszFile); 728 } 729 else 730 { 731 RTMemFree(pFile->pvData); 732 pFile->pvData = NULL; 733 pFile->cbData = 0; 734 } 735 736 return rc; 737 } 738 739 int DrvAudioHlpWAVFileClose(PPDMAUDIOFILE pFile) 740 { 741 AssertPtrReturn(pFile, VERR_INVALID_POINTER); 742 743 Assert(pFile->enmType == PDMAUDIOFILETYPE_WAV); 744 745 if (pFile->hFile != NIL_RTFILE) 746 { 747 PAUDIOWAVFILEDATA pData = (PAUDIOWAVFILEDATA)pFile->pvData; 748 AssertPtr(pData); 749 750 /* Update the header with the current data size. */ 751 RTFileWriteAt(pFile->hFile, 0, &pData->Hdr, sizeof(pData->Hdr), NULL); 752 753 RTFileClose(pFile->hFile); 754 pFile->hFile = NIL_RTFILE; 755 } 756 757 if (pFile->pvData) 758 { 759 RTMemFree(pFile->pvData); 760 pFile->pvData = NULL; 761 } 762 763 pFile->cbData = 0; 764 pFile->enmType = PDMAUDIOFILETYPE_UNKNOWN; 765 766 return VINF_SUCCESS; 767 } 768 769 size_t DrvAudioHlpWAVFileGetDataSize(PPDMAUDIOFILE pFile) 770 { 771 AssertPtrReturn(pFile, VERR_INVALID_POINTER); 772 773 Assert(pFile->enmType == PDMAUDIOFILETYPE_WAV); 774 775 PAUDIOWAVFILEDATA pData = (PAUDIOWAVFILEDATA)pFile->pvData; 776 AssertPtr(pData); 777 778 return pData->Hdr.u32Size2; 779 } 780 781 int DrvAudioHlpWAVFileWrite(PPDMAUDIOFILE pFile, const void *pvBuf, size_t cbBuf, uint32_t fFlags) 782 { 783 AssertPtrReturn(pFile, VERR_INVALID_POINTER); 784 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER); 785 /** @todo Validate fFlags. */ 786 787 Assert(pFile->enmType == PDMAUDIOFILETYPE_WAV); 788 789 if (!cbBuf) 790 return VINF_SUCCESS; 791 792 PAUDIOWAVFILEDATA pData = (PAUDIOWAVFILEDATA)pFile->pvData; 793 AssertPtr(pData); 794 795 int rc = RTFileWrite(pFile->hFile, pvBuf, cbBuf, NULL); 796 if (RT_SUCCESS(rc)) 797 { 798 pData->Hdr.u32Size += (uint32_t)cbBuf; 799 pData->Hdr.u32Size2 += (uint32_t)cbBuf; 800 } 801 802 return rc; 803 } 804 -
trunk/src/VBox/Devices/Makefile.kmk
r62577 r62580 548 548 Audio/DrvHostNullAudio.cpp 549 549 550 ifdef VBOX_WITH_AUDIO_DEBUG 551 VBoxDD_DEFS += VBOX_WITH_AUDIO_DEBUG 552 VBoxDD_SOURCES += \ 553 Audio/DrvHostDebugAudio.cpp 554 endif 555 550 556 ifeq ($(KBUILD_TARGET),darwin) 551 557 VBoxDD_SOURCES += \ -
trunk/src/VBox/Devices/build/VBoxDD.cpp
r62516 r62580 275 275 if (RT_FAILURE(rc)) 276 276 return rc; 277 #ifdef VBOX_WITH_AUDIO_DEBUG 278 rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvHostDebugAudio); 279 if (RT_FAILURE(rc)) 280 return rc; 281 #endif 277 282 rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvHostNullAudio); 278 283 if (RT_FAILURE(rc)) -
trunk/src/VBox/Devices/build/VBoxDD.h
r62056 r62580 118 118 extern const PDMDRVREG g_DrvNetSniffer; 119 119 extern const PDMDRVREG g_DrvAUDIO; 120 #ifdef VBOX_WITH_AUDIO_DEBUG 121 extern const PDMDRVREG g_DrvHostDebugAudio; 122 #endif 120 123 extern const PDMDRVREG g_DrvHostNullAudio; 121 124 #if defined(RT_OS_WINDOWS) -
trunk/src/VBox/Main/Makefile.kmk
r62577 r62580 274 274 $(if $(VBOX_WITH_ALSA),VBOX_WITH_ALSA,) \ 275 275 $(if $(VBOX_WITH_PULSE),VBOX_WITH_PULSE,) \ 276 $(if $(VBOX_WITH_AUDIO_DEBUG),VBOX_WITH_AUDIO_DEBUG,) \ 276 277 $(if $(VBOX_WITH_VRDE_AUDIO),VBOX_WITH_VRDE_AUDIO,) \ 277 278 $(if $(VBOX_WITH_E1000),VBOX_WITH_E1000,) \ -
trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
r62379 r62580 2923 2923 InsertConfigInteger(pCfg, "Object", (uintptr_t)mAudioVRDE); 2924 2924 InsertConfigInteger(pCfg, "ObjectVRDPServer", (uintptr_t)mConsoleVRDPServer); 2925 #endif 2926 2927 #ifdef VBOX_WITH_AUDIO_DEBUG 2928 InsertConfigNode(pInst, "LUN#2", &pLunL1); 2929 InsertConfigString(pLunL1, "Driver", "AUDIO"); 2930 2931 InsertConfigNode(pLunL1, "AttachedDriver", &pLunL1); 2932 InsertConfigString(pLunL1, "Driver", "DebugAudio"); 2933 2934 InsertConfigNode(pLunL1, "Config", &pCfg); 2935 InsertConfigString(pCfg, "AudioDriver", "DebugAudio"); 2936 InsertConfigString(pCfg, "StreamName", bstr); 2925 2937 #endif 2926 2938 /** @todo Add audio video recording driver here. */
Note:
See TracChangeset
for help on using the changeset viewer.