VirtualBox

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


Ignore:
Timestamp:
May 25, 2021 4:39:20 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
144625
Message:

Audio/ValKit: Implemented recording support for ValKit audio backend. Untested. bugref:10008

File:
1 edited

Legend:

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

    r89258 r89279  
    4141*********************************************************************************************************************************/
    4242/**
    43  * Structure for keeping a validation kit input/output stream.
     43 * Structure for keeping a Validation Kit input/output stream.
    4444 */
    4545typedef struct VAKITAUDIOSTREAM
     
    7373    };
    7474} VAKITAUDIOSTREAM;
    75 /** Pointer to a validation kit stream. */
     75/** Pointer to a Validation Kit stream. */
    7676typedef VAKITAUDIOSTREAM *PVAKITAUDIOSTREAM;
    7777
    7878/**
    79  * Validation kit audio driver instance data.
     79 * Test tone-specific instance data.
     80 */
     81typedef struct VALKITTESTTONEDATA
     82{
     83    /** How many ns to write. */
     84    uint64_t           nsToWrite;
     85    /** How many ns already written. */
     86    uint64_t           nsWritten;
     87    /** The test tone instance to use. */
     88    AUDIOTESTTONE      Tone;
     89    /** The test tone parameters to use. */
     90    AUDIOTESTTONEPARMS ToneParms;
     91} VALKITTESTTONEDATA;
     92
     93/**
     94 * Structure keeping a single Validation Kit test.
     95 */
     96typedef struct VALKITTESTDATA
     97{
     98    /** The list node. */
     99    RTLISTNODE             Node;
     100    /** Stream configuration to use for this test. */
     101    PDMAUDIOSTREAMCFG      StreamCfg;
     102    union
     103    {
     104        /** Test tone-specific data. */
     105        VALKITTESTTONEDATA TestTone;
     106    } t;
     107} VALKITTESTDATA;
     108/** Pointer to Validation Kit test data. */
     109typedef VALKITTESTDATA *PVALKITTESTDATA;
     110
     111/**
     112 * Validation Kit audio driver instance data.
    80113 * @implements PDMIAUDIOCONNECTOR
    81114 */
     
    86119    /** Pointer to host audio interface. */
    87120    PDMIHOSTAUDIO       IHostAudio;
     121    /** Number of tests in \a lstTestsRec. */
     122    uint32_t            cTestsRec;
     123    /** List keeping the recording tests (FIFO). */
     124    RTLISTANCHOR        lstTestsRec;
     125    /** Pointer to current recording test being processed. */
     126    PVALKITTESTDATA     pTestRecCur;
     127    /** Critical section for serializing access across threads. */
     128    RTCRITSECT          CritSect;
     129    /** The Audio Test Service (ATS) instance. */
     130    ATSSERVER           Srv;
    88131} DRVHOSTVAKITAUDIO;
    89 /** Pointer to a validation kit host audio driver instance. */
     132/** Pointer to a Validation Kit host audio driver instance. */
    90133typedef DRVHOSTVAKITAUDIO *PDRVHOSTVAKITAUDIO;
    91134
    92135
     136/**
     137 * Note: Called within server (client serving) thread.
     138 */
     139static DECLCALLBACK(int) drvHostValKitAudioSvcTonePlayCallback(void const *pvUser, PPDMAUDIOSTREAMCFG pStreamCfg, PAUDIOTESTTONEPARMS pToneParms)
     140{
     141    PDRVHOSTVAKITAUDIO pThis = (PDRVHOSTVAKITAUDIO)pvUser;
     142
     143    PVALKITTESTDATA pTestData = (PVALKITTESTDATA)RTMemAllocZ(sizeof(VALKITTESTDATA));
     144    AssertPtrReturn(pTestData, VERR_NO_MEMORY);
     145
     146    memcpy(&pTestData->StreamCfg,            pStreamCfg, sizeof(PDMAUDIOSTREAMCFG));
     147    memcpy(&pTestData->t.TestTone.ToneParms, pToneParms, sizeof(AUDIOTESTTONEPARMS));
     148
     149    int rc = RTCritSectEnter(&pThis->CritSect);
     150    if (RT_SUCCESS(rc))
     151    {
     152        RTListAppend(&pThis->lstTestsRec, &pTestData->Node);
     153
     154        int rc2 = RTCritSectLeave(&pThis->CritSect);
     155        AssertRC(rc2);
     156    }
     157
     158    return VINF_SUCCESS;
     159}
    93160
    94161/**
     
    106173    pBackendCfg->cbStream       = sizeof(VAKITAUDIOSTREAM);
    107174    pBackendCfg->fFlags         = 0;
    108     pBackendCfg->cMaxStreamsOut = 1; /* Output */
    109     pBackendCfg->cMaxStreamsIn  = 0; /* No input supported yet. */
     175    pBackendCfg->cMaxStreamsOut = 1; /* Output (Playback). */
     176    pBackendCfg->cMaxStreamsIn  = 1; /* Input (Recording). */
    110177
    111178    return VINF_SUCCESS;
     
    396463                                                            void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead)
    397464{
    398     RT_NOREF(pInterface, pStream, pvBuf, cbBuf);
    399 
    400     /* Never capture anything. */
    401     *pcbRead = 0;
     465    RT_NOREF(pStream);
     466
     467    PDRVHOSTVAKITAUDIO pThis = RT_FROM_MEMBER(pInterface, DRVHOSTVAKITAUDIO, IHostAudio);
     468
     469    int rc = VINF_SUCCESS;
     470
     471    if (pThis->pTestRecCur == NULL)
     472    {
     473        rc = RTCritSectEnter(&pThis->CritSect);
     474        if (RT_SUCCESS(rc))
     475        {
     476            pThis->pTestRecCur = RTListGetFirst(&pThis->lstTestsRec, VALKITTESTDATA, Node);
     477
     478            int rc2 = RTCritSectLeave(&pThis->CritSect);
     479            AssertRC(rc2);
     480        }
     481    }
     482
     483    if (pThis->pTestRecCur == NULL) /* Empty list? */
     484    {
     485        *pcbRead = 0;
     486        return VINF_SUCCESS;
     487    }
     488
     489    PVALKITTESTDATA pTst = pThis->pTestRecCur;
     490
     491    uint32_t cbToWrite = PDMAudioPropsNanoToBytes(&pTst->StreamCfg.Props,
     492                                                  (pTst->t.TestTone.nsToWrite - pTst->t.TestTone.nsWritten));
     493    uint32_t cbRead = 0;
     494    if (cbToWrite)
     495        rc = AudioTestToneGenerate(&pTst->t.TestTone.Tone, pvBuf, RT_MIN(cbToWrite, cbBuf), &cbRead);
     496
     497    const uint32_t nsWritten    = PDMAudioPropsBytesToNano(&pTst->StreamCfg.Props, cbRead);
     498    pTst->t.TestTone.nsWritten += nsWritten;
     499    Assert(pTst->t.TestTone.nsWritten <= pTst->t.TestTone.nsToWrite);
     500
     501    const bool fComplete = pTst->t.TestTone.nsToWrite == pTst->t.TestTone.nsWritten;
     502
     503    if (fComplete)
     504    {
     505        RTListNodeRemove(&pTst->Node);
     506
     507        RTMemFree(pTst);
     508        pTst = NULL;
     509
     510        Assert(pThis->cTestsRec);
     511        pThis->cTestsRec--;
     512    }
     513
     514    *pcbRead = cbRead;
     515
    402516    return VINF_SUCCESS;
    403517}
     
    439553    pThis->IHostAudio.pfnGetConfig                  = drvHostValKitAudioHA_GetConfig;
    440554    pThis->IHostAudio.pfnGetDevices                 = NULL;
    441     pThis->IHostAudio.pfnSetDevice                  = NULL;
    442555    pThis->IHostAudio.pfnGetStatus                  = drvHostValKitAudioHA_GetStatus;
    443556    pThis->IHostAudio.pfnDoOnWorkerThread           = NULL;
     
    455568    pThis->IHostAudio.pfnStreamCapture              = drvHostValKitAudioHA_StreamCapture;
    456569
    457     return VINF_SUCCESS;
     570    RTListInit(&pThis->lstTestsRec);
     571    pThis->cTestsRec = 0;
     572
     573    ATSCALLBACKS Callbacks;
     574    Callbacks.pfnTonePlay = drvHostValKitAudioSvcTonePlayCallback;
     575    Callbacks.pvUser      = pThis;
     576
     577    LogRel(("Audio: Validation Kit: Starting Audio Test Service (ATS) ...\n"));
     578
     579    int rc = AudioTestSvcInit(&pThis->Srv, &Callbacks);
     580    if (RT_SUCCESS(rc))
     581        rc = AudioTestSvcStart(&pThis->Srv);
     582
     583    if (RT_FAILURE(rc))
     584    {
     585        LogRel(("Audio: Validation Kit: Starting Audio Test Service (ATS) failed, rc=%Rrc\n", rc));
     586    }
     587    else
     588        LogRel(("Audio: Validation Kit: Audio Test Service (ATS) running\n"));
     589
     590    if (RT_SUCCESS(rc))
     591        rc = RTCritSectInit(&pThis->CritSect);
     592
     593    return rc;
     594}
     595
     596static DECLCALLBACK(void) drvHostValKitAudioDestruct(PPDMDRVINS pDrvIns)
     597{
     598    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
     599    PDRVHOSTVAKITAUDIO pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTVAKITAUDIO);
     600
     601    LogRel(("Audio: Validation Kit: Shutting down Audio Test Service (ATS) ...\n"));
     602
     603    int rc = AudioTestSvcShutdown(&pThis->Srv);
     604    if (RT_SUCCESS(rc))
     605        rc = AudioTestSvcDestroy(&pThis->Srv);
     606
     607    if (RT_SUCCESS(rc))
     608    {
     609        LogRel(("Audio: Validation Kit: Shutdown of Audio Test Service complete\n"));
     610
     611        PVALKITTESTDATA pData, pDataNext;
     612        RTListForEachSafe(&pThis->lstTestsRec, pData, pDataNext, VALKITTESTDATA, Node)
     613        {
     614            RTListNodeRemove(&pData->Node);
     615
     616            RTMemFree(pData);
     617
     618            Assert(pThis->cTestsRec);
     619            pThis->cTestsRec--;
     620        }
     621
     622        Assert(pThis->cTestsRec == 0);
     623    }
     624    else
     625        LogRel(("Audio: Validation Kit: Shutdown of Audio Test Service failed, rc=%Rrc\n", rc));
     626
     627    rc = RTCritSectDelete(&pThis->CritSect);
     628    AssertRC(rc);
    458629}
    459630
     
    484655    drvHostValKitAudioConstruct,
    485656    /* pfnDestruct */
    486     NULL,
     657    drvHostValKitAudioDestruct,
    487658    /* pfnRelocate */
    488659    NULL,
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