Changeset 90046 in vbox
- Timestamp:
- Jul 6, 2021 9:03:18 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/AudioTest.cpp
r90005 r90046 44 44 #define _USE_MATH_DEFINES 45 45 #include <math.h> /* sin, M_PI */ 46 47 #define LOG_GROUP LOG_GROUP_DRV_HOST_AUDIO /** @todo Add an own log group for this? */ 48 #include <VBox/log.h> 46 49 47 50 #include <VBox/version.h> … … 181 184 /** Flag indicating whether to keep going after an error has occurred. */ 182 185 bool fKeepGoing; 186 /** Threshold of file differences (chunks) at when we consider audio files 187 * as not matching. */ 188 uint32_t cThresholdDiff; 183 189 /** PCM properties to use for verification. */ 184 190 PDMAUDIOPCMPROPS PCMProps; … … 376 382 377 383 /** 384 * Finds the next audible *or* silent audio sample and returns its offset. 385 * 386 * @returns Offset (in bytes) of the next found sample. 387 * @param hFile File handle of file to search in. 388 * @param fFindSilence Whether to search for a silent sample or not (i.e. audible). 389 * What a silent sample is depends on \a pToneParms PCM parameters. 390 * @param uOff Absolute offset (in bytes) to start searching from. 391 * @param pToneParms Tone parameters to use. 392 */ 393 static uint64_t audioTestToneFileFind(RTFILE hFile, bool fFindSilence, uint64_t uOff, PAUDIOTESTTONEPARMS pToneParms) 394 { 395 int rc = RTFileSeek(hFile, uOff, RTFILE_SEEK_BEGIN, NULL); 396 AssertRCReturn(rc, 0); 397 398 uint64_t offFound = 0; 399 int64_t abSample[_4K]; 400 401 size_t cbRead; 402 uint32_t cConseqSilence = 0; 403 for (;;) 404 { 405 rc = RTFileRead(hFile, &abSample, sizeof(abSample), &cbRead); 406 if ( RT_FAILURE(rc) 407 || !cbRead) 408 break; 409 410 size_t const cbSample = PDMAudioPropsSampleSize(&pToneParms->Props); 411 412 for (size_t i = 0; i < cbRead / cbSample; i += cbSample) /** @todo Slow as heck, but works for now. */ 413 { 414 bool const fIsSilence = PDMAudioPropsIsBufferSilence(&pToneParms->Props, (const uint8_t *)abSample + i, cbSample); 415 if (fIsSilence == fFindSilence) 416 { 417 offFound += cbSample; 418 cConseqSilence++; 419 } 420 else 421 break; 422 } 423 } 424 425 return offFound; 426 } 427 428 /** 378 429 * Generates a tag. 379 430 * … … 801 852 int rc = audioTestObjGetStr(phObj, pszKey, szVal, sizeof(szVal)); 802 853 if (RT_SUCCESS(rc)) 803 *pbVal = RT_BOOL(RTStrToUInt8(szVal)); 854 *pbVal = (RTStrICmp(szVal, "true") == 0) 855 || (RTStrICmp(szVal, "1") == 0) ? true : false; 804 856 805 857 return rc; … … 1840 1892 { 1841 1893 int rc; 1842 1843 1894 uint32_t uHz; 1844 1895 rc = audioTestObjGetUInt32(phObj, "tone_pcm_hz", &uHz); … … 1860 1911 1861 1912 /** 1862 * Compares two (binary) files. 1863 * 1864 * @returns \c true if equal, or \c false if not. 1865 * @param hFileA File handle to file A to compare. 1866 * @param hFileB File handle to file B to compare file A with. 1867 * @param cbToCompare Number of bytes to compare starting the the both file's 1868 * current position. 1869 */ 1870 static bool audioTestFilesCompareBinary(RTFILE hFileA, RTFILE hFileB, uint64_t cbToCompare) 1871 { 1872 uint8_t auBufA[_32K]; 1873 uint8_t auBufB[_32K]; 1874 1875 int rc = VINF_SUCCESS; 1876 1913 * Structure for keeping file comparison parameters for one file. 1914 */ 1915 typedef struct AUDIOTESTFILECMPPARMS 1916 { 1917 /** File handle to file to compare. */ 1918 RTFILE hFile; 1919 /** Absolute offset (in bytes) to start comparing. 1920 * Ignored when set to 0. */ 1921 uint64_t offStart; 1922 /** Size (in bytes) of area to compare. 1923 * Starts at \a offStart. */ 1924 uint64_t cbSize; 1925 } AUDIOTESTFILECMPPARMS; 1926 /** Pointer to file comparison parameters for one file. */ 1927 typedef AUDIOTESTFILECMPPARMS *PAUDIOTESTFILECMPPARMS; 1928 1929 /** 1930 * Finds differences in two audio test files by binary comparing chunks. 1931 * 1932 * @returns Number of differences. 0 means they are equal (but not necessarily identical). 1933 * @param pCmpA File comparison parameters to file A to compare file B with. 1934 * @param pCmpB File comparison parameters to file B to compare file A with. 1935 * @param pToneParms Tone parameters to use for comparison. 1936 */ 1937 static uint32_t audioTestFilesFindDiffsBinary(PAUDIOTESTFILECMPPARMS pCmpA, PAUDIOTESTFILECMPPARMS pCmpB, 1938 PAUDIOTESTTONEPARMS pToneParms) 1939 { 1940 uint8_t auBufA[_4K]; 1941 uint8_t auBufB[_4K]; 1942 1943 int rc = RTFileSeek(pCmpA->hFile, pCmpA->offStart, RTFILE_SEEK_BEGIN, NULL); 1944 AssertRC(rc); 1945 1946 rc = RTFileSeek(pCmpB->hFile, pCmpB->offStart, RTFILE_SEEK_BEGIN, NULL); 1947 AssertRC(rc); 1948 1949 RT_NOREF(pToneParms); 1950 uint32_t const cbChunkSize = 4; //PDMAudioPropsMilliToBytes(&pToneParms->Props, 5 /* ms */); 1951 1952 uint64_t offCur = 0; 1953 uint64_t offLastDiff = 0; 1954 uint32_t cDiffs = 0; 1955 uint64_t cbToCompare = RT_MIN(pCmpA->cbSize, pCmpB->cbSize); 1877 1956 while (cbToCompare) 1878 1957 { 1879 1958 size_t cbReadA; 1880 rc = RTFileRead( hFileA, auBufA, RT_MIN(cbToCompare, sizeof(auBufA)), &cbReadA);1959 rc = RTFileRead(pCmpA->hFile, auBufA, RT_MIN(cbToCompare, cbChunkSize), &cbReadA); 1881 1960 AssertRCBreak(rc); 1882 1961 size_t cbReadB; 1883 rc = RTFileRead( hFileB, auBufB, RT_MIN(cbToCompare, sizeof(auBufB)), &cbReadB);1962 rc = RTFileRead(pCmpB->hFile, auBufB, RT_MIN(cbToCompare, cbChunkSize), &cbReadB); 1884 1963 AssertRCBreak(rc); 1885 1964 AssertBreakStmt(cbReadA == cbReadB, rc = VERR_INVALID_PARAMETER); /** @todo Find a better rc. */ 1965 1886 1966 if (memcmp(auBufA, auBufB, RT_MIN(cbReadA, cbReadB)) != 0) 1887 return false; 1888 Assert(cbToCompare >= cbReadA); 1967 { 1968 if (offLastDiff == 0) /* No consequitive different chunk? Count as new then. */ 1969 { 1970 cDiffs++; 1971 offLastDiff = offCur; 1972 } 1973 } 1974 else /* Reset and count next difference as new then. */ 1975 { 1976 if (cDiffs) 1977 { 1978 Log2Func(("Chunk A [%RU64-%RU64] vs. chunk B [%RU64-%RU64] (%RU64 bytes)\n", 1979 pCmpA->offStart + offLastDiff, pCmpA->offStart + offCur, 1980 pCmpB->offStart + offLastDiff, pCmpB->offStart + offCur, offCur - offLastDiff)); 1981 } 1982 offLastDiff = 0; 1983 } 1984 1985 AssertBreakStmt(cbToCompare >= cbReadA, VERR_INTERNAL_ERROR); 1889 1986 cbToCompare -= cbReadA; 1890 } 1891 1892 return RT_SUCCESS(rc) && (cbToCompare == 0); 1987 offCur += cbReadA; 1988 } 1989 1990 return cDiffs; 1893 1991 } 1894 1992 … … 1991 2089 } 1992 2090 1993 if (!audioTestFilesCompareBinary(pObjA->File.hFile, pObjB->File.hFile, cbSizeA)) 1994 { 1995 /** @todo Add more sophisticated stuff here. */ 1996 1997 int rc2 = audioTestErrorDescAddInfo(pVerJob->pErr, pVerJob->idxTest, "Files '%s' and '%s' have different content", 1998 pObjA->szName, pObjB->szName); 2091 /** @todo For now we only support comparison of data which do have identical PCM properties! */ 2092 2093 AUDIOTESTTONEPARMS ToneParmsA; 2094 RT_ZERO(ToneParmsA); 2095 ToneParmsA.Props = pVerJob->PCMProps; 2096 2097 AUDIOTESTFILECMPPARMS FileA; 2098 RT_ZERO(FileA); 2099 FileA.hFile = pObjA->File.hFile; 2100 FileA.offStart = audioTestToneFileFind(pObjA->File.hFile, true /* fFindSilence */, 0 /* uOff */, &ToneParmsA); 2101 FileA.cbSize = RT_MIN(audioTestToneFileFind(pObjA->File.hFile, false /* fFindSilence */, FileA.offStart, &ToneParmsA) + 1, 2102 cbSizeA); 2103 2104 AUDIOTESTTONEPARMS ToneParmsB; 2105 RT_ZERO(ToneParmsB); 2106 ToneParmsB.Props = pVerJob->PCMProps; 2107 2108 AUDIOTESTFILECMPPARMS FileB; 2109 RT_ZERO(FileB); 2110 FileB.hFile = pObjB->File.hFile; 2111 FileB.offStart = audioTestToneFileFind(pObjB->File.hFile, true /* fFindSilence */, 0 /* uOff */, &ToneParmsB); 2112 FileB.cbSize = RT_MIN(audioTestToneFileFind(pObjB->File.hFile, false /* fFindSilence */, FileB.offStart, &ToneParmsB), 2113 cbSizeB); 2114 2115 Log2Func(("Test #%RU32\n", pVerJob->idxTest)); 2116 Log2Func(("File A ('%s'): cbOff=%RU64 cbSize=%RU64, cbFileSize=%RU64\n", pObjA->szName, FileA.offStart, FileA.cbSize - FileA.offStart, cbSizeA)); 2117 Log2Func(("File B ('%s'): cbOff=%RU64, cbSize=%RU64, cbFileSize=%RU64\n", pObjB->szName, FileB.offStart, FileB.cbSize - FileB.offStart, cbSizeB)); 2118 2119 uint32_t const cDiffs = audioTestFilesFindDiffsBinary(&FileA, &FileB, &ToneParmsA); 2120 2121 int rc2 = audioTestErrorDescAddInfo(pVerJob->pErr, pVerJob->idxTest, "Files '%s' and '%s' are %s (%RU32 different chunks, threshold is %RU32)", 2122 pObjA->szName, pObjB->szName, cDiffs == 0 ? "equal" : "different", cDiffs, pVerJob->cThresholdDiff); 2123 AssertRC(rc2); 2124 2125 if (cDiffs > pVerJob->cThresholdDiff) 2126 { 2127 rc2 = audioTestErrorDescAddError(pVerJob->pErr, pVerJob->idxTest, "Files '%s' and '%s' do not match", 2128 pObjA->szName, pObjB->szName); 1999 2129 AssertRC(rc2); 2000 2130 } … … 2090 2220 VerJob.pSetB = pSetB; 2091 2221 VerJob.fKeepGoing = true; /** @todo Make this configurable. */ 2222 2223 /** @todo For now we're very strict and consider any diff as being erroneous. 2224 * We might want / need to change this depending on the test boxes lateron. */ 2225 VerJob.cThresholdDiff = 0; 2092 2226 2093 2227 PAUDIOTESTVERIFYJOB pVerJob = &VerJob;
Note:
See TracChangeset
for help on using the changeset viewer.