VirtualBox

Changeset 87843 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Feb 23, 2021 9:41:29 AM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
142907
Message:

Audio/DebugAudio: Implemented support of providing an artificial line-in / mic-in input for testing through the driver chain by creating a random sine wave on-the-fly.

File:
1 edited

Legend:

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

    r82968 r87843  
    77
    88/*
    9  * Copyright (C) 2016-2020 Oracle Corporation
     9 * Copyright (C) 2016-2021 Oracle Corporation
    1010 *
    1111 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1919
    2020#include <iprt/alloc.h>
     21#include <iprt/rand.h>
    2122#include <iprt/uuid.h> /* For PDMIBASE_2_PDMDRV. */
     23
     24#include <math.h>
    2225
    2326#define LOG_GROUP LOG_GROUP_DRV_HOST_AUDIO
     
    4245        struct
    4346        {
     47            /** Frequency (in Hz) of the sine wave to generate. */
     48            uint16_t   uFreqHz;
     49            /** Current sample index for generate the sine wave. */
     50            uint64_t   uSample;
    4451            /** Timestamp of last captured samples. */
    4552            uint64_t   tsLastCaptured;
     
    7784
    7885    pBackendCfg->cMaxStreamsOut = 1; /* Output; writing to a file. */
    79     pBackendCfg->cMaxStreamsIn  = 0; /** @todo Right now we don't support any input (capturing, injecting from a file). */
     86    pBackendCfg->cMaxStreamsIn  = 1; /* Input; generates a sine wave. */
    8087
    8188    return VINF_SUCCESS;
     
    116123
    117124
    118 static int debugCreateStreamIn(PDRVHOSTDEBUGAUDIO pDrv, PDEBUGAUDIOSTREAM pStreamDbg,
    119                                PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    120 {
    121     RT_NOREF(pDrv, pStreamDbg, pCfgReq, pCfgAcq);
    122 
    123     return VINF_SUCCESS;
    124 }
    125 
    126 
    127 static int debugCreateStreamOut(PDRVHOSTDEBUGAUDIO pDrv, PDEBUGAUDIOSTREAM pStreamDbg,
    128                                 PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
    129 {
    130     RT_NOREF(pDrv, pCfgAcq);
    131 
     125/**
     126 * Creates a debug output .WAV file on the host with the specified stream configuration.
     127 *
     128 * @returns VBox status code.
     129 * @param   pDrv                Driver instance.
     130 * @param   pStreamDbg          Debug audio stream to create file for.
     131 * @param   fIn                 Whether this is an input or output stream to create file for.
     132 * @param   pCfg                Stream configuration to create .wAV file with.
     133 */
     134static int debugCreateFile(PDRVHOSTDEBUGAUDIO pDrv, PDEBUGAUDIOSTREAM pStreamDbg, bool fIn, PPDMAUDIOSTREAMCFG pCfg)
     135{
    132136    char szTemp[RTPATH_MAX];
    133137    int rc = RTPathTemp(szTemp, sizeof(szTemp));
     
    135139    {
    136140        char szFile[RTPATH_MAX];
    137         rc = DrvAudioHlpFileNameGet(szFile, RT_ELEMENTS(szFile), szTemp, "DebugAudioOut",
     141        rc = DrvAudioHlpFileNameGet(szFile, RT_ELEMENTS(szFile), szTemp, fIn ? "DebugAudioIn" : "DebugAudioOut",
    138142                                    pDrv->pDrvIns->iInstance, PDMAUDIOFILETYPE_WAV, PDMAUDIOFILENAME_FLAGS_NONE);
    139143        if (RT_SUCCESS(rc))
     
    143147            {
    144148                rc = DrvAudioHlpFileOpen(pStreamDbg->pFile, RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE_REPLACE,
    145                                          &pCfgReq->Props);
     149                                         &pCfg->Props);
    146150            }
    147151
    148152            if (RT_FAILURE(rc))
    149                 LogRel(("DebugAudio: Creating output file '%s' failed with %Rrc\n", szFile, rc));
     153                LogRel(("DebugAudio: Creating %sput file '%s' failed with %Rrc\n", fIn ? "in" : "out", szFile, rc));
    150154        }
    151155        else
     
    159163
    160164
     165static int debugCreateStreamIn(PDRVHOSTDEBUGAUDIO pDrv, PDEBUGAUDIOSTREAM pStreamDbg,
     166                               PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     167{
     168    RT_NOREF(pDrv, pCfgReq);
     169
     170    pStreamDbg->In.uSample   = 0; /* Initialize sample index. */
     171
     172    const uint16_t auFreqsHz[] = { 400, 600, 750, 800, 1000, 1200, 1400, 1600 };
     173
     174    /* Chose a random frequency so that every time a recording is started (hopefully) another tone will be generated. */
     175    pStreamDbg->In.uFreqHz   = auFreqsHz[RTRandU32Ex(0, RT_ELEMENTS(auFreqsHz) - 1)];
     176
     177    pCfgAcq->Props.uHz         = 22050; /* 22,5 kHz. */
     178    pCfgAcq->Props.cbSample    = 2;     /* 16-bit samples. */
     179    pCfgAcq->Props.cChannels   = 1;     /* Mono. */
     180    pCfgAcq->Props.fSigned     = true;
     181    pCfgAcq->Props.fSwapEndian = false;
     182    pCfgAcq->Props.cShift      = PDMAUDIOPCMPROPS_MAKE_SHIFT_PARMS(pCfgAcq->Props.cbSample, pCfgAcq->Props.cChannels);
     183
     184    return debugCreateFile(pDrv, pStreamDbg, true /* fIn */, pCfgAcq);
     185}
     186
     187
     188static int debugCreateStreamOut(PDRVHOSTDEBUGAUDIO pDrv, PDEBUGAUDIOSTREAM pStreamDbg,
     189                                PPDMAUDIOSTREAMCFG pCfgReq, PPDMAUDIOSTREAMCFG pCfgAcq)
     190{
     191    RT_NOREF(pDrv, pCfgAcq);
     192
     193    return debugCreateFile(pDrv, pStreamDbg, false /* fIn */, pCfgReq);
     194}
     195
     196
    161197/**
    162198 * @interface_method_impl{PDMIHOSTAUDIO,pfnStreamCreate}
     
    219255                                                           void *pvBuf, uint32_t uBufSize, uint32_t *puRead)
    220256{
    221     RT_NOREF(pInterface, pStream, pvBuf, uBufSize);
    222 
    223     /* Never capture anything. */
     257    RT_NOREF(pInterface);
     258
     259    PDEBUGAUDIOSTREAM  pStreamDbg = (PDEBUGAUDIOSTREAM)pStream;
     260
     261    PPDMAUDIOSTREAMCFG pCfg = pStreamDbg->pCfg;
     262    AssertPtr(pCfg);
     263
     264    Assert(uBufSize % pCfg->Props.cbSample == 0);
     265
     266    uint16_t *paBuf = (uint16_t *)pvBuf;
     267
     268    /* Generate a simple mono sine wave. */
     269    for (size_t i = 0; i < uBufSize / pCfg->Props.cbSample; i++)
     270    {
     271        paBuf[i] = 32760 * sin((2.f * float(3.1415) * pStreamDbg->In.uFreqHz) / pCfg->Props.uHz * pStreamDbg->In.uSample);
     272        if (pStreamDbg->In.uSample == UINT64_MAX)
     273        {
     274            pStreamDbg->In.uSample = 0;
     275            continue;
     276        }
     277
     278        pStreamDbg->In.uSample++;
     279    }
     280
     281    int rc = DrvAudioHlpFileWrite(pStreamDbg->pFile, pvBuf, uBufSize, 0 /* fFlags */);
     282    if (RT_FAILURE(rc))
     283    {
     284        LogRel(("DebugAudio: Writing input failed with %Rrc\n", rc));
     285        return rc;
     286    }
     287
    224288    if (puRead)
    225         *puRead = 0;
     289        *puRead = uBufSize;
    226290
    227291    return VINF_SUCCESS;
     
    238302static int debugDestroyStreamOut(PDRVHOSTDEBUGAUDIO pDrv, PDEBUGAUDIOSTREAM pStreamDbg)
    239303{
    240     RT_NOREF(pDrv);
    241 
    242     DrvAudioHlpFileDestroy(pStreamDbg->pFile);
    243 
     304    RT_NOREF(pDrv, pStreamDbg);
    244305    return VINF_SUCCESS;
    245306}
     
    267328    if (RT_SUCCESS(rc))
    268329    {
     330        DrvAudioHlpFileDestroy(pStreamDbg->pFile);
     331
    269332        DrvAudioHlpStreamCfgFree(pStreamDbg->pCfg);
    270333        pStreamDbg->pCfg = NULL;
     
    294357static DECLCALLBACK(uint32_t) drvHostDebugAudioHA_StreamGetReadable(PPDMIHOSTAUDIO pInterface, PPDMAUDIOBACKENDSTREAM pStream)
    295358{
    296     RT_NOREF(pInterface, pStream);
    297 
    298     return 0; /* Never capture anything. */
     359    RT_NOREF(pInterface);
     360
     361    PDEBUGAUDIOSTREAM pStreamDbg = (PDEBUGAUDIOSTREAM)pStream;
     362
     363    AssertPtr(pStreamDbg->pCfg);
     364
     365    return DrvAudioHlpMilliToBytes(10 /* ms */, &pStreamDbg->pCfg->Props);
    299366}
    300367
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