⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dsound_wrapper.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 2 页
字号:
    }    AddTraceMessage("playCursor", playCursor);    AddTraceMessage("dsw_WriteOffset", dsw->dsw_WriteOffset);    // Determine size of gap between playIndex and WriteIndex that we cannot write into.    playWriteGap = writeCursor - playCursor;    if( playWriteGap < 0 ) playWriteGap += dsw->dsw_OutputSize; // unwrap    /* DirectSound doesn't have a large enough playCursor so we cannot detect wrap-around. */    /* Attempt to detect playCursor wrap-around and correct it. */    if( dsw->dsw_OutputRunning && (dsw->dsw_CounterTicksPerBuffer.QuadPart != 0) )    {        /* How much time has elapsed since last check. */        LARGE_INTEGER   currentTime;        LARGE_INTEGER   elapsedTime;        long            bytesPlayed;        long            bytesExpected;        long            buffersWrapped;        QueryPerformanceCounter( &currentTime );        elapsedTime.QuadPart = currentTime.QuadPart - dsw->dsw_LastPlayTime.QuadPart;        dsw->dsw_LastPlayTime = currentTime;        /* How many bytes does DirectSound say have been played. */        bytesPlayed = playCursor - dsw->dsw_LastPlayCursor;        if( bytesPlayed < 0 ) bytesPlayed += dsw->dsw_OutputSize; // unwrap        dsw->dsw_LastPlayCursor = playCursor;        /* Calculate how many bytes we would have expected to been played by now. */        bytesExpected = (long) ((elapsedTime.QuadPart * dsw->dsw_OutputSize) / dsw->dsw_CounterTicksPerBuffer.QuadPart);        buffersWrapped = (bytesExpected - bytesPlayed) / dsw->dsw_OutputSize;        if( buffersWrapped > 0 )        {            AddTraceMessage("playCursor wrapped! bytesPlayed", bytesPlayed );            AddTraceMessage("playCursor wrapped! bytesExpected", bytesExpected );            playCursor += (buffersWrapped * dsw->dsw_OutputSize);            bytesPlayed += (buffersWrapped * dsw->dsw_OutputSize);        }        /* Maintain frame output cursor. */        dsw->dsw_FramesPlayed += (bytesPlayed / dsw->dsw_BytesPerFrame);    }    numBytesEmpty = playCursor - dsw->dsw_WriteOffset;    if( numBytesEmpty < 0 ) numBytesEmpty += dsw->dsw_OutputSize; // unwrap offset    /* Have we underflowed? */    if( numBytesEmpty > (dsw->dsw_OutputSize - playWriteGap) )    {        if( dsw->dsw_OutputRunning )        {            dsw->dsw_OutputUnderflows += 1;            AddTraceMessage("underflow detected! numBytesEmpty", numBytesEmpty );        }        dsw->dsw_WriteOffset = writeCursor;        numBytesEmpty = dsw->dsw_OutputSize - playWriteGap;    }    *bytesEmpty = numBytesEmpty;    return hr;}/************************************************************************************/HRESULT DSW_ZeroEmptySpace( DSoundWrapper *dsw ){    HRESULT hr;    LPBYTE lpbuf1 = NULL;    LPBYTE lpbuf2 = NULL;    DWORD dwsize1 = 0;    DWORD dwsize2 = 0;    long  bytesEmpty;    hr = DSW_QueryOutputSpace( dsw, &bytesEmpty ); // updates dsw_FramesPlayed    if (hr != DS_OK) return hr;    if( bytesEmpty == 0 ) return DS_OK;    // Lock free space in the DS    hr = IDirectSoundBuffer_Lock( dsw->dsw_OutputBuffer, dsw->dsw_WriteOffset, bytesEmpty, (void **) &lpbuf1, &dwsize1,                                  (void **) &lpbuf2, &dwsize2, 0);    if (hr == DS_OK)    {        // Copy the buffer into the DS        ZeroMemory(lpbuf1, dwsize1);        if(lpbuf2 != NULL)        {            ZeroMemory(lpbuf2, dwsize2);        }        // Update our buffer offset and unlock sound buffer        dsw->dsw_WriteOffset = (dsw->dsw_WriteOffset + dwsize1 + dwsize2) % dsw->dsw_OutputSize;        IDirectSoundBuffer_Unlock( dsw->dsw_OutputBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);        dsw->dsw_FramesWritten += bytesEmpty / dsw->dsw_BytesPerFrame;    }    return hr;}/************************************************************************************/HRESULT DSW_WriteBlock( DSoundWrapper *dsw, char *buf, long numBytes ){    HRESULT hr;    LPBYTE lpbuf1 = NULL;    LPBYTE lpbuf2 = NULL;    DWORD dwsize1 = 0;    DWORD dwsize2 = 0;    // Lock free space in the DS    hr = IDirectSoundBuffer_Lock( dsw->dsw_OutputBuffer, dsw->dsw_WriteOffset, numBytes, (void **) &lpbuf1, &dwsize1,                                  (void **) &lpbuf2, &dwsize2, 0);    if (hr == DS_OK)    {        // Copy the buffer into the DS        CopyMemory(lpbuf1, buf, dwsize1);        if(lpbuf2 != NULL)        {            CopyMemory(lpbuf2, buf+dwsize1, dwsize2);        }        // Update our buffer offset and unlock sound buffer        dsw->dsw_WriteOffset = (dsw->dsw_WriteOffset + dwsize1 + dwsize2) % dsw->dsw_OutputSize;        IDirectSoundBuffer_Unlock( dsw->dsw_OutputBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);        dsw->dsw_FramesWritten += numBytes / dsw->dsw_BytesPerFrame;    }    return hr;}/************************************************************************************/DWORD DSW_GetOutputStatus( DSoundWrapper *dsw ){    DWORD status;    if (IDirectSoundBuffer_GetStatus( dsw->dsw_OutputBuffer, &status ) != DS_OK)        return( DSERR_INVALIDPARAM );    else        return( status );}#if SUPPORT_AUDIO_CAPTURE/* These routines are used to support audio input. * Do NOT compile these calls when using NT4 because it does * not support the entry points. *//************************************************************************************/HRESULT DSW_InitInputDevice( DSoundWrapper *dsw, LPGUID lpGUID ){    HRESULT hr = DirectSoundCaptureCreate(  lpGUID, &dsw->dsw_pDirectSoundCapture,   NULL );    if( hr != DS_OK ) return hr;    return hr;}/************************************************************************************/HRESULT DSW_InitInputBuffer( DSoundWrapper *dsw, unsigned long nFrameRate, int nChannels, int bytesPerBuffer ){    DSCBUFFERDESC  captureDesc;    WAVEFORMATEX   wfFormat;    HRESULT        result;    // Define the buffer format    wfFormat.wFormatTag      = WAVE_FORMAT_PCM;    wfFormat.nChannels       = nChannels;    wfFormat.nSamplesPerSec  = nFrameRate;    wfFormat.wBitsPerSample  = 8 * sizeof(short);    wfFormat.nBlockAlign     = wfFormat.nChannels * (wfFormat.wBitsPerSample / 8);    wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;    wfFormat.cbSize          = 0;   /* No extended format info. */    dsw->dsw_InputSize = bytesPerBuffer;    // ----------------------------------------------------------------------    // Setup the secondary buffer description    ZeroMemory(&captureDesc, sizeof(DSCBUFFERDESC));    captureDesc.dwSize = sizeof(DSCBUFFERDESC);    captureDesc.dwFlags =  0;    captureDesc.dwBufferBytes = bytesPerBuffer;    captureDesc.lpwfxFormat = &wfFormat;    // Create the capture buffer    if ((result = IDirectSoundCapture_CreateCaptureBuffer( dsw->dsw_pDirectSoundCapture,                  &captureDesc, &dsw->dsw_InputBuffer, NULL)) != DS_OK) return result;    dsw->dsw_ReadOffset = 0;  // reset last read position to start of buffer    return DS_OK;}/************************************************************************************/HRESULT DSW_StartInput( DSoundWrapper *dsw ){    // Start the buffer playback    if( dsw->dsw_InputBuffer != NULL )    {        return IDirectSoundCaptureBuffer_Start( dsw->dsw_InputBuffer, DSCBSTART_LOOPING );    }    else return 0;}/************************************************************************************/HRESULT DSW_StopInput( DSoundWrapper *dsw ){    // Stop the buffer playback    if( dsw->dsw_InputBuffer != NULL )    {        return IDirectSoundCaptureBuffer_Stop( dsw->dsw_InputBuffer );    }    else return 0;}/************************************************************************************/HRESULT DSW_QueryInputFilled( DSoundWrapper *dsw, long *bytesFilled ){    HRESULT hr;    DWORD capturePos;    DWORD readPos;    long  filled;    // Query to see how much data is in buffer.    // We don't need the capture position but sometimes DirectSound doesn't handle NULLS correctly    // so let's pass a pointer just to be safe.    hr = IDirectSoundCaptureBuffer_GetCurrentPosition( dsw->dsw_InputBuffer, &capturePos, &readPos );    if( hr != DS_OK )    {        return hr;    }    filled = readPos - dsw->dsw_ReadOffset;    if( filled < 0 ) filled += dsw->dsw_InputSize; // unwrap offset    *bytesFilled = filled;    return hr;}/************************************************************************************/HRESULT DSW_ReadBlock( DSoundWrapper *dsw, char *buf, long numBytes ){    HRESULT hr;    LPBYTE lpbuf1 = NULL;    LPBYTE lpbuf2 = NULL;    DWORD dwsize1 = 0;    DWORD dwsize2 = 0;    // Lock free space in the DS    hr = IDirectSoundCaptureBuffer_Lock ( dsw->dsw_InputBuffer, dsw->dsw_ReadOffset, numBytes, (void **) &lpbuf1, &dwsize1,                                          (void **) &lpbuf2, &dwsize2, 0);    if (hr == DS_OK)    {        // Copy from DS to the buffer        CopyMemory( buf, lpbuf1, dwsize1);        if(lpbuf2 != NULL)        {            CopyMemory( buf+dwsize1, lpbuf2, dwsize2);        }        // Update our buffer offset and unlock sound buffer        dsw->dsw_ReadOffset = (dsw->dsw_ReadOffset + dwsize1 + dwsize2) % dsw->dsw_InputSize;        IDirectSoundCaptureBuffer_Unlock ( dsw->dsw_InputBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);    }    return hr;}#endif /* SUPPORT_AUDIO_CAPTURE */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -