www.pudn.com > G729_Talk.rar > MixOut.cpp


 
#include "stdafx.h" 
#include "MixOut.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
#define	WND_CLASS_NAME	"Wave Output Volume Msg Wnd Class" 
#define	WND_NAME		"Wave Output Volume Msg Wnd" 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
static CMixOut *g_pThis = NULL; 
LRESULT CALLBACK CMixOut::MixerWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) 
{ 
	if ( uMsg == MM_MIXM_CONTROL_CHANGE ) 
	{ 
		if ( g_pThis ) 
		{ 
			g_pThis->OnControlChanged( (DWORD)lParam ); 
		}	 
	} 
	return ::DefWindowProc( hwnd, uMsg, wParam, lParam); 
} 
 
MMRESULT CMixOut::GetLastMMError() 
{ 
	return m_mmr; 
} 
CString CMixOut::GetLastErrorString() 
{ 
	char buffer[256]; 
	memset(buffer,0,256); 
	switch(m_mmr) 
	{ 
	case MMSYSERR_NOERROR: 
		sprintf(buffer,"No error."); 
		break; 
	case MIXERR_INVALCONTROL: 
		sprintf(buffer,"Specified device handle is invalid."); 
		break; 
	case MMSYSERR_BADDEVICEID: 
		sprintf(buffer,"The hmxobj parameter specifies an invalid device identifier."); 
		break; 
	case MMSYSERR_INVALFLAG: 
		sprintf(buffer,"One or more flags are invalid."); 
		break; 
	case MMSYSERR_INVALHANDLE: 
		sprintf(buffer,"The hmxobj parameter specifies an invalid handle."); 
		break; 
	case MMSYSERR_INVALPARAM: 
		sprintf(buffer,"One or more parameters are invalid."); 
		break; 
	case MMSYSERR_NODRIVER: 
		sprintf(buffer,"No mixer device is available for the object specified by hmxobj."); 
		break; 
	case MIXERR_INVALLINE: 
		sprintf(buffer,"The audio line reference is invalid.."); 
		break; 
	case MMSYSERR_NOTSUPPORTED: 
		sprintf(buffer,"The mixer device did not process the message."); 
		break; 
	case MMSYSERR_ALLOCATED: 
		sprintf(buffer,"The specified resource is already allocated by the maximum number of clients possible."); 
		break; 
	case MMSYSERR_NOMEM: 
		sprintf(buffer,"Unable to allocate resources."); 
		break; 
	default: 
		sprintf(buffer,"Unknow error,Error code %d",m_mmr); 
		break; 
	} 
	return buffer; 
} 
 
CMixOut::CMixOut(): 
	m_iDevNum(0), 
	m_uiMixerId(0), 
	m_hMixer(0), 
	m_hWnd(NULL), 
	m_bIni(FALSE), 
	m_dwMinimalVolume(0), 
	m_dwMaximalVolume(100) 
{ 
	g_pThis = this; 
} 
 
CMixOut::~CMixOut() 
{ 
} 
 
BOOL CMixOut::Ini() 
{ 
	if (m_bIni) 
	{ 
		TRACE("Mix in has alreadly ini.\n");		 
		return FALSE; 
	} 
	if (!OpenMixer()) 
	{ 
		TRACE("%s.\n",GetLastErrorString()); 
		return FALSE; 
	}; 
 
	if (!Initialize()) 
	{ 
		TRACE("%s.\n",GetLastErrorString()); 
		return FALSE; 
	} 
 
	m_bIni = TRUE; 
	return TRUE; 
} 
 
BOOL CMixOut::UnIni() 
{ 
	if (!m_bIni) 
	{ 
		TRACE("Mix in hasn't ini.\n"); 
		return FALSE; 
	} 
	::DestroyWindow( m_hWnd ); 
	CloseMixer(); 
 
	m_iDevNum = 0; 
	m_uiMixerId = 0; 
	m_hMixer = 0; 
	m_hWnd = NULL; 
	m_bIni = FALSE; 
	m_dwMinimalVolume = 0; 
	m_dwMaximalVolume = 100; 
 
	m_bIni = FALSE; 
	return TRUE; 
} 
 
