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

📄 cpi_player_output_directsound.c

📁 VC++视频开发实例集锦(包括“远程视频监控”"语音识别系统"等13个经典例子)
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "stdafx.h"
#include "globals.h"
#include "CPI_Player.h"
#include "CPI_Player_CoDec.h"
#include "CPI_Player_Output.h"
#include "CPI_Equaliser.h"
#define DIRECTSOUND_VERSION 0x0500  
#include <dsound.h> 
#include <math.h> 

#define CPC_OUTPUTBLOCKSIZE			0x10000 
#define CPC_MAXFILLAMOUNT			(CPC_OUTPUTBLOCKSIZE>>4) 
#define CPC_INVALIDCURSORPOS		0xFFFFFFFF

typedef struct __CPs_OutputContext_DirectSound
{
    LPDIRECTSOUNDBUFFER	lpDSB;
    LPDIRECTSOUND lpDirectSound;
    WAVEFORMATEX WaveFile;
    DWORD m_WriteCursor;
    BOOL m_TermState_Wrapped;
    DWORD m_TermState_WriteCursor;
    DWORD m_TermState_HighestPlayPos;
    DWORD m_TimerId;
    BOOL m_bStreamRunning;
    CPs_EqualiserModule* m_pEqualiser;
    BYTE* m_pShadowBuffer;
} CPs_OutputContext_DirectSound;
//
void CPP_OMDS_Initialise(CPs_OutputModule* pModule, const CPs_FileInfo* pFileInfo, CP_HEQUALISER hEqualiser);
void CPP_OMDS_Uninitialise(CPs_OutputModule* pModule);
void CPP_OMDS_RefillBuffers(CPs_OutputModule* pModule);
void CPP_OMDS_SetPause(CPs_OutputModule* pModule, const BOOL bPause);
BOOL CPP_OMDS_IsOutputComplete(CPs_OutputModule* pModule);
void CPP_OMDS_Flush(CPs_OutputModule* pModule);
void CPP_OMDS_SetVolume(CPs_OutputModule* pModule, int iVolume);
void CPP_OMDS_GetVolume(CPs_OutputModule* pModule, int *iVolume, HANDLE waitevent);
void CPP_OMDS_EnablePlay(CPs_OutputModule* pModule, const BOOL bEnable);
void CPP_OMDS_OnEQChanged(CPs_OutputModule* pModule);
void CPP_OMDS_SetInternalVolume(CPs_OutputModule* pModule, const int iNewVolume);
////////////////////////////////////////////////////////////////////////////////

