Changeset 89465 in vbox
- Timestamp:
- Jun 2, 2021 1:03:23 PM (4 years ago)
- Location:
- trunk/src/VBox/Devices/Audio
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/AudioTest.cpp
r89463 r89465 1464 1464 int AudioTestWaveFileOpen(const char *pszFile, PAUDIOTESTWAVEFILE pWaveFile, PRTERRINFO pErrInfo) 1465 1465 { 1466 pWaveFile->u32Magic = AUDIOTESTWAVEFILE_MAGIC_DEAD; 1466 1467 RT_ZERO(pWaveFile->Props); 1467 1468 pWaveFile->hFile = NIL_RTFILE; … … 1606 1607 * We're good! 1607 1608 */ 1608 pWaveFile->offCur = 0; 1609 pWaveFile->offCur = 0; 1610 pWaveFile->fReadMode = true; 1611 pWaveFile->u32Magic = AUDIOTESTWAVEFILE_MAGIC; 1609 1612 return VINF_SUCCESS; 1610 1613 } … … 1635 1638 } 1636 1639 1640 1641 /** 1642 * Creates a new wave file. 1643 * 1644 * @returns VBox status code. 1645 * @param pszFile The filename. 1646 * @param pProps The audio format properties. 1647 * @param pWaveFile The wave file structure to fill in on success. 1648 * @param pErrInfo Where to return addition error details on failure. 1649 */ 1650 int AudioTestWaveFileCreate(const char *pszFile, PCPDMAUDIOPCMPROPS pProps, PAUDIOTESTWAVEFILE pWaveFile, PRTERRINFO pErrInfo) 1651 { 1652 /* 1653 * Construct the file header first (we'll do some input validation 1654 * here, so better do it before creating the file). 1655 */ 1656 struct 1657 { 1658 RTRIFFHDR Hdr; 1659 RTRIFFWAVEFMTEXTCHUNK FmtExt; 1660 RTRIFFCHUNK Data; 1661 } FileHdr; 1662 1663 FileHdr.Hdr.uMagic = RTRIFFHDR_MAGIC; 1664 FileHdr.Hdr.cbFile = 0; /* need to update this later */ 1665 FileHdr.Hdr.uFileType = RTRIFF_FILE_TYPE_WAVE; 1666 FileHdr.FmtExt.Chunk.uMagic = RTRIFFWAVEFMT_MAGIC; 1667 FileHdr.FmtExt.Chunk.cbChunk = sizeof(RTRIFFWAVEFMTEXTCHUNK) - sizeof(RTRIFFCHUNK); 1668 FileHdr.FmtExt.Data.Core.uFormatTag = RTRIFFWAVEFMT_TAG_EXTENSIBLE; 1669 FileHdr.FmtExt.Data.Core.cChannels = PDMAudioPropsChannels(pProps); 1670 FileHdr.FmtExt.Data.Core.uHz = PDMAudioPropsHz(pProps); 1671 FileHdr.FmtExt.Data.Core.cbRate = PDMAudioPropsFramesToBytes(pProps, PDMAudioPropsHz(pProps)); 1672 FileHdr.FmtExt.Data.Core.cbFrame = PDMAudioPropsFrameSize(pProps); 1673 FileHdr.FmtExt.Data.Core.cBitsPerSample = PDMAudioPropsSampleBits(pProps); 1674 FileHdr.FmtExt.Data.cbExtra = sizeof(FileHdr.FmtExt.Data) - sizeof(FileHdr.FmtExt.Data.Core); 1675 FileHdr.FmtExt.Data.cValidBitsPerSample = PDMAudioPropsSampleBits(pProps); 1676 FileHdr.FmtExt.Data.fChannelMask = 0; 1677 for (uintptr_t idxCh = 0; idxCh < FileHdr.FmtExt.Data.Core.cChannels; idxCh++) 1678 { 1679 PDMAUDIOCHANNELID const idCh = (PDMAUDIOCHANNELID)pProps->aidChannels[idxCh]; 1680 if ( idCh >= PDMAUDIOCHANNELID_FIRST_STANDARD 1681 && idCh < PDMAUDIOCHANNELID_END_STANDARD) 1682 { 1683 if (!(FileHdr.FmtExt.Data.fChannelMask & RT_BIT_32(idCh - PDMAUDIOCHANNELID_FIRST_STANDARD))) 1684 FileHdr.FmtExt.Data.fChannelMask |= RT_BIT_32(idCh - PDMAUDIOCHANNELID_FIRST_STANDARD); 1685 else 1686 return RTErrInfoSetF(pErrInfo, VERR_INVALID_PARAMETER, "Channel #%u repeats channel ID %d", idxCh, idCh); 1687 } 1688 else 1689 return RTErrInfoSetF(pErrInfo, VERR_INVALID_PARAMETER, "Invalid channel ID %d for channel #%u", idCh, idxCh); 1690 } 1691 1692 RTUUID UuidTmp; 1693 int rc = RTUuidFromStr(&UuidTmp, RTRIFFWAVEFMTEXT_SUBTYPE_PCM); 1694 AssertRCReturn(rc, rc); 1695 FileHdr.FmtExt.Data.SubFormat = UuidTmp; /* (64-bit field maybe unaligned) */ 1696 1697 FileHdr.Data.uMagic = RTRIFFWAVEDATACHUNK_MAGIC; 1698 FileHdr.Data.cbChunk = 0; /* need to update this later */ 1699 1700 /* 1701 * Create the file and write the header. 1702 */ 1703 pWaveFile->hFile = NIL_RTFILE; 1704 rc = RTFileOpen(&pWaveFile->hFile, pszFile, RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE); 1705 if (RT_FAILURE(rc)) 1706 return RTErrInfoSet(pErrInfo, rc, "RTFileOpen failed"); 1707 1708 rc = RTFileWrite(pWaveFile->hFile, &FileHdr, sizeof(FileHdr), NULL); 1709 if (RT_SUCCESS(rc)) 1710 { 1711 /* 1712 * Initialize the wave file structure. 1713 */ 1714 pWaveFile->fReadMode = false; 1715 pWaveFile->offCur = 0; 1716 pWaveFile->offSamples = 0; 1717 pWaveFile->cbSamples = 0; 1718 pWaveFile->Props = *pProps; 1719 pWaveFile->offSamples = RTFileTell(pWaveFile->hFile); 1720 if (pWaveFile->offSamples != UINT32_MAX) 1721 { 1722 pWaveFile->u32Magic = AUDIOTESTWAVEFILE_MAGIC; 1723 return VINF_SUCCESS; 1724 } 1725 rc = RTErrInfoSet(pErrInfo, VERR_SEEK, "RTFileTell failed"); 1726 } 1727 else 1728 RTErrInfoSet(pErrInfo, rc, "RTFileWrite failed writing header"); 1729 1730 RTFileClose(pWaveFile->hFile); 1731 pWaveFile->hFile = NIL_RTFILE; 1732 pWaveFile->u32Magic = AUDIOTESTWAVEFILE_MAGIC_DEAD; 1733 1734 RTFileDelete(pszFile); 1735 return rc; 1736 } 1737 1738 1637 1739 /** 1638 1740 * Closes a wave file. 1639 1741 */ 1640 void AudioTestWaveFileClose(PAUDIOTESTWAVEFILE pWaveFile) 1641 { 1642 RTFileClose(pWaveFile->hFile); 1643 pWaveFile->hFile = NIL_RTFILE; 1742 int AudioTestWaveFileClose(PAUDIOTESTWAVEFILE pWaveFile) 1743 { 1744 AssertReturn(pWaveFile->u32Magic == AUDIOTESTWAVEFILE_MAGIC, VERR_INVALID_MAGIC); 1745 int rcRet = VINF_SUCCESS; 1746 int rc; 1747 1748 /* 1749 * Update the size fields if writing. 1750 */ 1751 if (!pWaveFile->fReadMode) 1752 { 1753 uint64_t cbFile = RTFileTell(pWaveFile->hFile); 1754 if (cbFile != UINT64_MAX) 1755 { 1756 uint32_t cbFile32 = cbFile - sizeof(RTRIFFCHUNK); 1757 rc = RTFileWriteAt(pWaveFile->hFile, RT_OFFSETOF(RTRIFFHDR, cbFile), &cbFile32, sizeof(cbFile32), NULL); 1758 AssertRCStmt(rc, rcRet = rc); 1759 1760 uint32_t cbSamples = cbFile - pWaveFile->offSamples; 1761 rc = RTFileWriteAt(pWaveFile->hFile, pWaveFile->offSamples - sizeof(uint32_t), &cbSamples, sizeof(cbSamples), NULL); 1762 AssertRCStmt(rc, rcRet = rc); 1763 } 1764 else 1765 rcRet = VERR_SEEK; 1766 } 1767 1768 /* 1769 * Close it. 1770 */ 1771 rc = RTFileClose(pWaveFile->hFile); 1772 AssertRCStmt(rc, rcRet = rc); 1773 1774 pWaveFile->hFile = NIL_RTFILE; 1775 pWaveFile->u32Magic = AUDIOTESTWAVEFILE_MAGIC_DEAD; 1776 return rcRet; 1644 1777 } 1645 1778 … … 1656 1789 int AudioTestWaveFileRead(PAUDIOTESTWAVEFILE pWaveFile, void *pvBuf, size_t cbBuf, size_t *pcbRead) 1657 1790 { 1791 AssertReturn(pWaveFile->u32Magic == AUDIOTESTWAVEFILE_MAGIC, VERR_INVALID_MAGIC); 1792 AssertReturn(pWaveFile->fReadMode, VERR_ACCESS_DENIED); 1793 1658 1794 bool fEofAdjusted; 1659 1795 if (pWaveFile->offCur + cbBuf <= pWaveFile->cbSamples) … … 1684 1820 } 1685 1821 1822 1823 /** 1824 * Writes samples to a wave file. 1825 * 1826 * @returns VBox status code. 1827 * @param pWaveFile The file to write to. 1828 * @param pvBuf The samples to write. 1829 * @param cbBuf How many bytes of samples to write. 1830 */ 1831 int AudioTestWaveFileWrite(PAUDIOTESTWAVEFILE pWaveFile, const void *pvBuf, size_t cbBuf) 1832 { 1833 AssertReturn(pWaveFile->u32Magic == AUDIOTESTWAVEFILE_MAGIC, VERR_INVALID_MAGIC); 1834 AssertReturn(!pWaveFile->fReadMode, VERR_ACCESS_DENIED); 1835 1836 pWaveFile->cbSamples += (uint32_t)cbBuf; 1837 return RTFileWrite(pWaveFile->hFile, pvBuf, cbBuf, NULL); 1838 } 1839 -
trunk/src/VBox/Devices/Audio/AudioTest.h
r89463 r89465 336 336 typedef AUDIOTESTERRORDESC *PAUDIOTESTERRORDESC; 337 337 338 double AudioTestToneInit(PAUDIOTESTTONE pTone, PPDMAUDIOPCMPROPS pProps, double dbFreq); 339 double AudioTestToneInitRandom(PAUDIOTESTTONE pTone, PPDMAUDIOPCMPROPS pProps); 340 int AudioTestToneGenerate(PAUDIOTESTTONE pTone, void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten); 341 342 int AudioTestToneParamsInitRandom(PAUDIOTESTTONEPARMS pToneParams, PPDMAUDIOPCMPROPS pProps); 343 344 int AudioTestPathCreateTemp(char *pszPath, size_t cbPath, const char *pszUUID); 345 int AudioTestPathCreate(char *pszPath, size_t cbPath, const char *pszUUID); 346 347 int AudioTestSetObjCreateAndRegister(PAUDIOTESTSET pSet, const char *pszName, PAUDIOTESTOBJ *ppObj); 348 int AudioTestSetObjWrite(PAUDIOTESTOBJ pObj, const void *pvBuf, size_t cbBuf); 349 int AudioTestSetObjAddMetadataStr(PAUDIOTESTOBJ pObj, const char *pszFormat, ...); 350 int AudioTestSetObjClose(PAUDIOTESTOBJ pObj); 351 352 int AudioTestSetTestBegin(PAUDIOTESTSET pSet, const char *pszDesc, PAUDIOTESTPARMS pParms, PAUDIOTESTENTRY *ppEntry); 353 int AudioTestSetTestFailed(PAUDIOTESTENTRY pEntry, int rc, const char *pszErr); 354 int AudioTestSetTestDone(PAUDIOTESTENTRY pEntry); 355 356 int AudioTestSetCreate(PAUDIOTESTSET pSet, const char *pszPath, const char *pszTag); 357 int AudioTestSetDestroy(PAUDIOTESTSET pSet); 358 int AudioTestSetOpen(PAUDIOTESTSET pSet, const char *pszPath); 359 int AudioTestSetClose(PAUDIOTESTSET pSet); 360 int AudioTestSetWipe(PAUDIOTESTSET pSet); 361 const char *AudioTestSetGetTag(PAUDIOTESTSET pSet); 362 bool AudioTestSetIsPacked(const char *pszPath); 363 int AudioTestSetPack(PAUDIOTESTSET pSet, const char *pszOutDir, char *pszFileName, size_t cbFileName); 364 int AudioTestSetUnpack(const char *pszFile, const char *pszOutDir); 365 int AudioTestSetVerify(PAUDIOTESTSET pSetA, PAUDIOTESTSET pSetB, PAUDIOTESTERRORDESC pErrDesc); 366 367 bool AudioTestErrorDescFailed(PAUDIOTESTERRORDESC pErr); 368 void AudioTestErrorDescDestroy(PAUDIOTESTERRORDESC pErr); 369 370 /** @name Wave File Accessors 371 * @{ */ 338 372 /** 339 373 * An open wave (.WAV) file. … … 341 375 typedef struct AUDIOTESTWAVEFILE 342 376 { 377 /** Magic value (AUDIOTESTWAVEFILE_MAGIC). */ 378 uint32_t u32Magic; 379 /** Set if we're in read-mode, clear if in write mode. */ 380 bool fReadMode; 343 381 /** The file handle. */ 344 382 RTFILE hFile; … … 355 393 typedef AUDIOTESTWAVEFILE *PAUDIOTESTWAVEFILE; 356 394 357 358 double AudioTestToneInit(PAUDIOTESTTONE pTone, PPDMAUDIOPCMPROPS pProps, double dbFreq); 359 double AudioTestToneInitRandom(PAUDIOTESTTONE pTone, PPDMAUDIOPCMPROPS pProps); 360 int AudioTestToneGenerate(PAUDIOTESTTONE pTone, void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten); 361 362 int AudioTestToneParamsInitRandom(PAUDIOTESTTONEPARMS pToneParams, PPDMAUDIOPCMPROPS pProps); 363 364 int AudioTestPathCreateTemp(char *pszPath, size_t cbPath, const char *pszUUID); 365 int AudioTestPathCreate(char *pszPath, size_t cbPath, const char *pszUUID); 366 367 int AudioTestSetObjCreateAndRegister(PAUDIOTESTSET pSet, const char *pszName, PAUDIOTESTOBJ *ppObj); 368 int AudioTestSetObjWrite(PAUDIOTESTOBJ pObj, const void *pvBuf, size_t cbBuf); 369 int AudioTestSetObjAddMetadataStr(PAUDIOTESTOBJ pObj, const char *pszFormat, ...); 370 int AudioTestSetObjClose(PAUDIOTESTOBJ pObj); 371 372 int AudioTestSetTestBegin(PAUDIOTESTSET pSet, const char *pszDesc, PAUDIOTESTPARMS pParms, PAUDIOTESTENTRY *ppEntry); 373 int AudioTestSetTestFailed(PAUDIOTESTENTRY pEntry, int rc, const char *pszErr); 374 int AudioTestSetTestDone(PAUDIOTESTENTRY pEntry); 375 376 int AudioTestSetCreate(PAUDIOTESTSET pSet, const char *pszPath, const char *pszTag); 377 int AudioTestSetDestroy(PAUDIOTESTSET pSet); 378 int AudioTestSetOpen(PAUDIOTESTSET pSet, const char *pszPath); 379 int AudioTestSetClose(PAUDIOTESTSET pSet); 380 int AudioTestSetWipe(PAUDIOTESTSET pSet); 381 const char *AudioTestSetGetTag(PAUDIOTESTSET pSet); 382 bool AudioTestSetIsPacked(const char *pszPath); 383 int AudioTestSetPack(PAUDIOTESTSET pSet, const char *pszOutDir, char *pszFileName, size_t cbFileName); 384 int AudioTestSetUnpack(const char *pszFile, const char *pszOutDir); 385 int AudioTestSetVerify(PAUDIOTESTSET pSetA, PAUDIOTESTSET pSetB, PAUDIOTESTERRORDESC pErrDesc); 386 387 bool AudioTestErrorDescFailed(PAUDIOTESTERRORDESC pErr); 388 void AudioTestErrorDescDestroy(PAUDIOTESTERRORDESC pErr); 395 /** Magic value for AUDIOTESTWAVEFILE::u32Magic (Miles Dewey Davis III). */ 396 #define AUDIOTESTWAVEFILE_MAGIC UINT32_C(0x19260526) 397 /** Magic value for AUDIOTESTWAVEFILE::u32Magic after closing. */ 398 #define AUDIOTESTWAVEFILE_MAGIC_DEAD UINT32_C(0x19910928) 389 399 390 400 int AudioTestWaveFileOpen(const char *pszFile, PAUDIOTESTWAVEFILE pWaveFile, PRTERRINFO pErrInfo); 401 int AudioTestWaveFileCreate(const char *pszFile, PCPDMAUDIOPCMPROPS pProps, PAUDIOTESTWAVEFILE pWaveFile, PRTERRINFO pErrInfo); 391 402 int AudioTestWaveFileRead(PAUDIOTESTWAVEFILE pWaveFile, void *pvBuf, size_t cbBuf, size_t *pcbRead); 392 void AudioTestWaveFileClose(PAUDIOTESTWAVEFILE pWaveFile); 403 int AudioTestWaveFileWrite(PAUDIOTESTWAVEFILE pWaveFile, const void *pvBuf, size_t cbBuf); 404 int AudioTestWaveFileClose(PAUDIOTESTWAVEFILE pWaveFile); 405 406 /** @} */ 393 407 394 408 #endif /* !VBOX_INCLUDED_SRC_Audio_AudioTest_h */
Note:
See TracChangeset
for help on using the changeset viewer.