📄 cpi_player_output_directsound.c
字号:
#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 + -