BOOL CMixOut::OpenMixer() 
{ 
	m_iDevNum = mixerGetNumDevs(); 
	if (m_iDevNum == 0) 
	{ 
		TRACE("There (is) are no device mixer.\n"); 
		return FALSE; 
	} 
 
	WAVEFORMATEX wfx; 
	memset( &wfx, 0, sizeof(WAVEFORMATEX) ); 
	wfx.wFormatTag = WAVE_FORMAT_PCM; 
	wfx.nChannels = 1; 
	wfx.nSamplesPerSec = 8000; 
	wfx.nAvgBytesPerSec = 1 * 8000 * 16 / 8; 
	wfx.nBlockAlign = 16 * 1 / 8; 
	wfx.wBitsPerSample = 16; 
	wfx.cbSize = 0; 
 
	HWAVEOUT hwaveOut; 
	m_mmr = waveOutOpen( &hwaveOut, WAVE_MAPPER, &wfx, 0L, 0L, CALLBACK_NULL ); 
	if ( m_mmr != MMSYSERR_NOERROR ) 
	{ 
		return false; 
	} 
	else 
	{ 
		m_mmr = mixerGetID( (HMIXEROBJ)hwaveOut, &m_uiMixerId, MIXER_OBJECTF_HWAVEOUT ); 
		waveOutClose( hwaveOut ); 
		if (m_mmr != MMSYSERR_NOERROR ) 
		{ 
			return false; 
		} 
	} 
 
	WNDCLASSEX wcx; 
	memset( &wcx, 0, sizeof(WNDCLASSEX) );	 
	wcx.cbSize = sizeof(WNDCLASSEX); 
	wcx.lpszClassName = WND_CLASS_NAME; 
	wcx.lpfnWndProc = (WNDPROC)MixerWndProc; 
	::RegisterClassEx(&wcx); 
	m_hWnd = CreateWindow(	WND_CLASS_NAME, 
							WND_NAME, 
							WS_POPUP | WS_DISABLED, 
							0, 0, 0, 0, 
							NULL, NULL, NULL, NULL ); 
	if ( !m_hWnd ) 
	{ 
	 
		return false; 
	} 
	::ShowWindow(m_hWnd, SW_HIDE); 
	m_mmr = mixerOpen( (LPHMIXER)&m_hMixer, m_uiMixerId, (DWORD)m_hWnd, 0L, CALLBACK_WINDOW ); 
	if (m_mmr != MMSYSERR_NOERROR ) 
	{ 
		::DestroyWindow( m_hWnd ); 
		return false; 
	} 
	return true; 
} 
 
BOOL CMixOut::CloseMixer() 
{ 
	if (m_hMixer) 
	{ 
		m_mmr = mixerClose((HMIXER)m_hMixer); 
		if (m_mmr != MMSYSERR_NOERROR ) 
		{ 
			return false; 
		} 
	} 
	return TRUE; 
} 
 
void CMixOut::OnControlChanged(int iValue) 
{ 
} 
 
BOOL CMixOut::Initialize() 
{ 
	if (m_hMixer) 
	{ 
		TRACE("You haven't open the mixer.\n"); 
		return FALSE; 
	} 
	 
	MIXERLINE MixerLine; 
	memset( &MixerLine, 0, sizeof(MIXERLINE) ); 
	MixerLine.cbStruct = sizeof(MIXERLINE); 
	MixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT; 
	m_mmr = mixerGetLineInfo( (HMIXEROBJ)m_hMixer, &MixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE ); 
	if ( m_mmr != MMSYSERR_NOERROR ) 
	{ 
		return false; 
	} 
 
	MIXERCONTROL Control; 
	memset( &Control, 0, sizeof(MIXERCONTROL) ); 
	Control.cbStruct = sizeof(MIXERCONTROL); 
 
	MIXERLINECONTROLS LineControls; 
	memset( &LineControls, 0, sizeof(MIXERLINECONTROLS) ); 
	LineControls.cbStruct = sizeof(MIXERLINECONTROLS); 
 
	LineControls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME; 
	LineControls.dwLineID = MixerLine.dwLineID; 
	LineControls.cControls = 1; 
	LineControls.cbmxctrl = sizeof(MIXERCONTROL); 
	LineControls.pamxctrl = &Control; 
	m_mmr = mixerGetLineControls( (HMIXEROBJ)m_hMixer, &LineControls, MIXER_GETLINECONTROLSF_ONEBYTYPE ); 
	if ( m_mmr == MMSYSERR_NOERROR ) 
	{ 
		if ((Control.fdwControl & MIXERCONTROL_CONTROLF_DISABLED) ) 
		{ 
			return FALSE; 
		}  
	}  
	else  
	{ 
		return FALSE; 
	} 
 
	m_dwMinimalVolume = Control.Bounds.dwMinimum; 
	m_dwMaximalVolume = Control.Bounds.dwMaximum; 
 
	return TRUE; 
} 
 
DWORD CMixOut::GetMinimalVolume() 
{ 
	if (!m_bIni) 
	{ 
		TRACE("Mix in hasn't ini.\n"); 
		return 0; 
	} 
	return this->m_dwMinimalVolume ; 
} 
 
DWORD CMixOut::GetMaximalVolume() 
{ 
	if (!m_bIni) 
	{ 
		TRACE("Mix in hasn't ini.\n"); 
		return 100; 
	} 
	return this->m_dwMaximalVolume ; 
} 
 
DWORD CMixOut::GetCurrentVolume() 
{ 
	if (!m_bIni) 
	{ 
		TRACE("Mix in hasn't ini.\n"); 
		return 0; 
	} 
	return 0; 
} 
 
void CMixOut::SetCurrentVolume(DWORD dwValue) 
{ 
}