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

📄 captureecho.cpp

📁 Windows CE .Net 下面 DIRECT SOUND编程的经典实例。对于初学Windows 平台下DIRECT SOUND编程技术的程序员颇具借鉴意义!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//

//==========================================================================;
//
//  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
//  PURPOSE.
//
//
//--------------------------------------------------------------------------;

#include "main.h"
#include "WinApp.h"
#include "ComUty.h"
#include "DebugUty.h"
#include "DSoundUty.h"


namespace
{
    // Class CEvent
    // ============
    // This class wraps an event handle to ameliorate event lifetime
    // management.  Since we want the class size to be _exactly_ the same
    // as the HANDLE we'll set the struct alignment to 1 byte.
#   include <pshpack1.h>
    class CEvent
    {

    public:

        CEvent()
            : m_hEvent(NULL)
        {
        }

        ~CEvent()
        {
            Close();
        }

        bool Create()
        {
            m_hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
            return m_hEvent!=NULL;
        }

        void Close()
        {
            if (m_hEvent!=NULL)
                CloseHandle(m_hEvent);
            m_hEvent=NULL;
        }

        operator HANDLE() // by returning an r-value, we still protect the data member
        {
            return m_hEvent;
        }

    protected:
        HANDLE m_hEvent;

    };
#   include <poppack.h>
}

// class CCaptureEchoApplication
// =============================
// This class represents the application and is self-explanatory.
// See WinApp.h for info on CWindowsApplication
class CCaptureEchoApplication : public CWindowsApplication
{
public:
    CCaptureEchoApplication();
    virtual bool Initialize();
    virtual void Run();
    virtual void Shutdown();
    virtual bool ProcessCommandLine();
private:
    CComPointer<IDirectSound> m_piDS;
    CComPointer<IDirectSoundCapture> m_piDSC;
    CComPointer<IDirectSoundBuffer> m_piDSBPrimary;
    DWORD m_dwTimeout;
    DWORD m_dwDelay;
    DWORD m_dwFormatIndex;

    void DisplayUsage();
};

int
WINAPI
WinMain (
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPWSTR lpCmd,
    int nCmdShow )
{
	// Declare a single instance of the application.
	CCaptureEchoApplication Application;

    return CWindowsApplication::WinMain(hInstance, 0, lpCmd, nCmdShow);
}

CCaptureEchoApplication::CCaptureEchoApplication()
: m_dwTimeout(DEFAULT_TIMEOUT), // N-second default timeout
  m_dwDelay(DEFAULT_DELAY),     // N-second delay
  m_dwFormatIndex(DEFAULT_CAPTURE_FORMAT) // 44kHz 16-bit stereo default
{
    // Nothing to do here
}

bool CCaptureEchoApplication::Initialize()
{
    HRESULT hr;
    const DSBUFFERDESC dsbdPrimary = { sizeof(DSBUFFERDESC), DSBCAPS_PRIMARYBUFFER, 0, 0, NULL };

    if (!CWindowsApplication::Initialize())
        return false;

    if (!ProcessCommandLine())
        return false;

    // Get the Direct Sound interface for the default Direct Sound object
    hr = DirectSoundCreate(NULL, m_piDS.AsOutParam(), NULL);
    CheckHRESULT(hr, "DirectSoundCreate", return false);

    // Set the cooperative level
    hr = m_piDS->SetCooperativeLevel(m_hWnd, DSSCL_NORMAL);
    CheckHRESULT(hr, "IDirectSound::SetCooperativeLevel(DSSCL_NORMAL)", return false);

    // Get the Direct Sound Capture interface for the default Direct Sound Capture object
    hr = DirectSoundCaptureCreate(NULL, m_piDSC.AsOutParam(), NULL);
    CheckHRESULT(hr, "DirectSoundCaptureCreate", return false);

    // Create the primary sound buffer
    hr = m_piDS->CreateSoundBuffer(&dsbdPrimary, m_piDSBPrimary.AsOutParam(), NULL);
    CheckHRESULT(hr, "IDirectSound::CreateSoundBuffer for the primary sound buffer", return false);

    // Play the primary sound buffer
    hr = m_piDSBPrimary->Play(0,0,DSBPLAY_LOOPING);
    CheckHRESULT(hr,"IDirectSoundBuffer::Play(Looping) on Primary Sound buffer", return false);

    return true;
}

void CCaptureEchoApplication::Shutdown()
{
    // Note: shutdown will be called even when Initialize fails

    // Release application global objects
    m_piDSBPrimary.ReleaseInterface();
    m_piDSC.ReleaseInterface();
    m_piDS.ReleaseInterface();

    CWindowsApplication::Shutdown();
}


void CCaptureEchoApplication::Run()
{
    const int nNumStreamingBlocks = 4;
    HRESULT hr;
    CEvent rhEvents[nNumStreamingBlocks];
    DSBPOSITIONNOTIFY rdsbpnNotifications[nNumStreamingBlocks];
    CComPointer<IDirectSoundBuffer> piDSB, piDSBPrimary;
    CComPointer<IDirectSoundCaptureBuffer> piDSCB;
    CComPointer<IDirectSoundNotify> piDSNCapture;
    WAVEFORMATEX wfx;
    DSBUFFERDESC dsbd;
    DSCBUFFERDESC dscbd;
    DWORD dwStartTime, dwTimeElapsed, dwTmp, dwWaitResult = 0;
    DWORD dwLastReadPosition, dwReadPosition, dwBlockSize, dwWritePosition, dwBufferSize;
    LPBYTE pbAudioCapturePtr0, pbAudioCapturePtr1, pbAudioPlaybackPtr0, pbAudioPlaybackPtr1;
    DWORD dwAudioCaptureBytes0, dwAudioCaptureBytes1, dwAudioPlaybackBytes0, dwAudioPlaybackBytes1;
    bool fPlaying;
    int i;

    dbgout(TEXT("Capturing %g seconds and playing back with a %lums delay.\n"),
           static_cast<double>(m_dwTimeout)/1000.0, m_dwDelay);

    // Because this application is using DirectSound as well as DirectSoundCapture,
    // capture buffer creation can fail when the format of the capture buffer is not
    // the same as that of the primary buffer. The reason is that some cards have only
    // a single clock and cannot support capture and playback at two different frequencies.
    // To simplify buffer creation, we'll borrow the wave format of the primary buffer
    // to create our capure and playback buffers.
    hr = m_piDSBPrimary->GetFormat(&wfx, sizeof(wfx), NULL);
    CheckHRESULT(hr,"IDirectSoundBuffer::GetFormat on the primary sound buffer", return);

    // Some dsound drivers support multiple capture formats.
    //
    // Set the requested format (specified on command line) instead of using
    // only the format of the primary buffer.
    hr = SetRequestedCaptureFormat(m_piDSC.AsInParam(), wfx, m_dwFormatIndex);
    CheckHRESULT(hr, "SetRequestedCaptureFormat", return);

    // The buffer size should be aligned along wfx.nBlockAlign.
    // We're going to use four blocks, each of which is 2 seconds long.
    // Change this to fit your specific memory requirements
    // and your platform's specific alignment requirements
    dwBlockSize  = (m_dwDelay>>1)*wfx.nAvgBytesPerSec/1000;
    dwBlockSize -= dwBlockSize%wfx.nBlockAlign;
    dwBufferSize = dwBlockSize*nNumStreamingBlocks;

    // Create the Capture Buffer
    dscbd.dwSize        = sizeof(DSCBUFFERDESC);
    dscbd.dwFlags       = 0;
    dscbd.dwBufferBytes = dwBufferSize;
    dscbd.dwReserved    = 0;
    dscbd.lpwfxFormat   = &wfx;

    hr = m_piDSC->CreateCaptureBuffer(&dscbd, piDSCB.AsOutParam(), NULL);
    CheckHRESULT(hr, "IDirectSoundCapture::CreateCaptureBuffer", return);

    // Create a streaming playback buffer
    dsbd.dwSize         = sizeof(DSBUFFERDESC);
    dsbd.dwFlags        = DSBCAPS_CTRLALL | DSBCAPS_GLOBALFOCUS;
    dsbd.dwBufferBytes  = dwBufferSize;
    dsbd.dwReserved     = 0;
    dsbd.lpwfxFormat    = &wfx;

    hr = m_piDS->CreateSoundBuffer(&dsbd, piDSB.AsOutParam(), NULL);
    CheckHRESULT(hr, "IDirectSound::CreateSoundBuffer", return);

    // clear the playback buffer
    hr = ClearSoundBuffer(piDSB.AsInParam());
    CheckHRESULT(hr, "ClearSoundBuffer", return);

    // Set up the notifications
    for (i=0; i<nNumStreamingBlocks; i++)
    {
        if (!rhEvents[i].Create())
        {
            dbgout(TEXT("Could not create the notification event %d\n"), i);
            return;
        }
        rdsbpnNotifications[i].dwOffset = dwBlockSize*(i+1)-wfx.nBlockAlign;
        rdsbpnNotifications[i].hEventNotify = rhEvents[i];
    }

    hr = piDSCB->QueryInterface(IID_IDirectSoundNotify, reinterpret_cast<void**>(piDSNCapture.AsOutParam()));
    CheckHRESULT(hr, "IDirectSoundCaptureBuffer::QueryInterface", return);

    hr = piDSNCapture->SetNotificationPositions(nNumStreamingBlocks, rdsbpnNotifications);

⌨️ 快捷键说明

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