|
|
/*==========================================================================
* * Copyright (C) 1999 Microsoft Corporation. All Rights Reserved. * * File: dscrecb.cpp * Content: * This module contains the implementation of the * CDirectSoundCaptureRecordBuffer. * * History: * Date By Reason * ==== == ====== * 11/04/99 rodtoll Created * 11/22/99 rodtoll Added code to allow specification of wave device ID * 11/23/99 rodtoll Updated to use waveIn device ID or DSound 7.1 when they are avail * rodtoll Updated with new Microphone select member * 12/08/99 rodtoll Bug #115783 - Will always adjust volume of default device * Now uses new CMixerLine class for adjusting volumes/selecting mic * 12/08/99 rodtoll Bug #121054 - DirectX 7.1 support. * - Added hwndOwner param for capture focus support * - Added lpfLostFocus param to GetCurrentPosition so upper * layers can detect lost focus. * 01/28/2000 rodtoll Bug #130465: Record Mute/Unmute must call YieldFocus() / ClaimFocus() * 02/10/2000 rodtoll Removed more capture focus code * 04/19/2000 rodtoll Re-enabled capture focus behaviour * 08/03/2000 rodtoll Bug #41457 - DPVOICE: need way to discover which specific dsound call failed when returning DVERR_SOUNDINITFAILURE * 04/22/2001 rodtoll Fixed bug in lockup simulation code (TESTING PURPOSES ONLY) * ***************************************************************************/
#include "dxvutilspch.h"
#undef DPF_SUBCOMP
#define DPF_SUBCOMP DN_SUBCOMP_VOICE
#define DSC_STARTUP_LATENCY 1
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::CDirectSoundCaptureRecordBuffer"
CDirectSoundCaptureRecordBuffer::CDirectSoundCaptureRecordBuffer( LPDIRECTSOUNDCAPTUREBUFFER lpdscBuffer, HWND hwndOwner, const GUID &guidDevice, UINT uiWaveDeviceID, const DSCBUFFERDESC * lpdsBufferDesc ): CAudioRecordBuffer(), m_lpwfxRecordFormat(NULL), m_lpdscBuffer7(NULL), m_guidDevice(guidDevice), m_uiWaveDeviceID(uiWaveDeviceID), #ifdef LOCKUP_SIMULATION
m_dwNumSinceLastLockup(0), m_dwLastPosition(0), #endif
m_hwndOwner(hwndOwner), m_fUseCaptureFocus( FALSE ) { HRESULT hr; DWORD dwSize;
if( lpdsBufferDesc->dwFlags & DSCBCAPS_FOCUSAWARE ) { DPFX(DPFPREP, 1, "Enabling focus" ); m_fUseCaptureFocus = TRUE; } else { DPFX(DPFPREP, 1, "Disabling focus" ); m_fUseCaptureFocus = FALSE; } hr = lpdscBuffer->QueryInterface( IID_IDirectSoundCaptureBuffer, (void **) &m_lpdscBuffer );
if( FAILED( hr ) ) { DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to get dsound buffer interface" ); m_lpdscBuffer = NULL; return; }
hr = lpdscBuffer->QueryInterface( IID_IDirectSoundCaptureBuffer7_1, (void **) &m_lpdscBuffer7 );
if( FAILED( hr ) ) { DPFX(DPFPREP, DVF_WARNINGLEVEL, "Could not retrieve new interface hr=0x%x.", hr );
hr = m_mixerLine.Initialize( m_uiWaveDeviceID );
if( FAILED( hr ) ) { DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to acquire volume controls hr=0x%x", hr ); DNASSERT( FALSE ); } } else { if( m_fUseCaptureFocus ) { hr = m_lpdscBuffer7->SetFocusHWND( hwndOwner );
if( FAILED( hr ) ) { DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to set the focus window hr = 0x%x", hr ); DNASSERT( FALSE ); } } }
hr = lpdscBuffer->GetFormat( NULL, 0, &dwSize );
m_lpwfxRecordFormat = (LPWAVEFORMATEX) new BYTE[dwSize];
if( m_lpwfxRecordFormat == NULL ) { DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to allocate space for record format" ); DNASSERT( FALSE ); }
hr = lpdscBuffer->GetFormat( m_lpwfxRecordFormat, dwSize, NULL );
if( FAILED( hr ) ) { delete [] ((LPBYTE) m_lpwfxRecordFormat); m_lpwfxRecordFormat = NULL; }
}
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::~CDirectSoundCaptureRecordBuffer"
CDirectSoundCaptureRecordBuffer::~CDirectSoundCaptureRecordBuffer() { if( m_lpdscBuffer7 != NULL ) { m_lpdscBuffer7->Release(); } if( m_lpdscBuffer != NULL ) { m_lpdscBuffer->Release(); }
if( m_lpwfxRecordFormat != NULL ) { delete [] ((LPBYTE) m_lpwfxRecordFormat); } }
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::Lock"
HRESULT CDirectSoundCaptureRecordBuffer::Lock( DWORD dwWriteCursor, DWORD dwWriteBytes, LPVOID *lplpvBuffer1, LPDWORD lpdwSize1, LPVOID *lplpvBuffer2, LPDWORD lpdwSize2, DWORD dwFlags ) { HRESULT hr; if( m_lpdscBuffer == NULL ) { DPFX(DPFPREP, DVF_ERRORLEVEL, "No DirectSoundCapture Buffer Available" ); return DVERR_NOTINITIALIZED; }
hr = m_lpdscBuffer->Lock( dwWriteCursor, dwWriteBytes, lplpvBuffer1, lpdwSize1, lplpvBuffer2, lpdwSize2, dwFlags );
DSERTRACK_Update( "DSCB::Lock()", hr );
return hr; }
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::UnLock"
HRESULT CDirectSoundCaptureRecordBuffer::UnLock( LPVOID lpvBuffer1, DWORD dwSize1, LPVOID lpvBuffer2, DWORD dwSize2 ) { HRESULT hr; if( m_lpdscBuffer == NULL ) { DPFX(DPFPREP, DVF_ERRORLEVEL, "No DirectSoundCapture Buffer Available" ); return DVERR_NOTINITIALIZED; }
hr = m_lpdscBuffer->Unlock( lpvBuffer1, dwSize1, lpvBuffer2, dwSize2 );
return hr; }
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::SetVolume"
HRESULT CDirectSoundCaptureRecordBuffer::SetVolume( LONG lVolume ) { if( m_lpdscBuffer == NULL ) { DPFX(DPFPREP, DVF_ERRORLEVEL, "No DirectSoundCapture Buffer Available" ); return DVERR_NOTINITIALIZED; }
HRESULT hr;
if( m_lpdscBuffer7 != NULL ) { hr = m_lpdscBuffer7->SetVolume( lVolume ); } else { hr = m_mixerLine.SetMasterRecordVolume( lVolume ); }
// This is only a warning condition
if( FAILED( hr ) ) { DPFX(DPFPREP, DVF_INFOLEVEL, "Could not set master volume hr=0x%x", hr ); }
if( m_lpdscBuffer7 != NULL ) { hr = m_lpdscBuffer7->SetMicVolume( lVolume ); } else { hr = m_mixerLine.SetMicrophoneVolume( lVolume ); }
if( FAILED( hr ) ) { DPFX(DPFPREP, DVF_INFOLEVEL, "Unable to set Microphone volume hr=0x%x", hr ); return hr; } return DV_OK; }
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::GetVolume"
HRESULT CDirectSoundCaptureRecordBuffer::GetVolume( LPLONG lplVolume ) { if( m_lpdscBuffer == NULL ) { DPFX(DPFPREP, DVF_ERRORLEVEL, "No DirectSoundCapture Buffer Available" ); return DVERR_NOTINITIALIZED; }
HRESULT hr; if( m_lpdscBuffer7 != NULL ) { hr = m_lpdscBuffer7->GetMicVolume( lplVolume ); } else { hr = m_mixerLine.GetMicrophoneVolume( lplVolume ); }
if( FAILED( hr ) ) { DPFX(DPFPREP, DVF_WARNINGLEVEL, "Unable to get Microphone volume hr=0x%x", hr );
if( m_lpdscBuffer7 != NULL ) { hr = m_lpdscBuffer7->GetVolume( lplVolume ); } else { hr = m_mixerLine.GetMasterRecordVolume( lplVolume ); }
// This is only a warning condition
if( FAILED( hr ) ) { DPFX(DPFPREP, DVF_WARNINGLEVEL, "Could not get master record volume hr=0x%x", hr ); return hr; }
return hr; }
return hr; }
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::GetCurrentPosition"
HRESULT CDirectSoundCaptureRecordBuffer::GetCurrentPosition( LPDWORD lpdwPosition, LPBOOL lpfLostFocus ) { if( m_lpdscBuffer == NULL ) { DPFX(DPFPREP, DVF_ERRORLEVEL, "No DirectSoundCapture Buffer Available" ); return DVERR_NOTINITIALIZED; }
#ifdef LOCKUP_SIMULATION
m_dwNumSinceLastLockup++;
if( m_dwNumSinceLastLockup > LOCKUP_NUM_CALLS_BEFORE_LOCKUP ) { *lpdwPosition = m_dwLastPosition; *lpfLostFocus = FALSE; return DV_OK; } #endif
HRESULT hr;
if( m_lpdscBuffer7 != NULL && m_fUseCaptureFocus ) { DWORD dwStatus; hr = m_lpdscBuffer7->GetStatus( &dwStatus );
if( FAILED( hr ) ) { DPFX(DPFPREP, DVF_ERRORLEVEL, "Error getting status hr=0x%x", hr ); *lpfLostFocus = FALSE; } else { *lpfLostFocus = (dwStatus & DSCBSTATUS_LOSTFOCUS) ? TRUE : FALSE; } } else { *lpfLostFocus = FALSE; }
hr = m_lpdscBuffer->GetCurrentPosition( NULL, lpdwPosition );
#ifdef LOCKUP_SIMULATION
m_dwLastPosition = *lpdwPosition; #endif
DSERTRACK_Update( "DSCB::GetCurrentPosition()", hr );
return hr;
}
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::Play"
HRESULT CDirectSoundCaptureRecordBuffer::Record( BOOL fLooping ) { if( m_lpdscBuffer == NULL ) { DPFX(DPFPREP, DVF_ERRORLEVEL, "No DirectSound Buffer Available" ); return DVERR_NOTINITIALIZED; }
HRESULT hr;
hr = m_lpdscBuffer->Start( (fLooping) ? DSCBSTART_LOOPING : 0 );
#ifdef LOCKUP_SIMULATION
#ifdef LOCKUP_STOPFAIL
if( m_dwNumSinceLastLockup > LOCKUP_NUM_CALLS_BEFORE_LOCKUP ) { hr = DSERR_GENERIC; } #else
m_dwNumSinceLastLockup = 0; #endif
#endif
DSERTRACK_Update( "DSCB::Start()", hr );
return hr; }
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::Stop"
HRESULT CDirectSoundCaptureRecordBuffer::Stop() { if( m_lpdscBuffer == NULL ) { DPFX(DPFPREP, DVF_ERRORLEVEL, "No DirectSound Buffer Available" ); return DVERR_NOTINITIALIZED; }
HRESULT hr;
hr = m_lpdscBuffer->Stop( );
#ifdef LOCKUP_SIMULATION
#ifdef LOCKUP_STOPFAIL
if( m_dwNumSinceLastLockup > LOCKUP_NUM_CALLS_BEFORE_LOCKUP ) { hr = DSERR_GENERIC; } #endif
#endif
DSERTRACK_Update( "DSCB::Stop()", hr );
return hr; }
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::GetStartupLatency"
DWORD CDirectSoundCaptureRecordBuffer::GetStartupLatency() { return DSC_STARTUP_LATENCY; }
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::GetRecordFormat"
LPWAVEFORMATEX CDirectSoundCaptureRecordBuffer::GetRecordFormat() { return m_lpwfxRecordFormat; }
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::SelectMicrophone"
HRESULT CDirectSoundCaptureRecordBuffer::SelectMicrophone( BOOL fSelect ) { if( m_lpdscBuffer7 != NULL ) { return m_lpdscBuffer7->EnableMic( fSelect ); } else { return m_mixerLine.EnableMicrophone( fSelect ); } }
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::ClaimFocus"
HRESULT CDirectSoundCaptureRecordBuffer::ClaimFocus( ) { if( m_lpdscBuffer7 != NULL && m_fUseCaptureFocus) { return m_lpdscBuffer7->ClaimFocus(); } else { return DVERR_NOTSUPPORTED; } }
#undef DPF_MODNAME
#define DPF_MODNAME "CDirectSoundCaptureRecordBuffer::YieldFocus"
HRESULT CDirectSoundCaptureRecordBuffer::YieldFocus( ) { if( m_lpdscBuffer7 != NULL && m_fUseCaptureFocus ) { return m_lpdscBuffer7->YieldFocus(); } else { return DVERR_NOTSUPPORTED; } }
|