541 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			541 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*==========================================================================
 | 
						|
 *
 | 
						|
 *  Copyright (C) 1999 Microsoft Corporation.  All Rights Reserved.
 | 
						|
 *
 | 
						|
 *  File:		wirecb.cpp
 | 
						|
 *  Content:
 | 
						|
 *		This module contains the implementation of the CWaveInRecordBuffer
 | 
						|
 *		class.  
 | 
						|
 *		
 | 
						|
 *  History:
 | 
						|
 *   Date		By		Reason
 | 
						|
 *   ====		==		======
 | 
						|
 * 11/04/99		rodtoll	Created
 | 
						|
 * 11/18/99		rodtoll	Fixed bug which causes lockup when stopping a buffer then 
 | 
						|
 *				 		restarting it.
 | 
						|
 * 11/23/99		rodtoll	Added SelectMicrophone call to the interface 
 | 
						|
 * 12/01/99		rodtoll	Bug #115783 - Always adjusts default device.
 | 
						|
 *						Added support for new mixerline class which supports
 | 
						|
 *						proper selection of devices/adjusting of volumes 
 | 
						|
 * 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/14/2000	rodtoll	Updated to use DWORD_PTR to allow proper 64-bit operation  
 | 
						|
 * 01/28/2000	rodtoll	Bug #130465: Record Mute/Unmute must call YieldFocus() / ClaimFocus() 
 | 
						|
 *
 | 
						|
 ***************************************************************************/
 | 
						|
 | 
						|
#include "stdafx.h"
 | 
						|
#include "wirecd.h"
 | 
						|
#include "dndbg.h"
 | 
						|
#include "OSInd.h"
 | 
						|
#include "wirecb.h"
 | 
						|
#include "dvoice.h"
 | 
						|
#include "micutils.h"
 | 
						|
 | 
						|
#define WAVEIN_STARTLATENCY		2
 | 
						|
 | 
						|
#define WIFAILED( x )  (x != MMSYSERR_NOERROR)
 | 
						|
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define DPF_MODNAME "CWaveInRecordBuffer::GetStartupLatency"
 | 
						|
DWORD CWaveInRecordBuffer::GetStartupLatency()
 | 
						|
{
 | 
						|
	return WAVEIN_STARTLATENCY;
 | 
						|
}
 | 
						|
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define DPF_MODNAME "CWaveInRecordBuffer::CWaveInRecordBuffer"
 | 
						|
CWaveInRecordBuffer::CWaveInRecordBuffer(
 | 
						|
): CAudioRecordBuffer(), m_hwiDevice(NULL), m_uDeviceID(0), m_dwCurrentPosition(0),
 | 
						|
   m_lpWaveHeaders(NULL), m_dwBufferSize(0), m_dwNumBuffers(0), m_dwFrameSize(0),
 | 
						|
   m_fRecording(FALSE), m_lpbShadowBuffer(NULL), m_dwShadowStart(0), 
 | 
						|
   m_hFrameProcessed(NULL), m_lpwfxRecordFormat(NULL),
 | 
						|
   m_fStopping( FALSE )
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define DPF_MODNAME "CWaveInRecordBuffer::~CWaveInRecordBuffer"
 | 
						|
CWaveInRecordBuffer::~CWaveInRecordBuffer()
 | 
						|
{
 | 
						|
	// Stop the buffers and unprepare them if they are prepared
 | 
						|
	Stop();
 | 
						|
	
 | 
						|
	if( m_dwNumBuffers )
 | 
						|
	{
 | 
						|
		for( DWORD dwIndex = 0; dwIndex < m_dwNumBuffers; dwIndex++ )
 | 
						|
		{
 | 
						|
			delete [] ((LPBYTE) m_lpWaveHeaders[dwIndex].lpData);
 | 
						|
		}
 | 
						|
 | 
						|
		delete [] m_lpWaveHeaders;
 | 
						|
	}
 | 
						|
 | 
						|
	// Close the device
 | 
						|
	if( m_hwiDevice != NULL )
 | 
						|
	{
 | 
						|
		waveInClose( m_hwiDevice );
 | 
						|
	}
 | 
						|
	
 | 
						|
	if( m_lpbShadowBuffer != NULL )
 | 
						|
	{
 | 
						|
		delete [] m_lpbShadowBuffer;
 | 
						|
	}
 | 
						|
 | 
						|
	CloseHandle( m_hFrameProcessed );
 | 
						|
}
 | 
						|
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define DPF_MODNAME "CWaveInRecordBuffer::Initialize"
 | 
						|
HRESULT CWaveInRecordBuffer::Initialize( UINT uDeviceID, LPDSCBUFFERDESC lpdscDesc, DWORD dwFrameSize )
 | 
						|
{
 | 
						|
	HRESULT hr;
 | 
						|
	DWORD dwIndex;
 | 
						|
 | 
						|
	m_hFrameProcessed = CreateEvent( NULL, FALSE, FALSE, NULL );
 | 
						|
 | 
						|
	if( m_hFrameProcessed == NULL )
 | 
						|
	{
 | 
						|
		DPFX(DPFPREP,  DVF_ERRORLEVEL, "Unable to create event" );
 | 
						|
		return DVERR_GENERIC;
 | 
						|
	}
 | 
						|
 | 
						|
	hr = m_mixerLine.Initialize( uDeviceID );
 | 
						|
 | 
						|
	if( FAILED( hr ) )
 | 
						|
	{
 | 
						|
		DPFX(DPFPREP,  DVF_ERRORLEVEL, "Unable to acquire volume controls" );
 | 
						|
		return hr;
 | 
						|
	}		
 | 
						|
 | 
						|
	hr = waveInOpen( &m_hwiDevice, uDeviceID, lpdscDesc->lpwfxFormat, (DWORD_PTR) WaveInHandler, (DWORD_PTR) this, CALLBACK_FUNCTION ) ; 
 | 
						|
 | 
						|
	if( WIFAILED( hr ) )
 | 
						|
	{
 | 
						|
		DPFX(DPFPREP,  DVF_ERRORLEVEL, "Unable to open waveIn Device (mmresult) hr=0x%x", hr );
 | 
						|
		return DVERR_RECORDSYSTEMERROR;
 | 
						|
	}
 | 
						|
 | 
						|
	m_dwNumBuffers = lpdscDesc->dwBufferBytes / dwFrameSize;	
 | 
						|
 | 
						|
	m_lpWaveHeaders = new WAVEHDR[m_dwNumBuffers];
 | 
						|
 | 
						|
	if( m_lpWaveHeaders == NULL )
 | 
						|
	{
 | 
						|
		DPFX(DPFPREP,  DVF_ERRORLEVEL, "Out of memory" );
 | 
						|
		hr = DVERR_OUTOFMEMORY;
 | 
						|
 | 
						|
		goto INITIALIZE_ERROR;
 | 
						|
	}
 | 
						|
 | 
						|
	for( dwIndex = 0; dwIndex < m_dwNumBuffers; dwIndex++ )
 | 
						|
	{
 | 
						|
		m_lpWaveHeaders[dwIndex].lpData = (LPSTR) new BYTE[dwFrameSize];
 | 
						|
 | 
						|
		if( m_lpWaveHeaders[dwIndex].lpData == NULL )
 | 
						|
		{
 | 
						|
			DPFX(DPFPREP,  DVF_ERRORLEVEL, "Out of memory" );
 | 
						|
 | 
						|
			// Make sure rest of buffer pointers are NULL;
 | 
						|
			for( ; dwIndex < m_dwNumBuffers; dwIndex++ )
 | 
						|
			{
 | 
						|
				m_lpWaveHeaders[dwIndex].lpData = NULL;
 | 
						|
			}
 | 
						|
 | 
						|
			hr = DVERR_OUTOFMEMORY;
 | 
						|
 | 
						|
			goto INITIALIZE_ERROR;
 | 
						|
		}
 | 
						|
 | 
						|
		if( lpdscDesc->lpwfxFormat->wBitsPerSample == 8  )
 | 
						|
		{
 | 
						|
			memset( m_lpWaveHeaders[dwIndex].lpData, 0x80, dwFrameSize );
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
			memset( m_lpWaveHeaders[dwIndex].lpData, 0x00, dwFrameSize );		
 | 
						|
		}
 | 
						|
 | 
						|
		m_lpWaveHeaders[dwIndex].dwBufferLength = dwFrameSize;
 | 
						|
		m_lpWaveHeaders[dwIndex].dwBytesRecorded = 0;
 | 
						|
 | 
						|
		// Used to specify buffer location when this buffer is complete
 | 
						|
		if( dwIndex == (m_dwNumBuffers-1))
 | 
						|
		{
 | 
						|
			m_lpWaveHeaders[dwIndex].dwUser = 0;
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
			m_lpWaveHeaders[dwIndex].dwUser = dwFrameSize*(dwIndex+1);		
 | 
						|
		}
 | 
						|
		
 | 
						|
		m_lpWaveHeaders[dwIndex].dwFlags = 0; 
 | 
						|
		m_lpWaveHeaders[dwIndex].dwLoops = 0;
 | 
						|
		m_lpWaveHeaders[dwIndex].lpNext = NULL;
 | 
						|
		m_lpWaveHeaders[dwIndex].reserved = 0;
 | 
						|
	}
 | 
						|
 | 
						|
	m_lpbShadowBuffer = new BYTE[lpdscDesc->dwBufferBytes];
 | 
						|
 | 
						|
	m_lpwfxRecordFormat = lpdscDesc->lpwfxFormat;
 | 
						|
	m_uDeviceID = uDeviceID;
 | 
						|
	m_dwFrameSize = dwFrameSize;
 | 
						|
	m_dwCurrentPosition = 0;
 | 
						|
	m_dwBufferSize = lpdscDesc->dwBufferBytes;
 | 
						|
	m_fRecording = FALSE;
 | 
						|
 | 
						|
	return DV_OK;
 | 
						|
 | 
						|
INITIALIZE_ERROR:
 | 
						|
 | 
						|
	if( m_lpbShadowBuffer != NULL )
 | 
						|
	{
 | 
						|
		delete [] m_lpbShadowBuffer;
 | 
						|
		m_lpbShadowBuffer = NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	if( m_lpWaveHeaders != NULL )
 | 
						|
	{
 | 
						|
		for( dwIndex = 0; dwIndex < m_dwNumBuffers; dwIndex++ )
 | 
						|
		{
 | 
						|
			if( m_lpWaveHeaders[dwIndex].lpData != NULL )
 | 
						|
			{
 | 
						|
				delete [] ((LPBYTE) m_lpWaveHeaders[dwIndex].lpData);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		delete [] m_lpWaveHeaders;
 | 
						|
		m_lpWaveHeaders = NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	if( m_hwiDevice != NULL )
 | 
						|
	{
 | 
						|
		waveInClose( m_hwiDevice );
 | 
						|
		m_hwiDevice = NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	return hr;
 | 
						|
}
 | 
						|
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define DPF_MODNAME "CWaveInRecordBuffer::WaveInHandler"
 | 
						|
void CWaveInRecordBuffer::WaveInHandler( HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 )
 | 
						|
{
 | 
						|
	CWaveInRecordBuffer *This = (CWaveInRecordBuffer *) dwInstance;
 | 
						|
	
 | 
						|
	DNASSERT( This != NULL );
 | 
						|
 | 
						|
	HRESULT hr;
 | 
						|
 | 
						|
	DPFX(DPFPREP,  DVF_INFOLEVEL, "WaveInHandler: Wakeup" );
 | 
						|
	
 | 
						|
	if( uMsg == WIM_DATA && !This->m_fStopping)
 | 
						|
	{
 | 
						|
		WAVEHDR *lpWaveHeader = (WAVEHDR *) dwParam1;
 | 
						|
 | 
						|
		hr = waveInUnprepareHeader( This->m_hwiDevice, lpWaveHeader, sizeof( WAVEHDR ) );
 | 
						|
 | 
						|
		if( WIFAILED( hr ) )
 | 
						|
		{
 | 
						|
			DPFX(DPFPREP,  DVF_ERRORLEVEL, "Error unpreparing header (mmresult) hr=0x%x", hr );
 | 
						|
			return;
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
			DPFX(DPFPREP,  DVF_INFOLEVEL, "WaveInHandler: Unpreparing for location: %d", lpWaveHeader->dwUser );
 | 
						|
		}
 | 
						|
 | 
						|
		This->m_dwCurrentPosition = lpWaveHeader->dwUser;
 | 
						|
 | 
						|
		if( !This->m_fRecording )
 | 
						|
		{
 | 
						|
			SetEvent( This->m_hFrameProcessed );
 | 
						|
			DPFX(DPFPREP,  DVF_INFOLEVEL, "WaveInHandler: Signalling single frame done" );
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define DPF_MODNAME "CWaveInRecordBuffer::Lock"
 | 
						|
HRESULT CWaveInRecordBuffer::Lock( DWORD dwWriteCursor, DWORD dwWriteBytes, LPVOID *lplpvBuffer1, LPDWORD lpdwSize1, LPVOID *lplpvBuffer2, LPDWORD lpdwSize2, DWORD dwFlags )
 | 
						|
{
 | 
						|
	*lpdwSize2 = 0;
 | 
						|
	*lplpvBuffer2 = NULL;
 | 
						|
 | 
						|
	// Special case for the entire buffer
 | 
						|
	if( dwFlags & DSCBLOCK_ENTIREBUFFER )
 | 
						|
	{
 | 
						|
		if( m_fRecording )
 | 
						|
		{
 | 
						|
			DPFX(DPFPREP,  DVF_ERRORLEVEL, "Cannot lock entire buffer while recording!" );
 | 
						|
			return DVERR_GENERIC;
 | 
						|
		}
 | 
						|
		
 | 
						|
		*lplpvBuffer1 = m_lpbShadowBuffer;
 | 
						|
		*lpdwSize1 = m_dwBufferSize;
 | 
						|
		m_dwShadowStart = 0;
 | 
						|
		
 | 
						|
		return DV_OK;
 | 
						|
	}
 | 
						|
 | 
						|
	if( dwWriteBytes % m_dwFrameSize != 0 )
 | 
						|
	{
 | 
						|
		DPFX(DPFPREP,  DVF_ERRORLEVEL, "Can only lock block aligned sizes" );
 | 
						|
		return DVERR_GENERIC;
 | 
						|
	}
 | 
						|
 | 
						|
	// We're working with a shadow buffer
 | 
						|
	if( dwWriteBytes > m_dwFrameSize )
 | 
						|
	{
 | 
						|
		*lplpvBuffer1 = m_lpbShadowBuffer;
 | 
						|
		*lpdwSize1 = dwWriteBytes;
 | 
						|
		m_dwShadowStart = dwWriteCursor;
 | 
						|
 | 
						|
		return DV_OK;
 | 
						|
	}
 | 
						|
 | 
						|
	// We're doing a plain old lock of a buffer.  When we do the unlock we'll commit the buffer
 | 
						|
	m_dwShadowStart = dwWriteCursor / m_dwFrameSize;
 | 
						|
 | 
						|
	*lpdwSize1 = m_dwFrameSize;
 | 
						|
	*lplpvBuffer1 = m_lpWaveHeaders[m_dwShadowStart].lpData;
 | 
						|
 | 
						|
	return DV_OK;
 | 
						|
}
 | 
						|
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define DPF_MODNAME "CWaveInRecordBuffer::UnLock"
 | 
						|
HRESULT CWaveInRecordBuffer::UnLock( LPVOID lpvBuffer1, DWORD dwSize1, LPVOID lpvBuffer2, DWORD dwSize2 )
 | 
						|
{
 | 
						|
	HRESULT hr;
 | 
						|
	// We used the shadow buffer, we're writing across multiple buffers.
 | 
						|
	//
 | 
						|
	// We don't commit the buffers to the sound device because this is always used for 
 | 
						|
	// setting silence into the buffers
 | 
						|
	if( dwSize1 > m_dwFrameSize )
 | 
						|
	{
 | 
						|
		DWORD dwCurrentBuffer = m_dwShadowStart / m_dwFrameSize;
 | 
						|
		LPBYTE lpCurrentShadowLoc = m_lpbShadowBuffer;
 | 
						|
 | 
						|
		for( DWORD dwIndex = 0; dwIndex < (dwSize1 / m_dwFrameSize); dwIndex++ )
 | 
						|
		{
 | 
						|
			memcpy( m_lpWaveHeaders[dwCurrentBuffer].lpData , lpCurrentShadowLoc, m_dwFrameSize );
 | 
						|
 | 
						|
			lpCurrentShadowLoc += m_dwFrameSize;
 | 
						|
			dwCurrentBuffer++;
 | 
						|
 | 
						|
			dwCurrentBuffer %= m_dwNumBuffers;
 | 
						|
		}
 | 
						|
 | 
						|
		return DV_OK;
 | 
						|
	}
 | 
						|
 | 
						|
	// We got just one buffer and we're now ready to commit it to the device
 | 
						|
 | 
						|
	m_lpWaveHeaders[m_dwShadowStart].dwFlags = 0;
 | 
						|
 | 
						|
	hr = waveInPrepareHeader( m_hwiDevice, &m_lpWaveHeaders[m_dwShadowStart], sizeof( WAVEHDR ) );
 | 
						|
 | 
						|
	if( WIFAILED( hr ) )
 | 
						|
	{
 | 
						|
		DPFX(DPFPREP,  DVF_ERRORLEVEL, "Unable to prepare the header for output to the sound device (mmresult) hr = 0x%x", hr );
 | 
						|
		return DVERR_RECORDSYSTEMERROR;
 | 
						|
	}
 | 
						|
 | 
						|
	hr = waveInAddBuffer( m_hwiDevice, &m_lpWaveHeaders[m_dwShadowStart], sizeof( WAVEHDR ) );
 | 
						|
 | 
						|
	if( WIFAILED( hr ) )
 | 
						|
	{
 | 
						|
		DPFX(DPFPREP,  DVF_ERRORLEVEL, "Unable to write the buffer (mmresult) hr=0x%x", hr );
 | 
						|
		waveInUnprepareHeader( m_hwiDevice, &m_lpWaveHeaders[m_dwShadowStart], sizeof( WAVEHDR ) );
 | 
						|
		return DVERR_RECORDSYSTEMERROR;
 | 
						|
	}
 | 
						|
 | 
						|
	return DV_OK;
 | 
						|
}
 | 
						|
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define DPF_MODNAME "CWaveInRecordBuffer::SetVolume"
 | 
						|
HRESULT CWaveInRecordBuffer::GetVolume( LPLONG lplVolume )
 | 
						|
{
 | 
						|
	HRESULT hr;
 | 
						|
 | 
						|
	hr = m_mixerLine.GetMicrophoneVolume( lplVolume );
 | 
						|
 | 
						|
	if( FAILED( hr ) )
 | 
						|
	{
 | 
						|
		DPFX(DPFPREP,  DVF_WARNINGLEVEL, "Unable to get mic volume, using master rec volume hr=0x%x", hr );
 | 
						|
		
 | 
						|
		hr = m_mixerLine.GetMasterRecordVolume( lplVolume );
 | 
						|
 | 
						|
		if( FAILED( hr ) )
 | 
						|
		{
 | 
						|
			DPFX(DPFPREP,  DVF_ERRORLEVEL, "Unable to get recording volume hr=0x%x", hr );
 | 
						|
			return hr;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return hr;
 | 
						|
}
 | 
						|
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define DPF_MODNAME "CWaveInRecordBuffer::SetVolume"
 | 
						|
HRESULT CWaveInRecordBuffer::SetVolume( LONG lVolume )
 | 
						|
{
 | 
						|
	HRESULT hr;
 | 
						|
 | 
						|
	hr = m_mixerLine.SetMasterRecordVolume( lVolume );
 | 
						|
 | 
						|
	if( FAILED( hr ) )
 | 
						|
	{
 | 
						|
		DPFX(DPFPREP,  DVF_WARNINGLEVEL, "Unable to set master recording volume hr=0x%x", hr );
 | 
						|
	}
 | 
						|
 | 
						|
	hr = m_mixerLine.SetMicrophoneVolume( lVolume );
 | 
						|
 | 
						|
	if( FAILED( hr ) )
 | 
						|
	{
 | 
						|
		DPFX(DPFPREP,  DVF_WARNINGLEVEL, "Unable to set mic volume hr=0x%x", hr );
 | 
						|
	}
 | 
						|
 | 
						|
	return hr;
 | 
						|
}
 | 
						|
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define DPF_MODNAME "CWaveInRecordBuffer::GetCurrentPosition"
 | 
						|
HRESULT CWaveInRecordBuffer::GetCurrentPosition( LPDWORD lpdwPosition, LPBOOL lpfLostFocus )
 | 
						|
{
 | 
						|
	*lpdwPosition = m_dwCurrentPosition;
 | 
						|
	*lpfLostFocus = FALSE;
 | 
						|
 | 
						|
	return DV_OK;
 | 
						|
}
 | 
						|
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define DPF_MODNAME "CWaveInRecordBuffer::Record"
 | 
						|
HRESULT CWaveInRecordBuffer::Record( BOOL fLooping )
 | 
						|
{
 | 
						|
	// Always send two buffers to the record device in order to allow
 | 
						|
	// for significant write-ahead
 | 
						|
 | 
						|
	HRESULT hr;
 | 
						|
 | 
						|
	m_fRecording = FALSE;
 | 
						|
 | 
						|
	m_dwCurrentPosition = 0;
 | 
						|
 | 
						|
	for( DWORD dwIndex = 0; dwIndex < m_dwNumBuffers; dwIndex++ )
 | 
						|
	{
 | 
						|
		m_lpWaveHeaders[dwIndex].dwFlags = 0;
 | 
						|
 | 
						|
		hr = waveInPrepareHeader( m_hwiDevice, &m_lpWaveHeaders[dwIndex], sizeof( WAVEHDR ) );
 | 
						|
 | 
						|
		if( WIFAILED( hr ) )
 | 
						|
		{
 | 
						|
			DPFX(DPFPREP,  DVF_ERRORLEVEL, "Unable to prepare header for recording (mmresult) hr=0x%x", hr );
 | 
						|
			return DVERR_RECORDSYSTEMERROR;
 | 
						|
		}
 | 
						|
 | 
						|
		hr = waveInAddBuffer( m_hwiDevice, &m_lpWaveHeaders[dwIndex], sizeof( WAVEHDR ) );
 | 
						|
 | 
						|
		if( WIFAILED( hr ) )
 | 
						|
		{
 | 
						|
			DPFX(DPFPREP,  DVF_ERRORLEVEL, "Unable to write wave chunk (mmresult) hr=0x%x", hr );
 | 
						|
			return DVERR_RECORDSYSTEMERROR;
 | 
						|
		}		
 | 
						|
	}
 | 
						|
 | 
						|
	DPFX(DPFPREP,  DVF_INFOLEVEL, "Starting recording" );
 | 
						|
 | 
						|
	hr = waveInStart( m_hwiDevice );
 | 
						|
 | 
						|
	if( WIFAILED( hr ) )
 | 
						|
	{
 | 
						|
		DPFX(DPFPREP,  DVF_ERRORLEVEL, "Unable to start input (mmresult) hr=0x%x", hr );
 | 
						|
		return DVERR_RECORDSYSTEMERROR;
 | 
						|
	}
 | 
						|
 | 
						|
	DPFX(DPFPREP,  DVF_INFOLEVEL, "Waiting for a frame to be processed" );
 | 
						|
 | 
						|
	// Delay for one frame to allow waveIn to start up. 
 | 
						|
	//
 | 
						|
	WaitForSingleObject( m_hFrameProcessed, INFINITE );
 | 
						|
 | 
						|
	DPFX(DPFPREP,  DVF_INFOLEVEL, "Frame processed, recording proceeding" );
 | 
						|
 | 
						|
	m_fRecording = TRUE;
 | 
						|
 | 
						|
	return DV_OK;
 | 
						|
}
 | 
						|
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define DPF_MODNAME "CWaveInRecordBuffer::Stop"
 | 
						|
HRESULT CWaveInRecordBuffer::Stop()
 | 
						|
{
 | 
						|
	HRESULT hr;
 | 
						|
	DWORD dwIndex;
 | 
						|
 | 
						|
	m_fStopping = TRUE;
 | 
						|
 | 
						|
	hr = waveInReset( m_hwiDevice );
 | 
						|
 | 
						|
	if( WIFAILED( hr ) )
 | 
						|
	{
 | 
						|
		DPFX(DPFPREP,  DVF_ERRORLEVEL, "Stop failed on waveInReset (mmresult) hr=0x%x", hr );
 | 
						|
		return DVERR_RECORDSYSTEMERROR;
 | 
						|
	}
 | 
						|
 | 
						|
	ResetEvent( m_hFrameProcessed );
 | 
						|
 | 
						|
	for( dwIndex = 0; dwIndex < m_dwNumBuffers; dwIndex++ )
 | 
						|
	{
 | 
						|
		hr = waveInUnprepareHeader( m_hwiDevice, &m_lpWaveHeaders[dwIndex], sizeof( WAVEHDR ) );
 | 
						|
 | 
						|
		if( WIFAILED( hr ) )
 | 
						|
		{
 | 
						|
			DPFX(DPFPREP,  DVF_ERRORLEVEL, "Unable to unprepare header for recording (mmresult) hr=0x%x", hr );
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	m_fStopping = FALSE;	
 | 
						|
	m_fRecording = FALSE;
 | 
						|
 | 
						|
	// This should cause the callback to be called which will
 | 
						|
	// unprepare all the headers.
 | 
						|
 | 
						|
	return DV_OK;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define DPF_MODNAME "CWaveInRecordBuffer::GetRecordFormat"
 | 
						|
LPWAVEFORMATEX CWaveInRecordBuffer::GetRecordFormat()
 | 
						|
{
 | 
						|
	return m_lpwfxRecordFormat;	
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define DPF_MODNAME "CWaveInRecordBuffer::SelectMicrophone"
 | 
						|
HRESULT CWaveInRecordBuffer::SelectMicrophone( BOOL fSelect )
 | 
						|
{
 | 
						|
	return m_mixerLine.EnableMicrophone( fSelect );
 | 
						|
}
 | 
						|
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define DPF_MODNAME "CWaveInRecordBuffer::ClaimFocus"
 | 
						|
HRESULT CWaveInRecordBuffer::ClaimFocus(  )
 | 
						|
{
 | 
						|
	return DVERR_NOTSUPPORTED;
 | 
						|
}
 | 
						|
 | 
						|
#undef DPF_MODNAME
 | 
						|
#define DPF_MODNAME "CWaveInRecordBuffer::YieldFocus"
 | 
						|
HRESULT CWaveInRecordBuffer::YieldFocus(  )
 | 
						|
{
 | 
						|
	return DVERR_NOTSUPPORTED;
 | 
						|
}
 | 
						|
 |