VirtualBox

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


Ignore:
Timestamp:
Sep 9, 2010 11:01:38 AM (14 years ago)
Author:
vboxsync
Message:

audio: Renamed config variable to match its function; default audio timer frequency now 200 Hz.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Audio/audio.c

    r29250 r32337  
    143143    },
    144144
    145     { 100 },                    /* period */
     145    { 200 },                    /* frequency (in Hz) */
    146146    0,                          /* plive */
    147147};
     
    15261526
    15271527    /* Misc */
    1528     {"TIMER_PERIOD", AUD_OPT_INT, &conf.period.hz,
    1529      "Timer period in HZ (0 - use lowest possible)", NULL, 0},
     1528    {"TIMER_FREQ", AUD_OPT_INT, &conf.period.hz,
     1529     "Timer frequency in Hz (0 - use lowest possible)", NULL, 0},
    15301530
    15311531    {"PLIVE", AUD_OPT_BOOL, &conf.plive,
  • trunk/src/VBox/Devices/Audio/audiosniffer.c

    r28800 r32337  
    2626#include <iprt/string.h>
    2727#include <iprt/alloc.h>
     28#include <iprt/file.h>
    2829
    2930#include "Builtins.h"
     
    5455    PPDMIAUDIOSNIFFERCONNECTOR   pDrv;
    5556
     57    void                         *pCapFileCtx;
    5658} AUDIOSNIFFERSTATE;
    5759
    5860static AUDIOSNIFFERSTATE *g_pData = NULL;
     61
     62typedef struct {
     63    RTFILE      capFile;
     64    int         curSampPerSec;
     65    int         curBitsPerSmp;
     66    int         curChannels;
     67    uint64_t    lastChunk;
     68} AUDCAPSTATE;
     69
     70typedef struct {
     71    uint16_t    wFormatTag;
     72    uint16_t    nChannels;
     73    uint32_t    nSamplesPerSec;
     74    uint32_t    nAvgBytesPerSec;
     75    uint16_t    nBlockAlign;
     76    uint16_t    wBitsPerSample;
     77} WAVEFMTHDR;
     78
     79static update_prev_chunk(AUDCAPSTATE *pState)
     80{
     81    size_t          written;
     82    uint64_t        cur_ofs;
     83    uint64_t        new_ofs;
     84    uint32_t        chunk_len;
     85
     86    Assert(pState);
     87    /* Write the size of the previous data chunk, if there was one. */
     88    if (pState->lastChunk)
     89    {
     90        cur_ofs = RTFileTell(pState->capFile);
     91        chunk_len = cur_ofs - pState->lastChunk - sizeof(chunk_len);
     92        RTFileWriteAt(pState->capFile, pState->lastChunk, &chunk_len, sizeof(chunk_len), &written);
     93        RTFileSeek(pState->capFile, 0, RTFILE_SEEK_END, &new_ofs);
     94    }
     95}
     96
     97static int create_capture_file(AUDCAPSTATE *pState, const char *fname)
     98{
     99    int             rc;
     100    size_t          written;
     101
     102    Assert(pState);
     103    memset(pState, 0, sizeof(*pState));
     104    /* Create the file and write the RIFF header. */
     105    rc = RTFileOpen(&pState->capFile, fname,
     106                    RTFILE_O_WRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_WRITE);
     107    rc = RTFileWrite(pState->capFile, "RIFFxxxx", 8, &written);
     108    return rc;
     109}
     110
     111static int close_capture_file(AUDCAPSTATE *pState)
     112{
     113    int             rc;
     114    size_t          written;
     115    uint64_t        cur_ofs;
     116    uint32_t        riff_len;
     117
     118    Assert(pState);
     119    update_prev_chunk(pState);
     120
     121    /* Update the global RIFF header. */
     122    cur_ofs = RTFileTell(pState->capFile);
     123    riff_len = cur_ofs - 8;
     124    RTFileWriteAt(pState->capFile, 4, &riff_len, sizeof(riff_len), &written);
     125   
     126    rc = RTFileClose(pState->capFile);
     127    return rc;
     128}
     129
     130static inline int16_t clip_natural_int16_t(int64_t v)
     131{
     132    if (v >= 0x7f000000) {
     133        return 0x7fff;
     134    }
     135    else if (v < -2147483648LL) {
     136        return (-32767-1);
     137    }
     138    return  ((int16_t) (v >> (32 - 16)));
     139}
     140
     141static int update_capture_file(AUDCAPSTATE *pState, HWVoiceOut *hw, st_sample_t *pSamples, unsigned cSamples)
     142{
     143    size_t          written;
     144    uint16_t        buff[16384];
     145    unsigned        i;
     146    uint16_t        *dst_smp;
     147
     148    Assert(pState);
     149    /* If the audio format changed, start a new WAVE chunk. */
     150    if (   hw->info.freq != pState->curSampPerSec
     151        || hw->info.bits != pState->curBitsPerSmp
     152        || hw->info.nchannels != pState->curChannels)
     153    {
     154        WAVEFMTHDR      wave_hdr;
     155        uint32_t        chunk_len;
     156
     157        update_prev_chunk(pState);
     158
     159        /* Build a new format ('fmt ') chunk. */
     160        wave_hdr.wFormatTag      = 1;    /* Linear PCM */
     161        wave_hdr.nChannels       = hw->info.nchannels;
     162        wave_hdr.nSamplesPerSec  = hw->info.freq;
     163        wave_hdr.nAvgBytesPerSec = hw->info.bytes_per_second;
     164        wave_hdr.nBlockAlign     = 4;
     165        wave_hdr.wBitsPerSample  = hw->info.bits;
     166
     167        pState->curSampPerSec = hw->info.freq;
     168        pState->curBitsPerSmp = hw->info.bits;
     169        pState->curChannels   = hw->info.nchannels;
     170
     171        /* Write the header to file. */
     172        RTFileWrite(pState->capFile, "WAVEfmt ", 8, &written);
     173        chunk_len = sizeof(wave_hdr);
     174        RTFileWrite(pState->capFile, &chunk_len, sizeof(chunk_len), &written);
     175        RTFileWrite(pState->capFile, &wave_hdr, sizeof(wave_hdr), &written);
     176        /* Write data chunk marker with dummy length. */
     177        RTFileWrite(pState->capFile, "dataxxxx", 8, &written);
     178        pState->lastChunk = RTFileTell(pState->capFile) - 4;
     179    }
     180
     181    /* Convert the samples from internal format. */
     182    //@todo: use mixer engine helpers instead?
     183    for (i = 0, dst_smp = buff; i < cSamples; ++i)
     184    {
     185        *dst_smp++ = clip_natural_int16_t(pSamples->l);
     186        *dst_smp++ = clip_natural_int16_t(pSamples->r);
     187        ++pSamples;
     188    }
     189
     190//    LogRel(("Audio: captured %d samples\n", cSamples));
     191    /* Write the audio data. */
     192    RTFileWrite(pState->capFile, buff, cSamples * (hw->info.bits / 8) * hw->info.nchannels, &written);
     193    return VINF_SUCCESS;
     194}
    59195
    60196/*
     
    82218    bool fUnsigned;
    83219
     220    if (g_pData)
     221        update_capture_file(g_pData->pCapFileCtx, hw, pvSamples, cSamples);
     222
    84223    if (!g_pData || !g_pData->pDrv || !g_pData->fEnabled)
    85224    {
     
    137276static DECLCALLBACK(int) audioSnifferR3Destruct(PPDMDEVINS pDevIns)
    138277{
     278    AUDIOSNIFFERSTATE *pThis = PDMINS_2_DATA(pDevIns, AUDIOSNIFFERSTATE *);
    139279    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
     280
     281    close_capture_file(pThis->pCapFileCtx);
     282    RTMemFree(pThis->pCapFileCtx);
    140283
    141284    /* Zero the global pointer. */
     
    211354        g_pData = pThis;
    212355    }
     356
     357    pThis->pCapFileCtx = RTMemAlloc(sizeof(AUDCAPSTATE));
     358    create_capture_file(pThis->pCapFileCtx, "c:\\vbox.wav");
    213359
    214360    return rc;
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