windows-nt/Source/XPSP1/NT/multimedia/directx/dplay/dvoice/dxvutils/dsplayd.cpp
2020-09-26 16:20:57 +08:00

358 lines
9.7 KiB
C++

/*==========================================================================
*
* Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
*
* File: dsplayd.cpp
* Content:
* This module contains the implementation of the
* CDirectSoundPlaybackDevice.
*
* History:
* Date By Reason
* ==== == ======
* 07/16/99 rodtoll Created
* 07/30/99 rodtoll Updated to allow creation of object using a pre-created
* DirectSound Object.
* 10/05/99 rodtoll Added DPF_MODNAMEs
* 10/14/99 rodtoll Added 3d caps to primary buffer created
* 10/27/99 rodtoll Bug #115431: Must release primary buffer
* 11/12/99 rodtoll Modified abstraction for new waveOut support.
* Now abstracted types look almost like dsound objects
* 12/01/99 rodtoll Bug #121815 - Static in playback/record
* Added implementations of Set/GetMixerQuality
* (For Win2k/Millenium/Systems w/DX7)
* 01/27/2000 rodtoll Updated sound classes to accept playback flags,
* buffer structures and DSBUFFERDESC instead of DSBUFFERDESC1
* 02/16/2000 rodtoll Fixed so primary buffer is not released
* 02/17/2000 rodtoll Updated so primary buffer is held instead of released immediately
* 04/21/2000 rodtoll Bug #32952 - Does not run on Win95 GOLD w/o IE4 -- modified
* to allow reads of REG_BINARY when expecting REG_DWORD
* 04/24/2000 rodtoll Bug #33203 - Removed workaround for aureal vortex 1 problem -- had
* problems on Vortex 2.
* 06/09/00 rmt Updates to split CLSID and allow whistler compat and support external create funcs
* 07/12/2000 rodtoll Bug #31468 - Add diagnostic spew to logfile to show what is failing the HW Wizard
* 08/03/2000 rodtoll Bug #41457 - DPVOICE: need way to discover which specific dsound call failed when returning DVERR_SOUNDINITFAILURE
* 08/28/2000 masonb Voice Merge: Changed ccomutil.h to comutil.h
* 04/04/2001 rodtoll WINBUG #343428 - DPVOICE: Voice wizard's playback is very choppy.
*
***************************************************************************/
#include "dxvutilspch.h"
#undef DPF_SUBCOMP
#define DPF_SUBCOMP DN_SUBCOMP_VOICE
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundPlaybackDevice::CDirectSoundPlaybackDevice"
CDirectSoundPlaybackDevice::CDirectSoundPlaybackDevice(
): CAudioPlaybackDevice(), m_hwndOwner(NULL), m_lpdsDirectSound(NULL), m_guidDevice(GUID_NULL), m_lpdsPrimaryBuffer(NULL), m_fEmulated(FALSE)
{
}
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundPlaybackDevice::~CDirectSoundPlaybackDevice"
CDirectSoundPlaybackDevice::~CDirectSoundPlaybackDevice()
{
if( m_lpdsPrimaryBuffer != NULL )
{
m_lpdsPrimaryBuffer->Release();
m_lpdsPrimaryBuffer = NULL;
}
if( m_lpdsDirectSound != NULL )
{
m_lpdsDirectSound->Release();
m_lpdsDirectSound = NULL;
}
}
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundPlaybackDevice::CheckAndSetEmulated"
HRESULT CDirectSoundPlaybackDevice::CheckAndSetEmulated( )
{
HRESULT hr;
DSCAPS dsCaps;
ZeroMemory( &dsCaps, sizeof( DSCAPS ) );
dsCaps.dwSize = sizeof( DSCAPS );
hr = m_lpdsDirectSound->GetCaps( &dsCaps );
if( FAILED( hr ) )
{
m_fEmulated = FALSE;
Diagnostics_Write(DVF_ERRORLEVEL, "Querying for playback caps failed hr=0x%x", hr );
return hr;
}
m_fEmulated = (dsCaps.dwFlags & DSCAPS_EMULDRIVER);
return hr;
}
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundPlaybackDevice::Initialize"
HRESULT CDirectSoundPlaybackDevice::Initialize( LPDIRECTSOUND lpdsDirectSound, const GUID &guidDevice )
{
HRESULT hr;
m_guidDevice = guidDevice;
hr = lpdsDirectSound->QueryInterface( IID_IDirectSound, (void **) &m_lpdsDirectSound );
if( FAILED( hr ) )
{
Diagnostics_Write(DVF_ERRORLEVEL, "DirectSound Object passed failed. 0x%x Creating internal", hr );
m_lpdsDirectSound = NULL;
return hr;
}
hr = CheckAndSetEmulated();
if( FAILED( hr ) )
{
m_lpdsDirectSound->Release();
m_lpdsDirectSound = NULL;
return hr;
}
return DV_OK;
}
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundPlaybackDevice::Initialize"
HRESULT CDirectSoundPlaybackDevice::Initialize( const GUID &guidDevice, HWND hwndOwner, WAVEFORMATEX *lpwfxFormat, BOOL fPriorityMode )
{
HRESULT hr;
DSBUFFERDESC dsbdesc;
DWORD dwPriority;
m_guidDevice = guidDevice;
if( m_lpdsDirectSound != NULL )
{
Diagnostics_Write(DVF_ERRORLEVEL, "Already initialized" );
return DVERR_INITIALIZED;
}
hr = COM_CoCreateInstance( CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER , IID_IDirectSound, (void **) &m_lpdsDirectSound );
DSERTRACK_Update( "DSD::CoCreateInstance()", hr );
if( FAILED( hr ) )
{
Diagnostics_Write(DVF_ERRORLEVEL, "Unable to load directsound hr=0x%x", hr );
goto INITIALIZE_ERROR;
}
hr = m_lpdsDirectSound->Initialize( &guidDevice );
DSERTRACK_Update( "DSD::Initialize()", hr );
if( FAILED( hr ) )
{
Diagnostics_Write(DVF_ERRORLEVEL, "Unable to initialize directsound hr=0x%x", hr );
goto INITIALIZE_ERROR;
}
if( fPriorityMode )
{
dwPriority = DSSCL_PRIORITY;
}
else
{
dwPriority = DSSCL_NORMAL;
}
hr = m_lpdsDirectSound->SetCooperativeLevel( hwndOwner, dwPriority );
DSERTRACK_Update( "DSD::SetCooperativeLevel()", hr );
if( FAILED( hr ) )
{
Diagnostics_Write(DVF_ERRORLEVEL, "Unable to set cooperative level hr=0x%x", hr );
goto INITIALIZE_ERROR;
}
if( fPriorityMode && lpwfxFormat != NULL )
{
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRL3D;
dsbdesc.dwBufferBytes = 0;
dsbdesc.lpwfxFormat = NULL;
hr = m_lpdsDirectSound->CreateSoundBuffer( (DSBUFFERDESC *) &dsbdesc, &m_lpdsPrimaryBuffer, NULL );
DSERTRACK_Update( "DSD::CreateSoundBuffer() (Primary)", hr );
if( FAILED( hr ) )
{
Diagnostics_Write(DVF_ERRORLEVEL, "Create of primary buffer failed. Trying DX5 dsound hr=0x%x", hr );
dsbdesc.dwSize = sizeof( DSBUFFERDESC1 );
hr = m_lpdsDirectSound->CreateSoundBuffer( (DSBUFFERDESC *) &dsbdesc, &m_lpdsPrimaryBuffer, NULL );
}
if( FAILED( hr ) )
{
Diagnostics_Write(DVF_ERRORLEVEL, "Could not create primary sound buffer" );
goto INITIALIZE_ERROR;
}
hr = m_lpdsPrimaryBuffer->SetFormat( lpwfxFormat );
DSERTRACK_Update( "DSD::SetFormat() (Primary)", hr );
if( FAILED( hr ) )
{
Diagnostics_Write(DVF_ERRORLEVEL, "Could not set the format" );
goto INITIALIZE_ERROR;
}
}
m_hwndOwner = hwndOwner;
hr = CheckAndSetEmulated();
if( FAILED( hr ) )
{
Diagnostics_Write(DVF_ERRORLEVEL, "Could not get emulated state hr=0x%x", hr );
goto INITIALIZE_ERROR;
}
return DV_OK;
INITIALIZE_ERROR:
if( m_lpdsPrimaryBuffer )
{
m_lpdsPrimaryBuffer->Release();
m_lpdsPrimaryBuffer = NULL;
}
if( m_lpdsDirectSound != NULL )
{
m_lpdsDirectSound->Release();
m_lpdsDirectSound = NULL;
}
return hr;
}
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundPlaybackDevice::CreateBuffer"
HRESULT CDirectSoundPlaybackDevice::CreateBuffer( LPDSBUFFERDESC lpdsBufferDesc, DWORD dwFrameSize, CAudioPlaybackBuffer **lplpapBuffer )
{
HRESULT hr;
LPDIRECTSOUNDBUFFER lpdsBuffer;
hr = m_lpdsDirectSound->CreateSoundBuffer( (DSBUFFERDESC *) lpdsBufferDesc, &lpdsBuffer, NULL );
DSERTRACK_Update( "DSD::CreateSoundBuffer() ", hr );
if( FAILED( hr ) )
{
lpdsBufferDesc->dwSize = sizeof( DSBUFFERDESC1 );
Diagnostics_Write(DVF_ERRORLEVEL, "Unable to create sound buffer under DX7. Attempting DX5 create hr=0x%x", hr );
hr = m_lpdsDirectSound->CreateSoundBuffer( (DSBUFFERDESC *) lpdsBufferDesc, &lpdsBuffer, NULL );
}
if( FAILED( hr ) )
{
Diagnostics_Write(DVF_ERRORLEVEL, "Failed to create the sound buffer hr=0x%x", hr );
return hr;
}
/*
// Freee wave format
delete dsBufferDesc.lpwfxFormat;
hr = lpdsBuffer->SetFrequency( 8000 );
if( FAILED( hr ) )
{
DPFX(DPFPREP, 0, "Could not set frequency hr=0x%x", hr );
return hr;
}*/
*lplpapBuffer = new CDirectSoundPlaybackBuffer( lpdsBuffer );
lpdsBuffer->Release();
if( *lplpapBuffer == NULL )
{
Diagnostics_Write(DVF_ERRORLEVEL, "Out of memory" );
return DVERR_OUTOFMEMORY;
}
return DV_OK;
}
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundPlaybackDevice::GetPlaybackDevice"
LPDIRECTSOUND CDirectSoundPlaybackDevice::GetPlaybackDevice( )
{
return m_lpdsDirectSound;
}
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundPlaybackDevice::GetMixerQuality"
HRESULT CDirectSoundPlaybackDevice::GetMixerQuality( DIRECTSOUNDMIXER_SRCQUALITY *psrcQuality )
{
HRESULT hr;
LPKSPROPERTYSET pPropertySet = NULL;
hr = DirectSoundPrivateCreate( &pPropertySet );
if( FAILED( hr ) )
{
DPFX(DPFPREP, DVF_WARNINGLEVEL, "Unable to get int to get mixer quality hr=0x%x", hr );
return hr;
}
hr = PrvGetMixerSrcQuality( pPropertySet, m_guidDevice, psrcQuality );
if( FAILED( hr ) )
{
DPFX(DPFPREP, DVF_WARNINGLEVEL, "Unable to retrieve mixer quality hr=0x%x", hr );
}
pPropertySet->Release();
return hr;
}
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundPlaybackDevice::SetMixerQuality"
HRESULT CDirectSoundPlaybackDevice::SetMixerQuality( const DIRECTSOUNDMIXER_SRCQUALITY srcQuality )
{
HRESULT hr;
LPKSPROPERTYSET pPropertySet = NULL;
hr = DirectSoundPrivateCreate( &pPropertySet );
if( FAILED( hr ) )
{
DPFX(DPFPREP, DVF_WARNINGLEVEL, "Unable to get int to set mixer quality hr=0x%x", hr );
return hr;
}
hr = PrvSetMixerSrcQuality( pPropertySet, m_guidDevice, srcQuality );
if( FAILED( hr ) )
{
DPFX(DPFPREP, DVF_WARNINGLEVEL, "Unable to set mixer quality hr=0x%x", hr );
}
pPropertySet->Release();
return hr;
}