VirtualBox

Changeset 89051 in vbox for trunk/src/VBox/Devices/Audio


Ignore:
Timestamp:
May 14, 2021 6:58:11 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
144391
Message:

Audio/ValKit: More code for VKAT audio test set generation; initial implementation now can pack up tests sets as .tar.gz files. bugref:10008

Location:
trunk/src/VBox/Devices/Audio
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/AudioTest.cpp

    r89045 r89051  
    3434#include <iprt/uuid.h>
    3535#include <iprt/vfs.h>
     36#include <iprt/zip.h>
    3637
    3738#define _USE_MATH_DEFINES
     
    110111 * @param   pcbWritten          How many bytes were written on success.
    111112 */
    112 int AudioTestToneWrite(PAUDIOTESTTONE pTone, void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
     113int AudioTestToneGenerate(PAUDIOTESTTONE pTone, void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten)
    113114{
    114115    /*
    115      * Clear the buffer first so we don't need to thing about additional channels.
     116     * Clear the buffer first so we don't need to think about additional channels.
    116117     */
    117     uint32_t cFrames = PDMAudioPropsBytesToFrames(&pTone->Props, cbBuf);
     118    uint32_t cFrames   = PDMAudioPropsBytesToFrames(&pTone->Props, cbBuf);
     119
     120    /* Input cbBuf not necessarily is aligned to the frames, so re-calculate it. */
     121    const uint32_t cbToWrite = PDMAudioPropsFramesToBytes(&pTone->Props, cFrames);
     122
    118123    PDMAudioPropsClearBuffer(&pTone->Props, pvBuf, cbBuf, cFrames);
    119124
     
    206211
    207212    if (pcbWritten)
    208         *pcbWritten = PDMAudioPropsFramesToBytes(&pTone->Props, cFrames);
     213        *pcbWritten = cbToWrite;
    209214
    210215    return VINF_SUCCESS;
     
    225230
    226231    pToneParams->msPrequel      = RTRandU32Ex(0, RT_MS_5SEC);
     232#ifdef DEBUG_andy
     233    pToneParams->msDuration     = RTRandU32Ex(0, RT_MS_1SEC);
     234#else
    227235    pToneParams->msDuration     = RTRandU32Ex(0, RT_MS_10SEC); /** @todo Probably a bit too long, but let's see. */
     236#endif
    228237    pToneParams->msSequel       = RTRandU32Ex(0, RT_MS_5SEC);
    229238    pToneParams->uVolumePercent = RTRandU32Ex(0, 100);
     
    246255int AudioTestPathCreate(char *pszPath, size_t cbPath, const char *pszTag)
    247256{
     257    AssertReturn(strlen(pszTag) <= AUDIOTEST_TAG_MAX, VERR_INVALID_PARAMETER);
     258
    248259    int rc;
    249260
     
    263274    }
    264275
    265     char szName[128];
    266     if (RTStrPrintf2(szName, sizeof(szName), "%s%s", AUDIOTEST_PATH_PREFIX_STR, szTag) < 0)
     276    char szName[RT_ELEMENTS(AUDIOTEST_PATH_PREFIX_STR) + AUDIOTEST_TAG_MAX + 4];
     277    if (RTStrPrintf2(szName, sizeof(szName), "%s-%s", AUDIOTEST_PATH_PREFIX_STR, szTag) < 0)
    267278        AssertFailedReturn(VERR_BUFFER_OVERFLOW);
    268279
     
    365376{
    366377    pSet->f.hFile = NIL_RTFILE;
     378
     379    RTListInit(&pSet->lstObj);
    367380}
    368381
     
    510523int AudioTestPathCreateTemp(char *pszPath, size_t cbPath, const char *pszTag)
    511524{
     525    AssertReturn(strlen(pszTag) <= AUDIOTEST_TAG_MAX, VERR_INVALID_PARAMETER);
     526
    512527    char szPath[RTPATH_MAX];
    513528
     
    531546int AudioTestSetCreate(PAUDIOTESTSET pSet, const char *pszPath, const char *pszTag)
    532547{
     548    AssertReturn(strlen(pszTag) <= AUDIOTEST_TAG_MAX, VERR_INVALID_PARAMETER);
     549
    533550    int rc;
    534551
     
    596613
    597614        pSet->enmMode = AUDIOTESTSETMODE_TEST;
     615
     616        rc = RTStrCopy(pSet->szTag, sizeof(pSet->szTag), pszTag);
     617        AssertRCReturn(rc, rc);
    598618    }
    599619
     
    604624 * Destroys a test set.
    605625 *
     626 * @returns VBox status code.
    606627 * @param   pSet                Test set to destroy.
    607628 */
    608 void AudioTestSetDestroy(PAUDIOTESTSET pSet)
     629int AudioTestSetDestroy(PAUDIOTESTSET pSet)
    609630{
    610631    if (!pSet)
    611         return;
     632        return VINF_SUCCESS;
     633
     634    int rc = VINF_SUCCESS;
     635
     636    PAUDIOTESTOBJ pObj, pObjNext;
     637    RTListForEachSafe(&pSet->lstObj, pObj, pObjNext, AUDIOTESTOBJ, Node)
     638    {
     639        rc = AudioTestSetObjClose(pObj);
     640        if (RT_SUCCESS(rc))
     641        {
     642            RTListNodeRemove(&pObj->Node);
     643            RTMemFree(pObj);
     644
     645            Assert(pSet->cObj);
     646            pSet->cObj--;
     647        }
     648        else
     649            break;
     650    }
     651
     652    if (RT_FAILURE(rc))
     653        return rc;
     654
     655    Assert(pSet->cObj == 0);
    612656
    613657    if (RTFileIsValid(pSet->f.hFile))
     
    616660        pSet->f.hFile = NIL_RTFILE;
    617661    }
     662
     663    return rc;
    618664}
    619665
     
    661707
    662708/**
     709 * Physically wipes all related test set files off the disk.
     710 *
     711 * @param   pSet                Test set to wipe.
     712 */
     713void AudioTestSetWipe(PAUDIOTESTSET pSet)
     714{
     715    RT_NOREF(pSet);
     716}
     717
     718/**
     719 * Creates and registers a new audio test object to a test set.
     720 *
     721 * @returns VBox status code.
     722 * @param   pSet                Test set to create and register new object for.
     723 * @param   pszName             Name of new object to create.
     724 * @param   ppObj               Where to return the pointer to the newly created object on success.
     725 */
     726int AudioTestSetObjCreateAndRegister(PAUDIOTESTSET pSet, const char *pszName, PAUDIOTESTOBJ *ppObj)
     727{
     728    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
     729
     730    PAUDIOTESTOBJ pObj = (PAUDIOTESTOBJ)RTMemAlloc(sizeof(AUDIOTESTOBJ));
     731    AssertPtrReturn(pObj, VERR_NO_MEMORY);
     732
     733    int rc = RTStrPrintf(pObj->szName, sizeof(pObj->szName), "%04RU32-%s", pSet->cObj, pszName);
     734    AssertRCReturn(rc, rc);
     735
     736    /** @todo Generalize this function more once we have more object types. */
     737
     738    char szFilePath[RTPATH_MAX];
     739    rc = RTPathJoin(szFilePath, sizeof(szFilePath), pSet->szPathAbs, pObj->szName);
     740    AssertRCReturn(rc, rc);
     741
     742    rc = RTFileOpen(&pObj->File.hFile, szFilePath, RTFILE_O_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE);
     743    if (RT_SUCCESS(rc))
     744    {
     745        pObj->enmType = AUDIOTESTOBJTYPE_FILE;
     746
     747        RTListAppend(&pSet->lstObj, &pObj->Node);
     748        pSet->cObj++;
     749
     750        *ppObj = pObj;
     751    }
     752
     753    if (RT_FAILURE(rc))
     754        RTMemFree(pObj);
     755
     756    return rc;
     757}
     758
     759/**
     760 * Writes to a created audio test object.
     761 *
     762 * @returns VBox status code.
     763 * @param   pObj                Audio test object to write to.
     764 */
     765int AudioTestSetObjWrite(PAUDIOTESTOBJ pObj, void *pvBuf, size_t cbBuf)
     766{
     767    /** @todo Generalize this function more once we have more object types. */
     768    AssertReturn(pObj->enmType == AUDIOTESTOBJTYPE_FILE, VERR_INVALID_PARAMETER);
     769
     770    return RTFileWrite(pObj->File.hFile, pvBuf, cbBuf, NULL);
     771}
     772
     773/**
     774 * Closes an opened audio test object.
     775 *
     776 * @returns VBox status code.
     777 * @param   pObj                Audio test object to close.
     778 */
     779int AudioTestSetObjClose(PAUDIOTESTOBJ pObj)
     780{
     781    if (!pObj)
     782        return VINF_SUCCESS;
     783
     784    /** @todo Generalize this function more once we have more object types. */
     785    AssertReturn(pObj->enmType == AUDIOTESTOBJTYPE_FILE, VERR_INVALID_PARAMETER);
     786
     787    int rc = VINF_SUCCESS;
     788
     789    if (RTFileIsValid(pObj->File.hFile))
     790    {
     791        rc = RTFileClose(pObj->File.hFile);
     792        pObj->File.hFile = NIL_RTFILE;
     793    }
     794
     795    return rc;
     796}
     797
     798/**
    663799 * Packs an audio test so that it's ready for transmission.
    664800 *
    665801 * @returns VBox status code.
    666802 * @param   pSet                Test set to pack.
    667  * @param   pszOutDir           Where to store the packed test set.
    668  */
    669 int AudioTestSetPack(PAUDIOTESTSET pSet, const char *pszOutDir)
    670 {
    671     RT_NOREF(pSet, pszOutDir);
    672 
     803 * @param   pszOutDir           Directory where to store the packed test set.
     804 * @param   pszFileName         Where to return the final name of the packed test set. Optional and can be NULL.
     805 * @param   cbFileName          Size (in bytes) of \a pszFileName.
     806 */
     807int AudioTestSetPack(PAUDIOTESTSET pSet, const char *pszOutDir, char *pszFileName, size_t cbFileName)
     808{
     809    AssertReturn(!pszFileName || cbFileName, VERR_INVALID_PARAMETER);
    673810    AssertReturn(audioTestManifestIsOpen(pSet), VERR_WRONG_ORDER);
    674     // RTZipTarCmd()
    675 
    676     return VERR_NOT_IMPLEMENTED;
     811
     812    /** @todo Check and deny if \a pszOutDir is part of the set's path. */
     813
     814    char szOutName[RT_ELEMENTS(AUDIOTEST_PATH_PREFIX_STR) + AUDIOTEST_TAG_MAX + 16];
     815    int rc = RTStrPrintf(szOutName, sizeof(szOutName), "%s-%s.tar.gz", AUDIOTEST_PATH_PREFIX_STR, pSet->szTag);
     816    AssertRCReturn(rc, rc);
     817
     818    char szOutPath[RTPATH_MAX];
     819    rc = RTPathJoin(szOutPath, sizeof(szOutPath), pszOutDir, szOutName);
     820    AssertRCReturn(rc, rc);
     821
     822    const char *apszArgs[10];
     823    unsigned    cArgs = 0;
     824
     825    apszArgs[cArgs++] = "AudioTest";
     826    apszArgs[cArgs++] = "--create";
     827    apszArgs[cArgs++] = "--gzip";
     828    apszArgs[cArgs++] = "--directory";
     829    apszArgs[cArgs++] = pSet->szPathAbs;
     830    apszArgs[cArgs++] = "--file";
     831    apszArgs[cArgs++] = szOutPath;
     832    apszArgs[cArgs++] = ".";
     833
     834    RTEXITCODE rcExit = RTZipTarCmd(cArgs, (char **)apszArgs);
     835    if (rcExit != RTEXITCODE_SUCCESS)
     836        rc = VERR_GENERAL_FAILURE; /** @todo Fudge! */
     837
     838    if (RT_SUCCESS(rc))
     839    {
     840        if (pszFileName)
     841            rc = RTStrCopy(pszFileName, cbFileName, szOutPath);
     842    }
     843
     844    return rc;
    677845}
    678846
  • trunk/src/VBox/Devices/Audio/AudioTest.h

    r89043 r89051  
    2424#endif
    2525
     26/** @todo Some stuff here can be private-only to the implementation. */
     27
     28/** Maximum length in characters an audio test tag can have. */
     29#define AUDIOTEST_TAG_MAX          64
     30/** Maximum length in characters a single audio test error description can have. */
     31#define AUDIOTEST_ERROR_DESC_MAX   128
    2632/** Prefix for audio test (set) directories. */
    27 #define AUDIOTEST_PATH_PREFIX_STR "audio-test-"
     33#define AUDIOTEST_PATH_PREFIX_STR "vkat"
    2834
    2935/**
     
    131137typedef struct AUDIOTESTPARMS
    132138{
    133     /** Specifies the test to run. */
    134     uint32_t                idxTest;
     139    /** Specifies the current test iteration. */
     140    uint32_t                idxCurrent;
    135141    /** How many iterations the test should be executed. */
    136142    uint32_t                cIterations;
     
    152158typedef AUDIOTESTPARMS *PAUDIOTESTPARMS;
    153159
     160typedef enum AUDIOTESTOBJTYPE
     161{
     162    AUDIOTESTOBJTYPE_UNKNOWN = 0,
     163    AUDIOTESTOBJTYPE_FILE,
     164    /** The usual 32-bit hack. */
     165    AUDIOTESTOBJTYPE_32BIT_HACK = 0x7fffffff
     166} AUDIOTESTOBJTYPE;
     167
     168typedef struct AUDIOTESTOBJFILE
     169{
     170    RTFILE hFile;
     171} AUDIOTESTOBJFILE;
     172
     173typedef struct AUDIOTESTOBJ
     174{
     175    RTLISTNODE           Node;
     176    char                 szName[64];
     177    AUDIOTESTOBJTYPE     enmType;
     178    union
     179    {
     180        AUDIOTESTOBJFILE File;
     181    };
     182} AUDIOTESTOBJ;
     183/** Pointer to an audio test object. */
     184typedef AUDIOTESTOBJ *PAUDIOTESTOBJ;
     185
    154186/**
    155187 * Structure specifying an audio test set.
     
    157189typedef struct AUDIOTESTSET
    158190{
     191    /** The set's tag. */
     192    char             szTag[AUDIOTEST_TAG_MAX];
    159193    /** Absolute path where to store the test audio data. */
    160194    char             szPathAbs[RTPATH_MAX];
     
    166200        RTINIFILE    hIniFile;
    167201    } f;
     202    uint32_t         cObj;
     203    RTLISTANCHOR     lstObj;
    168204} AUDIOTESTSET;
    169205/** Pointer to an audio test set. */
     
    180216    int              rc;
    181217    /** Actual error description. */
    182     char             szDesc[128];
     218    char             szDesc[AUDIOTEST_ERROR_DESC_MAX];
    183219} AUDIOTESTERRORENTRY;
    184220/** Pointer to an audio test error description. */
     
    201237
    202238double AudioTestToneInitRandom(PAUDIOTESTTONE pTone, PPDMAUDIOPCMPROPS pProps);
    203 int    AudioTestToneWrite(PAUDIOTESTTONE pTone, void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten);
     239int    AudioTestToneGenerate(PAUDIOTESTTONE pTone, void *pvBuf, uint32_t cbBuf, uint32_t *pcbWritten);
    204240
    205241int    AudioTestToneParamsInitRandom(PAUDIOTESTTONEPARMS pToneParams, PPDMAUDIOPCMPROPS pProps);
     
    208244int    AudioTestPathCreate(char *pszPath, size_t cbPath, const char *pszUUID);
    209245
     246int    AudioTestSetObjCreateAndRegister(PAUDIOTESTSET pSet, const char *pszName, PAUDIOTESTOBJ *ppObj);
     247int    AudioTestSetObjWrite(PAUDIOTESTOBJ pObj, void *pvBuf, size_t cbBuf);
     248int    AudioTestSetObjClose(PAUDIOTESTOBJ pObj);
     249
    210250int    AudioTestSetCreate(PAUDIOTESTSET pSet, const char *pszPath, const char *pszTag);
    211 void   AudioTestSetDestroy(PAUDIOTESTSET pSet);
     251int    AudioTestSetDestroy(PAUDIOTESTSET pSet);
    212252int    AudioTestSetOpen(PAUDIOTESTSET pSet, const char *pszPath);
    213253void   AudioTestSetClose(PAUDIOTESTSET pSet);
    214 int    AudioTestSetPack(PAUDIOTESTSET pSet, const char *pszOutDir);
     254void   AudioTestSetWipe(PAUDIOTESTSET pSet);
     255int    AudioTestSetPack(PAUDIOTESTSET pSet, const char *pszOutDir, char *pszFileName, size_t cbFileName);
    215256int    AudioTestSetUnpack(const char *pszFile, const char *pszOutDir);
    216257int    AudioTestSetVerify(PAUDIOTESTSET pSet, const char *pszTag, PAUDIOTESTERRORDESC pErrDesc);
  • trunk/src/VBox/Devices/Audio/DrvHostAudioDebug.cpp

    r88923 r89051  
    264264
    265265    uint32_t cbWritten;
    266     int rc = AudioTestToneWrite(&pStreamDbg->In, pvBuf, cbBuf, &cbWritten);
     266    int rc = AudioTestToneGenerate(&pStreamDbg->In, pvBuf, cbBuf, &cbWritten);
    267267    if (RT_SUCCESS(rc))
    268268    {
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette