VirtualBox

Changeset 89014 in vbox for trunk


Ignore:
Timestamp:
May 12, 2021 2:33:19 PM (4 years ago)
Author:
vboxsync
Message:

Audio/ValKit: More work on test tone execution. bugref:10008

Location:
trunk/src/VBox
Files:
3 edited

Legend:

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

    r89010 r89014  
    223223
    224224    pToneParams->msPrequel      = RTRandU32Ex(0, RT_MS_5SEC);
    225     pToneParams->msDuration     = RTRandU32Ex(0, RT_MS_30SEC); /** @todo Probably a bit too long, but let's see. */
     225    pToneParams->msDuration     = RTRandU32Ex(0, RT_MS_10SEC); /** @todo Probably a bit too long, but let's see. */
    226226    pToneParams->msSequel       = RTRandU32Ex(0, RT_MS_5SEC);
    227227    pToneParams->uVolumePercent = RTRandU32Ex(0, 100);
  • trunk/src/VBox/Devices/Audio/AudioTest.h

    r89010 r89014  
    8585
    8686/**
     87 * Structure for keeping an audio test audio stream.
     88 */
     89typedef struct AUDIOTESTSTREAM
     90{
     91    /** Created flag to avoid double destruction in backends. */
     92    bool                  fCreated;
     93    /** Backend-specific stream data. */
     94    PDMAUDIOBACKENDSTREAM Backend;
     95} AUDIOTESTSTREAM;
     96/** Pointer to audio test stream. */
     97typedef AUDIOTESTSTREAM *PAUDIOTESTSTREAM;
     98
     99/**
    87100 * Enumeration for the test set mode.
    88101 */
     
    98111    AUDIOTESTSETMODE_32BIT_HACK = 0x7fffffff
    99112} AUDIOTESTSETMODE;
     113
     114/**
     115 * Enumeration to specify an audio test type.
     116 */
     117typedef enum AUDIOTESTTYPE
     118{
     119    /** Invalid test type, do not use. */
     120    AUDIOTESTTYPE_INVALID = 0,
     121    /** Play a test tone. */
     122    AUDIOTESTTYPE_TESTTONE
     123} AUDIOTESTTYPE;
     124
     125/**
     126 * Audio test request data.
     127 */
     128typedef struct AUDIOTESTPARMS
     129{
     130    /** Specifies the test to run. */
     131    uint32_t                idxTest;
     132    /** How many iterations the test should be executed. */
     133    uint32_t                cIterations;
     134    /** Audio device to use. */
     135    PDMAUDIOHOSTDEV         Dev;
     136    /** How much to delay (wait, in ms) the test being executed. */
     137    RTMSINTERVAL            msDelay;
     138    /** The test direction.. */
     139    PDMAUDIODIR             enmDir;
     140    /** The test type. */
     141    AUDIOTESTTYPE           enmType;
     142    /** Union for test type-specific data. */
     143    union
     144    {
     145        AUDIOTESTTONEPARMS  TestTone;
     146    };
     147} AUDIOTESTPARMS;
     148/** Pointer to a test parameter structure. */
     149typedef AUDIOTESTPARMS *PAUDIOTESTPARMS;
    100150
    101151/**
  • trunk/src/VBox/ValidationKit/utils/audio/vkat.cpp

    r89010 r89014  
    3636#include <iprt/message.h>
    3737#include <iprt/process.h>
     38#include <iprt/rand.h>
    3839#include <iprt/stream.h>
    3940#include <iprt/string.h>
     
    6869*   Structures and Typedefs                                                                                                      *
    6970*********************************************************************************************************************************/
    70 /**
    71  * Audio test request data.
    72  */
    73 typedef struct AUDIOTESTPARMS
    74 {
    75     /** Specifies the test to run. */
    76     uint32_t                idxTest;
    77     /** How many iterations the test should be executed. */
    78     uint32_t                cIterations;
    79     /** Audio device to use. */
    80     PDMAUDIOHOSTDEV         Dev;
    81     /** How much to delay (wait, in ms) the test being executed. */
    82     RTMSINTERVAL            msDelay;
    83     /** The test type. */
    84     PDMAUDIODIR             enmDir;
    85     union
    86     {
    87         AUDIOTESTTONEPARMS  ToneParms;
    88     };
    89 } AUDIOTESTPARMS;
    90 /** Pointer to a test parameter structure. */
    91 typedef AUDIOTESTPARMS *PAUDIOTESTPARMS;
    9271
    9372/**
     
    125104    /** The current (last) audio device enumeration to use. */
    126105    PDMAUDIOHOSTENUM      DevEnm;
    127     PDMAUDIOBACKENDSTREAM aStreams[AUDIOTESTENV_MAX_STREAMS];
     106    AUDIOTESTSTREAM      aStreams[AUDIOTESTENV_MAX_STREAMS];
    128107    /** The audio test set to use. */
    129108    AUDIOTESTSET          Set;
     
    156135*********************************************************************************************************************************/
    157136static int audioTestCombineParms(PAUDIOTESTPARMS pBaseParms, PAUDIOTESTPARMS pOverrideParms);
    158 static int audioTestPlayTone(PAUDIOTESTENV pTstEnv, PPDMAUDIOBACKENDSTREAM pStream, PAUDIOTESTTONEPARMS pParms);
    159 
     137static int audioTestPlayTone(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PAUDIOTESTTONEPARMS pParms);
     138static int audioTestStreamDestroy(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream);
    160139
    161140/*********************************************************************************************************************************
     
    234213
    235214/*********************************************************************************************************************************
    236 *   Test callbacks                                                                                                               *
    237 *********************************************************************************************************************************/
    238 
    239 /**
    240  * Setup callback for playing an output tone.
    241  *
    242  * @copydoc FNAUDIOTESTSETUP
    243  */
    244 static DECLCALLBACK(int) audioTestPlayToneSetup(PAUDIOTESTENV pTstEnv, PAUDIOTESTDESC pTstDesc, PAUDIOTESTPARMS pTstParmsAcq, void **ppvCtx)
    245 {
    246     RT_NOREF(pTstEnv, pTstDesc, ppvCtx);
    247 
    248     PDMAudioPropsInit(&pTstParmsAcq->ToneParms.Props, 16 /* bit */ / 8, true /* fSigned */, 2 /* Channels */, 44100 /* Hz */);
    249 
    250     AudioTestToneParamsInitRandom(&pTstParmsAcq->ToneParms, &pTstParmsAcq->ToneParms.Props);
    251 
    252     return VINF_SUCCESS;
    253 }
    254 
    255 static DECLCALLBACK(int) audioTestPlayToneExec(PAUDIOTESTENV pTstEnv, void *pvCtx, PAUDIOTESTPARMS pTstParms)
    256 {
    257     RT_NOREF(pvCtx);
    258 
    259     return audioTestPlayTone(pTstEnv, &pTstEnv->aStreams[0], &pTstParms->ToneParms);
    260 }
    261 
    262 static DECLCALLBACK(int) audioTestPlayToneDestroy(PAUDIOTESTENV pTstEnv, void *pvCtx)
    263 {
    264     RT_NOREF(pTstEnv, pvCtx);
    265 
    266     return VINF_SUCCESS;
    267 }
    268 
    269 
    270 /*********************************************************************************************************************************
    271215*   Implementation                                                                                                               *
    272216*********************************************************************************************************************************/
     
    302246    PDMAudioHostEnumDelete(&pTstEnv->DevEnm);
    303247
     248    for (unsigned i = 0; i < RT_ELEMENTS(pTstEnv->aStreams); i++)
     249    {
     250        int rc2 = audioTestStreamDestroy(pTstEnv, &pTstEnv->aStreams[i]);
     251        if (RT_FAILURE(rc2))
     252            RTTestFailed(g_hTest, "Stream destruction for stream #%u failed with %Rrc\n", i, rc2);
     253    }
     254
    304255    AudioTestSetDestroy(&pTstEnv->Set);
    305256}
     
    329280    return;
    330281}
    331 
    332 static AUDIOTESTDESC g_aTests[] =
    333 {
    334     /* pszTest      fExcluded      pfnSetup */
    335     { "PlayTone",   false,         audioTestPlayToneSetup,       audioTestPlayToneExec,      audioTestPlayToneDestroy }
    336 };
    337 
    338282
    339283/**
     
    550494}
    551495
    552 static int audioTestPlayTone(PAUDIOTESTENV pTstEnv, PPDMAUDIOBACKENDSTREAM pStream, PAUDIOTESTTONEPARMS pParms)
    553 {
    554     PDMAUDIOSTREAMCFG CfgReq;
     496static int audioTestStreamCreate(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PPDMAUDIOSTREAMCFG pCfg)
     497{
    555498    PDMAUDIOSTREAMCFG CfgAcq;
    556499
    557     int rc = PDMAudioStrmCfgInitWithProps(&CfgReq, &pParms->Props);
     500    int rc = PDMAudioStrmCfgCopy(&CfgAcq, pCfg);
    558501    AssertRC(rc); /* Cannot fail. */
    559502
    560     CfgReq.enmDir      = PDMAUDIODIR_OUT;
    561     CfgReq.u.enmDst    = PDMAUDIOPLAYBACKDST_FRONT;
    562     CfgReq.enmLayout   = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
    563 
    564     rc = PDMAudioStrmCfgCopy(&CfgAcq, &CfgReq);
    565     AssertRC(rc); /* Ditto. */
    566 
    567     rc = pTstEnv->pDrvAudio->pfnStreamCreate(pTstEnv->pDrvAudio, pStream, &CfgReq, &CfgAcq);
     503    rc = pTstEnv->pDrvAudio->pfnStreamCreate(pTstEnv->pDrvAudio, &pStream->Backend, pCfg, &CfgAcq);
    568504    if (RT_FAILURE(rc))
    569505        return rc;
     
    571507    /* Do the async init in a synchronous way for now here. */
    572508    if (rc == VINF_AUDIO_STREAM_ASYNC_INIT_NEEDED)
    573         rc = pTstEnv->pDrvAudio->pfnStreamInitAsync(pTstEnv->pDrvAudio, pStream, false /* fDestroyed */);
    574 
     509        rc = pTstEnv->pDrvAudio->pfnStreamInitAsync(pTstEnv->pDrvAudio, &pStream->Backend, false /* fDestroyed */);
     510
     511    if (RT_SUCCESS(rc))
     512        pStream->fCreated = true;
     513
     514    return rc;
     515}
     516
     517static int audioTestStreamDestroy(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream)
     518{
     519    if (!pStream)
     520        return VINF_SUCCESS;
     521
     522  if (!pStream->fCreated)
     523        return VINF_SUCCESS;
     524
     525    /** @todo Anything else to do here, e.g. test if there are left over samples or some such? */
     526
     527    int rc = pTstEnv->pDrvAudio->pfnStreamDestroy(pTstEnv->pDrvAudio, &pStream->Backend);
     528    if (RT_SUCCESS(rc))
     529        RT_BZERO(pStream, sizeof(PDMAUDIOBACKENDSTREAM));
     530
     531    return rc;
     532}
     533
     534static int audioTestCreateStreamDefaultOut(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PPDMAUDIOPCMPROPS pProps)
     535{
     536    PDMAUDIOSTREAMCFG Cfg;
     537    int rc = PDMAudioStrmCfgInitWithProps(&Cfg, pProps);
     538    AssertRC(rc); /* Cannot fail. */
     539
     540    Cfg.enmDir      = PDMAUDIODIR_OUT;
     541    Cfg.u.enmDst    = PDMAUDIOPLAYBACKDST_FRONT;
     542    Cfg.enmLayout   = PDMAUDIOSTREAMLAYOUT_NON_INTERLEAVED;
     543
     544    return audioTestStreamCreate(pTstEnv, pStream, &Cfg);
     545}
     546
     547static int audioTestPlayTone(PAUDIOTESTENV pTstEnv, PAUDIOTESTSTREAM pStream, PAUDIOTESTTONEPARMS pParms)
     548{
    575549    AUDIOTESTTONE TstTone;
    576550    AudioTestToneInitRandom(&TstTone, &pParms->Props);
    577551
    578     PDMHOSTAUDIOSTREAMSTATE enmState = pTstEnv->pDrvAudio->pfnStreamGetState(pTstEnv->pDrvAudio, pStream);
     552    RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Playing test tone (freq %RU16, %RU32ms)\n", TstTone.rdFreqHz, pParms->msDuration);
     553
     554    int rc;
     555
     556    PDMHOSTAUDIOSTREAMSTATE enmState = pTstEnv->pDrvAudio->pfnStreamGetState(pTstEnv->pDrvAudio, &pStream->Backend);
    579557    if (enmState == PDMHOSTAUDIOSTREAMSTATE_OKAY)
    580558    {
     
    583561
    584562        const uint64_t tsStartMs     = RTTimeMilliTS();
    585         const unsigned cSchedulingMs = 10;
    586         const uint32_t cbPerMs       = PDMAudioPropsMilliToBytes(&CfgAcq.Props, cSchedulingMs);
     563        const uint16_t cSchedulingMs = RTRandU32Ex(10, 80); /* Chose a random scheduling (in ms). */
     564        const uint32_t cbPerMs       = PDMAudioPropsMilliToBytes(&pParms->Props, cSchedulingMs);
    587565
    588566        do
     
    592570            {
    593571                uint32_t cbWritten;
    594                 rc = pTstEnv->pDrvAudio->pfnStreamPlay(pTstEnv->pDrvAudio, pStream, abBuf, cbBuf, &cbWritten);
     572                rc = pTstEnv->pDrvAudio->pfnStreamPlay(pTstEnv->pDrvAudio, &pStream->Backend, abBuf, cbBuf, &cbWritten);
    595573            }
    596574
     
    602580        } while (RT_SUCCESS(rc));
    603581    }
    604 
    605     int rc2 = pTstEnv->pDrvAudio->pfnStreamDestroy(pTstEnv->pDrvAudio, pStream);
    606     if (RT_SUCCESS(rc))
    607         rc = rc2;
    608 
    609     return VINF_SUCCESS;
     582    else
     583        rc = VERR_AUDIO_STREAM_NOT_READY;
     584
     585    return rc;
    610586}
    611587
     
    626602    return VERR_NOT_IMPLEMENTED;
    627603}
     604
     605
     606/*********************************************************************************************************************************
     607*   Test callbacks                                                                                                               *
     608*********************************************************************************************************************************/
     609
     610/**
     611 * @copydoc FNAUDIOTESTSETUP
     612 */
     613static DECLCALLBACK(int) audioTestPlayToneSetup(PAUDIOTESTENV pTstEnv, PAUDIOTESTDESC pTstDesc, PAUDIOTESTPARMS pTstParmsAcq, void **ppvCtx)
     614{
     615    RT_NOREF(pTstEnv, pTstDesc, ppvCtx);
     616
     617    PDMAudioPropsInit(&pTstParmsAcq->TestTone.Props, 16 /* bit */ / 8, true /* fSigned */, 2 /* Channels */, 44100 /* Hz */);
     618
     619    pTstParmsAcq->cIterations = RTRandU32Ex(1, 10);
     620
     621    return VINF_SUCCESS;
     622}
     623
     624/**
     625 * @copydoc FNAUDIOTESTEXEC
     626 */
     627static DECLCALLBACK(int) audioTestPlayToneExec(PAUDIOTESTENV pTstEnv, void *pvCtx, PAUDIOTESTPARMS pTstParms)
     628{
     629    RT_NOREF(pvCtx);
     630
     631    int rc;
     632
     633    PAUDIOTESTSTREAM pStream = &pTstEnv->aStreams[0];
     634
     635    for (uint32_t i = 0; i < pTstParms->cIterations; i++)
     636    {
     637        AudioTestToneParamsInitRandom(&pTstParms->TestTone, &pTstParms->TestTone.Props);
     638        rc = audioTestCreateStreamDefaultOut(pTstEnv, pStream, &pTstParms->TestTone.Props);
     639        if (RT_SUCCESS(rc))
     640            rc = audioTestPlayTone(pTstEnv, pStream, &pTstParms->TestTone);
     641
     642        int rc2 = audioTestStreamDestroy(pTstEnv, pStream);
     643        if (RT_SUCCESS(rc))
     644            rc = rc2;
     645    }
     646
     647    return rc;
     648}
     649
     650/**
     651 * @copydoc FNAUDIOTESTDESTROY
     652 */
     653static DECLCALLBACK(int) audioTestPlayToneDestroy(PAUDIOTESTENV pTstEnv, void *pvCtx)
     654{
     655    RT_NOREF(pTstEnv, pvCtx);
     656
     657    return VINF_SUCCESS;
     658}
     659
     660
     661/*********************************************************************************************************************************
     662*   Test execution                                                                                                               *
     663*********************************************************************************************************************************/
     664
     665static AUDIOTESTDESC g_aTests[] =
     666{
     667    /* pszTest      fExcluded      pfnSetup */
     668    { "PlayTone",   false,         audioTestPlayToneSetup,       audioTestPlayToneExec,      audioTestPlayToneDestroy }
     669};
    628670
    629671/**
     
    660702        rc = pTstDesc->pfnSetup(pTstEnv, pTstDesc, &TstParms, &pvCtx);
    661703        if (RT_FAILURE(rc))
     704        {
     705            RTTestFailed(g_hTest, "Test setup failed\n");
    662706            return rc;
     707        }
    663708    }
    664709
    665710    audioTestCombineParms(&TstParms, pOverrideParms);
     711
     712    RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "Test #%u: %RU32 iterations\n", uSeq, TstParms.cIterations);
    666713
    667714    if (strlen(TstParms.Dev.szName)) /** @todo Refine this check. */
     
    678725        if (RT_SUCCESS(rc))
    679726            rc = rc2;
     727
     728        if (RT_FAILURE(rc2))
     729            RTTestFailed(g_hTest, "Test destruction failed\n");
    680730    }
    681731
     
    836886            case VKAT_TEST_OPT_PCM_BIT:
    837887            {
    838                 TstCust.ToneParms.Props.cbSampleX = ValueUnion.u8 / 8 /* bit */;
     888                TstCust.TestTone.Props.cbSampleX = ValueUnion.u8 / 8 /* bit */;
    839889                break;
    840890            }
     
    842892            case VKAT_TEST_OPT_PCM_CHAN:
    843893            {
    844                 TstCust.ToneParms.Props.cChannelsX = ValueUnion.u8;
     894                TstCust.TestTone.Props.cChannelsX = ValueUnion.u8;
    845895                break;
    846896            }
     
    848898            case VKAT_TEST_OPT_PCM_HZ:
    849899            {
    850                 TstCust.ToneParms.Props.uHz = ValueUnion.u32;
     900                TstCust.TestTone.Props.uHz = ValueUnion.u32;
    851901                break;
    852902            }
     
    854904            case VKAT_TEST_OPT_PCM_SIGNED:
    855905            {
    856                 TstCust.ToneParms.Props.fSigned = ValueUnion.f;
     906                TstCust.TestTone.Props.fSigned = ValueUnion.f;
    857907                break;
    858908            }
     
    866916            case VKAT_TEST_OPT_VOL:
    867917            {
    868                 TstCust.ToneParms.uVolumePercent = ValueUnion.u8;
     918                TstCust.TestTone.uVolumePercent = ValueUnion.u8;
    869919                break;
    870920            }
Note: See TracChangeset for help on using the changeset viewer.

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