VirtualBox

Changeset 89259 in vbox for trunk/src/VBox


Ignore:
Timestamp:
May 25, 2021 9:58:10 AM (4 years ago)
Author:
vboxsync
Message:

ValKit/AudioTest: Added device selection to play. bugref:10008

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/utils/audio/vkat.cpp

    r89231 r89259  
    406406}
    407407
     408VMMR3DECL(void) MMR3HeapFree(void *pv)
     409{
     410    /* counterpart to CFGMR3QueryStringAlloc */
     411    RTStrFree((char *)pv);
     412}
     413
    408414VMMR3DECL(int) CFGMR3QueryStringDef(PCFGMNODE pNode, const char *pszName, char *pszString, size_t cchString, const char *pszDef)
    409415{
     
    819825    }
    820826
     827    return rc;
     828}
     829
     830/**
     831 * Wrapper around PDMIHOSTAUDIO::pfnSetDevice.
     832 */
     833static int audioTestDriverStackSetDevice(PAUDIOTESTDRVSTACK pDrvStack, PDMAUDIODIR enmDir, const char *pszDevId)
     834{
     835    int rc;
     836    if (   pDrvStack->pIHostAudio
     837        && pDrvStack->pIHostAudio->pfnSetDevice)
     838        rc = pDrvStack->pIHostAudio->pfnSetDevice(pDrvStack->pIHostAudio, enmDir, pszDevId);
     839    else if (!pszDevId || *pszDevId)
     840        rc = VINF_SUCCESS;
     841    else
     842        rc = VERR_INVALID_FUNCTION;
    821843    return rc;
    822844}
     
    22552277 * Worker for audioTestCmdPlayHandler that plays one file.
    22562278 */
    2257 static RTEXITCODE audioTestPlayOne(const char *pszFile, PCPDMDRVREG pDrvReg, uint32_t cMsBufferSize,
     2279static RTEXITCODE audioTestPlayOne(const char *pszFile, PCPDMDRVREG pDrvReg, const char *pszDevId, uint32_t cMsBufferSize,
    22582280                                   uint32_t cMsPreBuffer, uint32_t cMsSchedulingHint, bool fWithDrvAudio)
    22592281{
     
    22862308    {
    22872309        /*
    2288          * Open a stream for the output.
     2310         * Set the output device if one is specified.
    22892311         */
    2290         PDMAUDIOSTREAMCFG CfgAcq;
    2291         PPDMAUDIOSTREAM   pStream = NULL;
    2292         rc = audioTestDriverStackStreamCreateOutput(&DrvStack, &WaveFile.Props, cMsBufferSize,
    2293                                                     cMsPreBuffer, cMsSchedulingHint, &pStream, &CfgAcq);
     2312        rc = audioTestDriverStackSetDevice(&DrvStack, PDMAUDIODIR_OUT, pszDevId);
    22942313        if (RT_SUCCESS(rc))
    22952314        {
    2296             rc = audioTestDriverStackStreamEnable(&DrvStack, pStream);
     2315            /*
     2316             * Open a stream for the output.
     2317             */
     2318            PDMAUDIOSTREAMCFG CfgAcq;
     2319            PPDMAUDIOSTREAM   pStream = NULL;
     2320            rc = audioTestDriverStackStreamCreateOutput(&DrvStack, &WaveFile.Props, cMsBufferSize,
     2321                                                        cMsPreBuffer, cMsSchedulingHint, &pStream, &CfgAcq);
    22972322            if (RT_SUCCESS(rc))
    22982323            {
    2299                 uint64_t const nsStarted = RTTimeNanoTS();
    2300 
    2301                 /*
    2302                  * Transfer data as quickly as we're allowed.
    2303                  */
    2304                 for (;;)
     2324                rc = audioTestDriverStackStreamEnable(&DrvStack, pStream);
     2325                if (RT_SUCCESS(rc))
    23052326                {
    2306                     /* Read a chunk from the wave file. */
    2307                     uint8_t  abSamples[16384];
    2308                     size_t   cbSamples = 0;
    2309                     rc = AudioTestWaveFileRead(&WaveFile, abSamples, sizeof(abSamples), &cbSamples);
    2310                     if (RT_SUCCESS(rc) && cbSamples > 0)
     2327                    uint64_t const nsStarted = RTTimeNanoTS();
     2328
     2329                    /*
     2330                     * Transfer data as quickly as we're allowed.
     2331                     */
     2332                    for (;;)
    23112333                    {
    2312                         /* Transfer the data to the audio stream. */
    2313                         for (uint32_t offSamples = 0; offSamples < cbSamples;)
     2334                        /* Read a chunk from the wave file. */
     2335                        uint8_t  abSamples[16384];
     2336                        size_t   cbSamples = 0;
     2337                        rc = AudioTestWaveFileRead(&WaveFile, abSamples, sizeof(abSamples), &cbSamples);
     2338                        if (RT_SUCCESS(rc) && cbSamples > 0)
    23142339                        {
    2315                             uint32_t const cbCanWrite = audioTestDriverStackStreamGetWritable(&DrvStack, pStream);
    2316                             if (cbCanWrite > 0)
     2340                            /* Transfer the data to the audio stream. */
     2341                            for (uint32_t offSamples = 0; offSamples < cbSamples;)
    23172342                            {
    2318                                 uint32_t const cbToPlay = RT_MIN(cbCanWrite, (uint32_t)cbSamples - offSamples);
    2319                                 uint32_t       cbPlayed = 0;
    2320                                 rc = audioTestDriverStackStreamPlay(&DrvStack, pStream, &abSamples[offSamples],
    2321                                                                     cbToPlay, &cbPlayed);
    2322                                 if (RT_SUCCESS(rc))
     2343                                uint32_t const cbCanWrite = audioTestDriverStackStreamGetWritable(&DrvStack, pStream);
     2344                                if (cbCanWrite > 0)
    23232345                                {
    2324                                     if (cbPlayed)
    2325                                         offSamples += cbPlayed;
     2346                                    uint32_t const cbToPlay = RT_MIN(cbCanWrite, (uint32_t)cbSamples - offSamples);
     2347                                    uint32_t       cbPlayed = 0;
     2348                                    rc = audioTestDriverStackStreamPlay(&DrvStack, pStream, &abSamples[offSamples],
     2349                                                                        cbToPlay, &cbPlayed);
     2350                                    if (RT_SUCCESS(rc))
     2351                                    {
     2352                                        if (cbPlayed)
     2353                                            offSamples += cbPlayed;
     2354                                        else
     2355                                        {
     2356                                            rcExit = RTMsgErrorExitFailure("Played zero out of %#x bytes - %#x bytes reported playable!\n",
     2357                                                                           cbToPlay, cbCanWrite);
     2358                                            break;
     2359                                        }
     2360                                    }
    23262361                                    else
    23272362                                    {
    2328                                         rcExit = RTMsgErrorExitFailure("Played zero out of %#x bytes - %#x bytes reported playable!\n",
    2329                                                                        cbToPlay, cbCanWrite);
     2363                                        rcExit = RTMsgErrorExitFailure("Failed to play %#x bytes: %Rrc\n", cbToPlay, rc);
    23302364                                        break;
    23312365                                    }
    23322366                                }
     2367                                else if (audioTestDriverStackStreamIsOkay(&DrvStack, pStream))
     2368                                    RTThreadSleep(RT_MIN(RT_MAX(1, CfgAcq.Device.cMsSchedulingHint), 256));
    23332369                                else
    23342370                                {
    2335                                     rcExit = RTMsgErrorExitFailure("Failed to play %#x bytes: %Rrc\n", cbToPlay, rc);
     2371                                    rcExit = RTMsgErrorExitFailure("Stream is not okay!\n");
    23362372                                    break;
    23372373                                }
    23382374                            }
    2339                             else if (audioTestDriverStackStreamIsOkay(&DrvStack, pStream))
    2340                                 RTThreadSleep(RT_MIN(RT_MAX(1, CfgAcq.Device.cMsSchedulingHint), 256));
    2341                             else
    2342                             {
    2343                                 rcExit = RTMsgErrorExitFailure("Stream is not okay!\n");
    2344                                 break;
    2345                             }
     2375                        }
     2376                        else if (RT_SUCCESS(rc) && cbSamples == 0)
     2377                        {
     2378                            rcExit = RTEXITCODE_SUCCESS;
     2379                            break;
     2380                        }
     2381                        else
     2382                        {
     2383                            rcExit = RTMsgErrorExitFailure("Error reading wav file '%s': %Rrc", pszFile, rc);
     2384                            break;
    23462385                        }
    23472386                    }
    2348                     else if (RT_SUCCESS(rc) && cbSamples == 0)
     2387
     2388                    /*
     2389                     * Drain the stream.
     2390                     */
     2391                    if (rcExit == RTEXITCODE_SUCCESS)
    23492392                    {
    2350                         rcExit = RTEXITCODE_SUCCESS;
    2351                         break;
    2352                     }
    2353                     else
    2354                     {
    2355                         rcExit = RTMsgErrorExitFailure("Error reading wav file '%s': %Rrc", pszFile, rc);
    2356                         break;
     2393                        if (g_uVerbosity > 0)
     2394                            RTMsgInfo("%'RU64 ns: Draining...\n", RTTimeNanoTS() - nsStarted);
     2395                        rc = audioTestDriverStackStreamDrain(&DrvStack, pStream, true /*fSync*/);
     2396                        if (RT_SUCCESS(rc))
     2397                        {
     2398                            if (g_uVerbosity > 0)
     2399                                RTMsgInfo("%'RU64 ns: Done\n", RTTimeNanoTS() - nsStarted);
     2400                        }
     2401                        else
     2402                            rcExit = RTMsgErrorExitFailure("Draining failed: %Rrc", rc);
    23572403                    }
    23582404                }
    2359 
    2360                 /*
    2361                  * Drain the stream.
    2362                  */
    2363                 if (rcExit == RTEXITCODE_SUCCESS)
    2364                 {
    2365                     if (g_uVerbosity > 0)
    2366                         RTMsgInfo("%'RU64 ns: Draining...\n", RTTimeNanoTS() - nsStarted);
    2367                     rc = audioTestDriverStackStreamDrain(&DrvStack, pStream, true /*fSync*/);
    2368                     if (RT_SUCCESS(rc))
    2369                     {
    2370                         if (g_uVerbosity > 0)
    2371                             RTMsgInfo("%'RU64 ns: Done\n", RTTimeNanoTS() - nsStarted);
    2372                     }
    2373                     else
    2374                         rcExit = RTMsgErrorExitFailure("Draining failed: %Rrc", rc);
    2375                 }
     2405                else
     2406                    rcExit = RTMsgErrorExitFailure("Enabling the output stream failed: %Rrc", rc);
     2407                audioTestDriverStackStreamDestroy(&DrvStack, pStream);
    23762408            }
    23772409            else
    2378                 rcExit = RTMsgErrorExitFailure("Enabling the output stream failed: %Rrc", rc);
    2379             audioTestDriverStackStreamDestroy(&DrvStack, pStream);
     2410                rcExit = RTMsgErrorExitFailure("Creating output stream failed: %Rrc", rc);
    23802411        }
    23812412        else
    2382             rcExit = RTMsgErrorExitFailure("Creating output stream failed: %Rrc", rc);
     2413            rcExit = RTMsgErrorExitFailure("Failed to set output device to '%s': %Rrc", pszDevId, rc);
    23832414        audioTestDriverStackDelete(&DrvStack);
    23842415    }
     
    23952426{
    23962427    { "--backend",          'b',                          RTGETOPT_REQ_STRING  },
     2428    { "--output-device",    'o',                          RTGETOPT_REQ_STRING  },
    23972429    { "--with-drv-audio",   'd',                          RTGETOPT_REQ_NOTHING },
    23982430};
     
    24052437        case 'b': return "The audio backend to use.";
    24062438        case 'd': return "Go via DrvAudio instead of directly interfacing with the backend.";
     2439        case 'o': return "The ID of the output device to use.";
    24072440        default:  return NULL;
    24082441    }
     
    24222455    uint32_t    cMsPreBuffer      = UINT32_MAX;
    24232456    uint32_t    cMsSchedulingHint = UINT32_MAX;
     2457    const char *pszDevId          = NULL;
    24242458    bool        fWithDrvAudio     = false;
    24252459
     
    24482482                break;
    24492483
     2484            case 'o':
     2485                pszDevId = ValueUnion.psz;
     2486                break;
     2487
    24502488            case VINF_GETOPT_NOT_OPTION:
    24512489            {
    2452                 RTEXITCODE rcExit = audioTestPlayOne(ValueUnion.psz, pDrvReg, cMsBufferSize, cMsPreBuffer,
     2490                RTEXITCODE rcExit = audioTestPlayOne(ValueUnion.psz, pDrvReg, pszDevId, cMsBufferSize, cMsPreBuffer,
    24532491                                                     cMsSchedulingHint, fWithDrvAudio);
    24542492                if (rcExit != RTEXITCODE_SUCCESS)
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