void CPI_Player_Output_Initialise_DirectSound(CPs_OutputModule* pModule)
{
    pModule->Initialise = CPP_OMDS_Initialise;
    pModule->Uninitialise = CPP_OMDS_Uninitialise;
    pModule->RefillBuffers = CPP_OMDS_RefillBuffers;
    pModule->SetPause = CPP_OMDS_SetPause;
    pModule->IsOutputComplete = CPP_OMDS_IsOutputComplete;
    pModule->Flush = CPP_OMDS_Flush;
    pModule->OnEQChanged = CPP_OMDS_OnEQChanged;
    pModule->SetInternalVolume = CPP_OMDS_SetInternalVolume;
    pModule->m_pModuleCookie = NULL;
    pModule->m_pcModuleName = "DirectSound Plugout";
    pModule->m_pCoDec = NULL;
    pModule->m_pEqualiser = NULL;
}
//
void CPP_OMDS_Initialise(CPs_OutputModule* pModule, const CPs_FileInfo* pFileInfo, CP_HEQUALISER hEqualiser)
{
    
    DSBUFFERDESC dsbd;
    HRESULT hrRetVal;

    CPs_OutputContext_DirectSound* pContext;
    CP_ASSERT(pModule->m_pModuleCookie == NULL);
    pContext = (CPs_OutputContext_DirectSound*)malloc(sizeof(CPs_OutputContext_DirectSound));
    pModule->m_pModuleCookie = pContext;
    CP_TRACE0("DirectSound initialising");

    pModule->m_evtBlockFree = CreateEvent(NULL, FALSE, FALSE, NULL);

    if(DirectSoundCreate(NULL,&(pContext->lpDirectSound), NULL))
    {
        CP_FAIL("Cannot create DirectSound Object");
    }

    if(IDirectSound_SetCooperativeLevel(pContext->lpDirectSound, windows.wnd_main, DSSCL_NORMAL))
    {
        CPP_OMDS_Uninitialise(pModule);
        CP_FAIL("Can\'t set DirectSound Cooperative level");
    }

    if(!pContext->lpDirectSound)
    {
        CPP_OMDS_Uninitialise(pModule);
        CP_FAIL("Unable to initialise DirectSound");
    }

    pContext->WaveFile.wFormatTag = WAVE_FORMAT_PCM;
    pContext->WaveFile.nChannels = pFileInfo->m_bStereo ? 2 : 1;
    pContext->WaveFile.nSamplesPerSec = pFileInfo->m_iFreq_Hz;
    pContext->WaveFile.wBitsPerSample = pFileInfo->m_b16bit ? 16 : 8;
    pContext->WaveFile.nBlockAlign = (pContext->WaveFile.nChannels * pContext->WaveFile.wBitsPerSample)>>3;
    pContext->WaveFile.nAvgBytesPerSec = pContext->WaveFile.nSamplesPerSec * pContext->WaveFile.nBlockAlign;
    pContext->WaveFile.cbSize = 0;

    memset(&dsbd, 0, sizeof(DSBUFFERDESC));
    dsbd.dwSize = sizeof(DSBUFFERDESC);
    dsbd.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLVOLUME;
    dsbd.dwBufferBytes = CPC_OUTPUTBLOCKSIZE;
    dsbd.lpwfxFormat = &pContext->WaveFile;
    hrRetVal = IDirectSound_CreateSoundBuffer(pContext->lpDirectSound,
               &dsbd,
               &(pContext->lpDSB),
               NULL);
    if(FAILED(hrRetVal))
    {
        pContext->lpDSB = NULL;
        CP_FAIL("Cannot create soundbuffer");
    }

    {
        BYTE *pbData = NULL;
        DWORD dwLength;

        IDirectSoundBuffer_Lock(pContext->lpDSB,
                                0,
                                CPC_OUTPUTBLOCKSIZE,
                                &pbData,
                                &dwLength,
                                NULL,
                                NULL,
                                0);

        if(pbData)
            memset(pbData, 0, dwLength);

        IDirectSoundBuffer_Unlock(pContext->lpDSB,
                                  pbData,
                                  dwLength,
                                  NULL,
                                  0L);
    }

    pContext->m_WriteCursor = CPC_INVALIDCURSORPOS;
    pContext->m_TermState_Wrapped = FALSE;
    pContext->m_TermState_WriteCursor = CPC_INVALIDCURSORPOS;
    pContext->m_TermState_HighestPlayPos = CPC_INVALIDCURSORPOS;
    pContext->m_TimerId = 0;
    pContext->m_bStreamRunning = FALSE;

    pContext->m_pShadowBuffer = (BYTE*)malloc(CPC_OUTPUTBLOCKSIZE);
    memset(pContext->m_pShadowBuffer, 0, CPC_OUTPUTBLOCKSIZE);

    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
    pModule->m_pEqualiser = hEqualiser;
}
//
void CPP_OMDS_Uninitialise(CPs_OutputModule* pModule)
{
    CPs_OutputContext_DirectSound* pContext = (CPs_OutputContext_DirectSound*)pModule->m_pModuleCookie;
    CP_CHECKOBJECT(pContext);
    CP_TRACE0("DirectSound shutting down");
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);

    if(pContext->lpDSB)
    {
        IDirectSoundBuffer_Release(pContext->lpDSB);
    }

    if(pContext->lpDirectSound)
    {
        IDirectSound_Release(pContext->lpDirectSound);
        DeleteObject(pModule->m_evtBlockFree);
    }

    if(pContext->m_TimerId)
    {
        timeKillEvent(pContext->m_TimerId);
        pContext->m_TimerId = 0;
    }

    pContext->lpDirectSound=NULL;
    pContext->lpDSB=NULL;
    free(pContext->m_pShadowBuffer);
    free(pContext);
    pContext=NULL;
    pModule->m_pModuleCookie = NULL;
}

void GetPlayPosAndInvalidLength(CPs_OutputContext_DirectSound* pContext, DWORD* pdwPlayPos, DWORD* pdwLength)
{
    HRESULT hrResult;

    hrResult = IDirectSoundBuffer_GetCurrentPosition(pContext->lpDSB, pdwPlayPos, NULL);
    if(FAILED(hrResult))
        CP_TRACE0("Failed call to IDirectSoundBuffer_GetCurrentPosition");

    if(pContext->m_WriteCursor != CPC_INVALIDCURSORPOS)
    {
        if(pContext->m_WriteCursor >= *pdwPlayPos)
            *pdwLength = (CPC_OUTPUTBLOCKSIZE - pContext->m_WriteCursor) + *pdwPlayPos;
        else
            *pdwLength = *pdwPlayPos - pContext->m_WriteCursor;
    }
    else
    {
        pContext->m_WriteCursor = 0;
        *pdwLength = CPC_OUTPUTBLOCKSIZE;
    }
}
//

void CPP_OMDS_RefillBuffers(CPs_OutputModule* pModule)
{
    HRESULT	hrRetVal;
    BYTE *pbData;
    DWORD dwLength=0;
    BOOL bMoreData=TRUE;
    DWORD RealLength;
    DWORD dwAmountToFill, dwCurrentPlayCursor;
    CPs_OutputContext_DirectSound* pContext = (CPs_OutputContext_DirectSound*)pModule->m_pModuleCookie;
    CP_CHECKOBJECT(pContext);

    if(!pContext->lpDirectSound)
        return;

    GetPlayPosAndInvalidLength(pContext, &dwCurrentPlayCursor, &dwAmountToFill);

    
    if(dwAmountToFill > CPC_MAXFILLAMOUNT && pContext->m_bStreamRunning == FALSE)
        dwAmountToFill = CPC_MAXFILLAMOUNT;

    
    if(dwAmountToFill > 0)
    {
        hrRetVal = IDirectSoundBuffer_Lock(pContext->lpDSB,
                                           0,
                                           CPC_OUTPUTBLOCKSIZE,

⌨️ 快捷键说明

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