📄 dsound_buf.cpp
字号:
/*////////////////////////////////////////////////////////////////////////////////// INTEL CORPORATION PROPRIETARY INFORMATION// This software is supplied under the terms of a license agreement or// nondisclosure agreement with Intel Corporation and may not be copied// or disclosed except in accordance with the terms of that agreement.// Copyright(c) 2003-2005 Intel Corporation. All Rights Reserved.//*/#include "umc_defs.h"#if defined UMC_ENABLE_DSOUND_AUDIO_RENDER#include <vm_debug.h>#include "ipps.h"#include "vm_debug.h"#include "dsound_buf.h"UMC::StatusUMC::DSBuffer::Init(const HWND hWnd, const DWORD dwBufferSize, const WORD wChannels, const DWORD dwFrequency, const WORD wBytesPerSample){ Status umcRes = UMC_OK; assert(0 != dwBufferSize); assert(0 != wChannels); assert(0 != dwFrequency); assert(0 != wBytesPerSample); Close(); m_dwInitedBufferSize = dwBufferSize; m_wInitedChannels = wChannels; m_dwInitedFrequency = dwFrequency; m_wInitedBytesPerSample = wBytesPerSample; if (UMC_OK == umcRes) { m_hWnd = hWnd; if (NULL == m_hWnd) { umcRes = UMC_OPERATION_FAILED; } } if (UMC_OK == umcRes) { HRESULT hRes = DirectSoundCreate8( NULL, &m_pDS, NULL ); if (FAILED(hRes)) { vm_debug_msg(0x1, VM_STRING("Failed to initialize DirectSound 8 @DirectSoundRender")); umcRes = UMC_OPERATION_FAILED; } } if(UMC_OK == umcRes && FAILED(m_pDS->SetCooperativeLevel(m_hWnd, DSSCL_PRIORITY))) { umcRes = UMC_OPERATION_FAILED;} DSBUFFERDESC dsbd; // Get the primary buffer if(UMC_OK == umcRes) { ippsZero_8u( (Ipp8u*)&dsbd, sizeof(DSBUFFERDESC) ); dsbd.dwSize = sizeof(DSBUFFERDESC); dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER; dsbd.dwBufferBytes = 0; dsbd.lpwfxFormat = NULL; if( FAILED(m_pDS->CreateSoundBuffer( &dsbd, &m_pDSBPrimary, NULL ) ) ) { vm_debug_msg( -1, VM_STRING("Failed to create DirectSound primary buffer @Open")); umcRes = UMC_FAILED_TO_ALLOCATE_BUFFER; } } // Set primary buffer format WAVEFORMATEX wfx; if(UMC_OK == umcRes) { ippsZero_8u( (Ipp8u*)&wfx, sizeof(WAVEFORMATEX) ); wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nChannels = wChannels; wfx.nSamplesPerSec = dwFrequency; wfx.wBitsPerSample = (WORD)(wBytesPerSample << 3); wfx.nBlockAlign = (WORD) (wfx.wBitsPerSample / 8 * wfx.nChannels); wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; if( FAILED(m_pDSBPrimary->SetFormat(&wfx) ) ) { vm_debug_msg(-1, VM_STRING("Failed to set PCM format for DirectSound primary buffer @Open")); umcRes = UMC_FAILED_TO_OPEN_DEVICE; } } // Create Secondary buffer if(UMC_OK == umcRes) { dsbd.dwSize = sizeof(DSBUFFERDESC); dsbd.dwFlags = DSBCAPS_GLOBALFOCUS|DSBCAPS_CTRLVOLUME| DSBCAPS_CTRLFREQUENCY|DSBCAPS_GETCURRENTPOSITION2; dsbd.dwBufferBytes = dwBufferSize; dsbd.lpwfxFormat = &wfx; if( FAILED(m_pDS->CreateSoundBuffer( &dsbd, &m_pDSBSecondary, NULL ))) { vm_debug_msg(-1, VM_STRING("Failed to create DirectSound secondary buffer @Open")); umcRes = UMC_FAILED_TO_ALLOCATE_BUFFER; } } if(UMC_OK == umcRes) { void *lock1_ptr, *lock2_ptr; DWORD lock1_bytes, lock2_bytes; if (FAILED(m_pDSBSecondary->Lock(0,m_dwDSBufferSize, &lock1_ptr,&lock1_bytes, &lock2_ptr,&lock2_bytes, DSBLOCK_ENTIREBUFFER))) { vm_debug_msg(-1, VM_STRING("Failed to lock DirectSound secondary buffer @Open")); umcRes = UMC_FAILED_TO_OPEN_DEVICE; } else { ippsZero_8u((Ipp8u*)lock1_ptr,lock1_bytes); m_pDSBSecondary->Unlock(lock1_ptr,lock1_bytes,lock2_ptr,0); } } DSCAPS dscaps = {0}; if(UMC_OK == umcRes) { ippsZero_8u( (Ipp8u*)&dscaps, sizeof(DSCAPS) ); dscaps.dwSize = sizeof(DSCAPS); if (FAILED(m_pDS->GetCaps(&dscaps))) { umcRes = UMC_OPERATION_FAILED; } } if(UMC_OK == umcRes) { m_dfCompensation = (dscaps.dwFlags & DSCAPS_EMULDRIVER)?0.020:0.005; m_dfNorm = 1.0/dwFrequency/wBytesPerSample/wChannels; m_dwNextWriteOffset = 0; } if (UMC_OK == umcRes) { m_dwDSBufferSize = dwBufferSize; m_bPausedWaitingData = true; } else { Close(); } return umcRes;}UMC::StatusUMC::DSBuffer::GetPlayPos(DWORD& rdwPos){ if (!m_pDSBSecondary) { return UMC_OPERATION_FAILED; } m_MutAccess.Lock(); Status umcRes = (m_pDSBSecondary) ? UMC_OK : UMC_NOT_INITIALIZED; if (UMC_OK == umcRes && FAILED(m_pDSBSecondary->GetCurrentPosition(&rdwPos, NULL))) { rdwPos = 0xFFFFFFFF; umcRes = UMC_OPERATION_FAILED; } m_MutAccess.Unlock(); return umcRes;}UMC::StatusUMC::DSBuffer::GetWritePos(DWORD& rdwPos){ if (!m_pDSBSecondary) { return UMC_OPERATION_FAILED; } m_MutAccess.Lock(); Status umcRes = (m_pDSBSecondary) ? UMC_OK : UMC_NOT_INITIALIZED; if (UMC_OK == umcRes && FAILED(m_pDSBSecondary->GetCurrentPosition(NULL, &rdwPos))) { rdwPos = 0xFFFFFFFF; umcRes = UMC_OPERATION_FAILED; } m_MutAccess.Unlock(); return umcRes;}UMC::StatusUMC::DSBuffer::CopyDataToBuffer(unsigned char* pucData, DWORD dwLength, DWORD& rdwBytesWrote){ void *lock1_ptr = NULL; void *lock2_ptr = NULL; DWORD lock1_bytes = 0; DWORD lock2_bytes = 0; HRESULT hRes = DS_OK; if (!m_pDSBSecondary) { return UMC_OPERATION_FAILED; } m_MutAccess.Lock(); Status umcRes = (NULL != m_pDSBSecondary) ? UMC_OK : UMC_NOT_INITIALIZED; if (UMC_OK == umcRes) { hRes = m_pDSBSecondary->Lock(m_dwNextWriteOffset, min(dwLength,m_dwDSBufferSize), &lock1_ptr, &lock1_bytes, &lock2_ptr, &lock2_bytes, 0); if (DSERR_BUFFERLOST == hRes) { m_pDSBSecondary->Restore(); hRes = m_pDSBSecondary->Lock(m_dwNextWriteOffset, min(dwLength,m_dwDSBufferSize), &lock1_ptr, &lock1_bytes, &lock2_ptr, &lock2_bytes, 0); } if (DS_OK != hRes) { umcRes = UMC_OPERATION_FAILED; } } if (UMC_OK == umcRes) { ippsCopy_8u(pucData, (Ipp8u*)lock1_ptr, lock1_bytes); hRes = m_pDSBSecondary->Unlock(lock1_ptr, lock1_bytes, lock2_ptr,0); if (DS_OK != hRes) { umcRes = UMC_OPERATION_FAILED; } } if (UMC_OK == umcRes) { m_dwNextWriteOffset = (m_dwNextWriteOffset + lock1_bytes) % m_dwDSBufferSize; rdwBytesWrote = lock1_bytes; } if (UMC_OK == umcRes && m_bPausedWaitingData && (m_dwDSBufferSize /2 < m_dwNextWriteOffset || (0 == m_dwNextWriteOffset && 0 != rdwBytesWrote))) { if (FAILED(m_pDSBSecondary->Play( 0, 0, DSBPLAY_LOOPING))) { umcRes = UMC_OPERATION_FAILED; } else { m_bPausedWaitingData = false; } } m_MutAccess.Unlock(); return umcRes;}UMC::StatusUMC::DSBuffer::Pause(bool bPause){ if (!m_pDSBSecondary) { return UMC_OPERATION_FAILED; } m_MutAccess.Lock(); Status umcRes = (NULL != m_pDSBSecondary) ? UMC_OK : UMC_NOT_INITIALIZED; if (UMC_OK == umcRes) { if(bPause) { if (FAILED(m_pDSBSecondary->Stop()))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -