⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mixhw.cpp

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

	Copyright (c) 1999 Microsoft Corporation

	Module Name:

		mixhw.c

	Abstract:

		Defines the structures and functions that describe the mixer hardware of the device

	Environment:

	Notes:
		

	Revision History:

-------------------------------------------------------------------*/

#include "includes.h"
#include "AC97Codec.h"
#include "CX5530Audio.h"
#include <mmreg.h>
#include "globals.h"
#include "mixdrv.h"
#include "mixhw.h"


DWORD GetAssociatedMuteID(DWORD dwVolumeControlID);

// indexes for the audio sources of the clipper4
// *not* of the AC97 mixer chip!
// all of them can be accessed as lines by users of mixapi.lib

MIXERLINE g_mixerLines[LINES_COUNT] = 
{	// destination lines for the EPR:
	// Line out:
	{
		sizeof(MIXERLINE),				// size of MIXERLINE structure 
			0,								// zero based destination index
			(ULONG)-1,						// Index for the audio source line associated with the dwDestination member.
			// That is, this member specifies the nth audio source line associated 
			// with the specified audio destination line. 
			LINE_OUT,								// unique line id for mixer device 
			MIXERLINE_LINEF_ACTIVE,         // state/information about line 
			0,								// driver specific information 
			MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,        // component type line connects to 
			STEREO,								// number of channels line supports 
			1,								// number of input connections [possible] 
			// the controls are: one mute, one volume
			2,								// number of controls at this line 
			TEXT("Line Out"),
			TEXT("Line Out"),
		{
			MIXERLINE_TARGETTYPE_UNDEFINED,                 // MIXERLINE_TARGETTYPE_xxxx 
				0,							// target device ID of device type 
				0,							// of target device 
				0,							//
				0,							//
				TEXT("")					//
		}
	},
		// wave in destination (PCM recorder)
	{
		sizeof(MIXERLINE),				// size of MIXERLINE structure 
			1,								// zero based destination index
			(ULONG)-1,						// Index for the audio source line associated with the dwDestination member.
			// That is, this member specifies the nth audio source line associated 
			// with the specified audio destination line. 
			WAVE_IN,								// unique line id for mixer device 
			MIXERLINE_LINEF_ACTIVE,         // state/information about line 
			0,								// driver specific information 
			MIXERLINE_COMPONENTTYPE_DST_WAVEIN,        // component type line connects to 
			STEREO,								// number of channels line supports 
			1,								// number of input connections [possible] 
			// the controls are: one mux, one mute, one volume
			3,								// number of controls at this line 
			TEXT("PCM record"),
			TEXT("PCM record input"),
		{
			MIXERLINE_TARGETTYPE_WAVEIN,                 // MIXERLINE_TARGETTYPE_xxxx 
				0,							// target device ID of device type 
				DRIVER_WMID,				// of target device 
				MM_MSFT_WDMAUDIO_WAVEIN,	//
				DRIVER_VERSION,				//
				DRIVER_NAME					//
		}
	},
		// source lines
		// PCM
	{
		sizeof(MIXERLINE),				// size of MIXERLINE structure 
			(ULONG)-1,								// zero based destination index
			0,								// zero based source index (if source) 
			PCM,								// unique line id for mixer device 
			MIXERLINE_LINEF_ACTIVE|MIXERLINE_LINEF_SOURCE,         // state/information about line 
			0,								// driver specific information 
			MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT,        // component type line connects to 
			STEREO,								// number of channels line supports 
			0,								// number of connections [possible] 
			// the controls are: one volume, one mute
			2,								// number of controls at this line 
			TEXT("PCM"),
			TEXT("Wave audio player"),
		{
			MIXERLINE_TARGETTYPE_WAVEOUT,                 // MIXERLINE_TARGETTYPE_xxxx 
				0,							// target device ID of device type (i.e., this line is wave device 0)
				DRIVER_WMID,				//  wMid
				MM_MSFT_WDMAUDIO_WAVEOUT,	//	wPid
				DRIVER_VERSION,				//
				DRIVER_NAME				//
		}
	},
		// line in 
	{
		sizeof(MIXERLINE),				// size of MIXERLINE structure 
			(ULONG)-1,								// zero based destination index
			0,								// zero based source index (if source) 
			LINE_IN,								// unique line id for mixer device 
			MIXERLINE_LINEF_ACTIVE|MIXERLINE_LINEF_SOURCE,         // state/information about line 
			0,								// driver specific information 
			MIXERLINE_COMPONENTTYPE_SRC_LINE,        // component type line connects to 
			STEREO,								// number of channels line supports 
			0,								// number of connections [possible] 
			// the controls are: one volume, one mute
			2,								// number of controls at this line 
			TEXT("LINE_IN"),
			TEXT("Line in"),
		{
			MIXERLINE_TARGETTYPE_WAVEOUT,                 // MIXERLINE_TARGETTYPE_xxxx 
				0,							// target device ID of device type (i.e., this line is wave device 0)
				DRIVER_WMID,				//  wMid
				MM_MSFT_GENERIC_AUX_LINE,	//	wPid
				DRIVER_VERSION,				//
				DRIVER_NAME				//
		}
	},
		// microphone
	{
		sizeof(MIXERLINE),				// size of MIXERLINE structure 
			(ULONG)-1,								// zero based destination index
			0,								// zero based source index (if source) 
			MICROPHONE,								// unique line id for mixer device 
			MIXERLINE_LINEF_ACTIVE|MIXERLINE_LINEF_SOURCE,         // state/information about line 
			0,								// driver specific information 
			MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE,        // component type line connects to 
			MONO,								// number of channels line supports 
			0,								// number of connections [possible] 
			// the controls are: one volume, one mute
			2,								// number of controls at this line 
			TEXT("Microphone"),
			TEXT("Microphone"),
		{
			MIXERLINE_TARGETTYPE_WAVEOUT,                 // MIXERLINE_TARGETTYPE_xxxx 
				0,							// target device ID of device type (i.e., this line is wave device 0)
				DRIVER_WMID,				//  wMid
				MM_MSFT_GENERIC_AUX_MIC,	//	wPid
				DRIVER_VERSION,				//
				DRIVER_NAME				//
		}
	}
};


// the g_Connections array maps the possible hardware connections between the input lines
// (sources) and the destination lines; the position in the array is the index of the 
// connection for the destination line

MIXER_LINES g_Connections[DESTINATION_LINES_COUNT][LINES_COUNT - DESTINATION_LINES_COUNT] =
{
	// indexes in g_mixer Lines for the sources connected to destination 0 (line out)
	PCM,
	LINE_IN,
	MICROPHONE,

	// indexes in g_mixer Lines for the sources connected to destination 0 (line out)
	PCM,
	LINE_IN,
	MICROPHONE,
};


// Controls

//	Note! the "minimum" value in the following array means the one that sets the volume to minimum
//	that's a different meaning from the one of the logical value exposed to applications!

SHORTMIXERCONTROL g_Controls[MAX_CONTROLS] = 
{
	// controls for line 0 (line out destination): 
	// master line out volume (AC97 register)
	{// control 0
		LINE_OUT, 
		MIXERCONTROL_CONTROLTYPE_VOLUME,	// dwControlType; 
		0,
		AC97_MASTER_VOLUME,
		0x3F,		// minimum
		0,			// maximum
		TEXT("Line out volume"),// szShortName[MIXER_SHORT_NAME_CHARS]; 
		TEXT("Line out volume for mixer output"), // szName[MIXER_LONG_NAME_CHARS]; 
	},
	// master line out mute (AC97 register)
	{// control 1
		LINE_OUT, 
		MIXERCONTROL_CONTROLTYPE_MUTE,	// dwControlType; 
		0,
		AC97_MASTER_VOLUME,
		0,		// minimum
		0,		// maximum
		TEXT("Line out mute"),// szShortName[MIXER_SHORT_NAME_CHARS]; 
		TEXT("Mixer output mute"), // szName[MIXER_LONG_NAME_CHARS]; 
	},

	// controls for line 1 (wave in recorder): 
	// record volume (AC97 register)
	{// control 0
		WAVE_IN, 
		MIXERCONTROL_CONTROLTYPE_VOLUME,	// dwControlType; 
		0,
		AC97_RECORD_GAIN,
		0x0F,		// minimum
		0,			// maximum
		TEXT("Record gain"),// szShortName[MIXER_SHORT_NAME_CHARS]; 
		TEXT("PCM record gain"), // szName[MIXER_LONG_NAME_CHARS]; 
	},
	// record mute (AC97 register)
	{// control 1
		WAVE_IN, 
		MIXERCONTROL_CONTROLTYPE_MUTE,	// dwControlType; 
		0,
		AC97_RECORD_GAIN,
		0,		// minimum
		0,		// maximum
		TEXT("Record mute"),// szShortName[MIXER_SHORT_NAME_CHARS]; 
		TEXT("PCM record mute"), // szName[MIXER_LONG_NAME_CHARS]; 
	},
	{// control 2: record source selection mux
		WAVE_IN, 
		MIXERCONTROL_CONTROLTYPE_MUX,	// dwControlType; 
		0,
		AC97_RECORD_SELECT,
		0,		// minimum
		0,		// maximum
		TEXT("Record source"),// szShortName[MIXER_SHORT_NAME_CHARS]; 
		TEXT("PCM record source selector"), // szName[MIXER_LONG_NAME_CHARS]; 
	},
	// source lines

	// controls for line  (PCM player)
	// PCM volume (AC97 register)
	{// control 0
		PCM, 
 		MIXERCONTROL_CONTROLTYPE_VOLUME,	// dwControlType; 
 
		0,
		AC97_PCM_OUT_VOL,
		0x1F,		// minimum
		0,		// maximum
		TEXT("PCM volume"),// szShortName[MIXER_SHORT_NAME_CHARS]; 
		TEXT("PCM volume for mixer input"), // szName[MIXER_LONG_NAME_CHARS]; 
	},
	// PCM mute (AC97 register)
	{// control 1
		PCM, 
		MIXERCONTROL_CONTROLTYPE_MUTE,	// dwControlType; 
		0,
		AC97_PCM_OUT_VOL,
		0,		// minimum
		0,		// maximum
		TEXT("PCM mute"),// szShortName[MIXER_SHORT_NAME_CHARS]; 
		TEXT("PCM mute for mixer input"), // szName[MIXER_LONG_NAME_CHARS]; 
	},
	// controls for line 2 (line in jack)
	// LINE_IN volume (AC97 register)
	{// control 0
		LINE_IN, 
 		MIXERCONTROL_CONTROLTYPE_VOLUME,	// dwControlType; 
 
		0,
		AC97_LINE_IN_VOLUME,
		0x1F,		// minimum
		0,		// maximum
		TEXT("Line in volume"),// szShortName[MIXER_SHORT_NAME_CHARS]; 
		TEXT("Line in volume for mixer input"), // szName[MIXER_LONG_NAME_CHARS]; 
	},
	// Line in mute (AC97 register)
	{// control 1
		LINE_IN, 
		MIXERCONTROL_CONTROLTYPE_MUTE,	// dwControlType; 
		0,
		AC97_LINE_IN_VOLUME,
		0,		// minimum
		0,		// maximum
		TEXT("Line in mute"),// szShortName[MIXER_SHORT_NAME_CHARS]; 
		TEXT("Line in mute for mixer input"), // szName[MIXER_LONG_NAME_CHARS]; 
	},
	// controls for source line 3 (microphone)
	// MIC volume (AC97 register)
	{// control 0
		MICROPHONE, 
 		MIXERCONTROL_CONTROLTYPE_VOLUME,	// dwControlType; 
 		0,
		AC97_MIC_VOLUME,
		0x2C,		// minimum
		0,		// maximum
		TEXT("Mic gain"),// szShortName[MIXER_SHORT_NAME_CHARS]; 
		TEXT("Microphone gain for mixer input"), // szName[MIXER_LONG_NAME_CHARS]; 
	},
	// MIC mute (AC97 register)
	{// control 1
		MICROPHONE, 
		MIXERCONTROL_CONTROLTYPE_MUTE,	// dwControlType; 
		0,
		AC97_MIC_VOLUME,
		0,		// minimum
		0,		// maximum
		TEXT("Mic mute"),// szShortName[MIXER_SHORT_NAME_CHARS]; 
		TEXT("Microphone mute"), // szName[MIXER_LONG_NAME_CHARS]; 
	}

};

// only valid for volume and mute controls;
// stores pairs of associated controls (mute and volume, used to mute
// a line when the volume is less than the hardware min)
DWORD g_ControlsPairs[][2] = 
{
	{ LINE_OUT_VOLUME, LINE_OUT_MUTE},
	{ PCM_VOLUME, PCM_MUTE},
	{ LINE_IN_VOLUME,	LINE_IN_MUTE},
	{ MIC_VOLUME, MIC_MUTE},
	{ WAVE_IN_GAIN, WAVE_IN_MUTE}
};

// that structure describes the lines that are multiplexed

MULTIPLEXER g_Multiplexers[MAX_MULTIPLEXERS] = 
{
	{	// the record sources. The AC97 mixer has more entries, but we only expose those
		// because the others are not connected or not useful (as yet).
		WAVE_IN_SELECTOR,
		{
			MICROPHONE,
			LINE_IN,
			LINE_OUT
		}
	}
};

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Function:

	SetMixerVolume

Description:

	Sets the volume for one of the mixer controls

Arguments:

	PDRIVER_CONTEXT pDriverContext : the context
	DWORD dwId :	the ID of the control
	DWORD dwLeft :	the new volume for the left channel
	DWORD dwRight :	the new volume for the right channel

Return Value: DWORD
	NO_ERROR : the op succeeded
-------------------------------------------------------------------*/
DWORD SetMixerVolume(PDRIVER_CONTEXT pDriverContext, DWORD dwId, DWORD dwLeft, DWORD dwRight )
{
	DWORD wVal, dwAddr;
	WORD wMuted = 0;
	DWORD dwRet = NO_ERROR;
	BOOL bMute = FALSE;
	CCX5530Audio* pCX5530Audio = CCX5530Audio::GetCX5530AudioObject();
		
	ASSERT(pCX5530Audio && pDriverContext && dwId >= 0 && dwId < MAX_CONTROLS);

	MIXMSG3("+SetMixerVolume %s (%d, %d)", g_Controls[dwId].szShortName, dwLeft, dwRight);

	dwAddr = g_Controls[dwId].dwRegister; 
	g_Controls[dwId].dwLogicalValue = MAKELONG(dwLeft, dwRight);


	switch (dwId)
	{
	case MIC_VOLUME:	// needs special handling because of the 20 dB amplifier which extends the 
						// range to 66.5 dB
		{
			WORD wAmplifierFlag = AC97_MICROPHONE_AMPLIFIER_GAIN;
			// the logical range of the mic gain is from +32 dB to -34.5 dB, in steps of 1.5 dB
			// the physical range of the variable amplifier is +12 dB to -34.5 dB
			// we map the logical range to values between 0 (representing +32 dB) and 0x2C
			// (representing -34.5 dB)
			
			dwLeft /= 100;	// convert attenuation to dB
			
			if (!pCX5530Audio->ReadAC97(USHORT(dwAddr), wMuted))
			{
				dwRet = ERROR_READ_FAULT;
				break;
			}
			// separate mute flag
			wMuted &= AC97_MIXER_MUTE;
			
			// is the attenuation higher than the hardware range?
			if (dwLeft > g_Controls[dwId].dwMinimum)
			{	// yes; mute instead
				bMute = TRUE;
				dwLeft = g_Controls[dwId].dwMinimum;
			}
			
			if (bMute)	// hack-mute
			{
				wMuted |= AC97_MIXER_MUTE;
			}
			else if (wMuted) 
			{	
				// muted, but volume set to something large: need to know if this was really mute, or 
				// transparently muted by the driver during a previous volume setting
				
				DWORD dwMute = GetAssociatedMuteID(dwId);
				if (dwMute != (DWORD)-1)
				{
					if (!g_Controls[dwMute].dwLogicalValue)
					{
						wMuted = 0;
					}
				}
			}
			
			// is the amplifier on?
			
			if (dwLeft > AC97_MICROPHONE_AMPLIFIER_GAIN)
			{
				// no;
				INFMSG("Turning Mic amp OFF");
				wAmplifierFlag = 0;
				dwLeft -= AC97_MICROPHONE_AMPLIFIER_GAIN;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -