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

📄 mixfunc.cpp

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

Copyright (c) 1999 Microsoft Corporation

Module Name:

	mixfunc.c

Abstract:


Environment:

	

Notes:


Revision History:

	5/20/1999


-------------------------------------------------------------------*/
#include "includes.h"
#include <mmddk.h>
#include "globals.h"
#include "mixdrv.h"
#include "mixfunc.h"
#include "mmreg.h"
#include "mixhw.h"

static void CopyControlStruct(PMIXERCONTROL pMixerControl, int iIndex);


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

Function:

	mix_handle_GETNUMDEVS

Description:

	Returns the number of supported instances for the driver 
	(1, that is each app can open only one instance). Not that we check for that, 
	i.e, an app could still open multiple instances, but it shouldn't

Arguments:

	PMIXER_CONTEXT pMixer :  pointer to the mixer context structure
	DWORD dwUser : returned by the app (not used)
	DWORD dwParam1 :
	DWORD dwParam2 :

Return Value: DWORD
-------------------------------------------------------------------*/
DWORD mix_handle_GETNUMDEVS(PMIXER_CONTEXT pMixer, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
{
	return MAX_SUPPORTED_INSTANCES;	// the driver only supports one device instance at the moment
}


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

Function:

	mix_handle_OPEN

Description:

	Opens a mixer handle; i.e., initializes the stored values in the MIXER_CONTEXT structure that
	describes the mixer with the values sent by the application

Arguments:

	PMIXER_CONTEXT pMixer :  pointer to the mixer context structure
	DWORD *pdwUser :	given us by the app for storage; we don't use it at this time
	DWORD dwParam1 :	pointer to a MIXEROPENDESC structure, describing parameters
	DWORD dwParam2 :	not used

Return Value: DWORD
-------------------------------------------------------------------*/
DWORD mix_handle_OPEN(PMIXER_CONTEXT pMixer, DWORD *pdwUser, DWORD dwParam1, DWORD dwParam2)
{
	MIXEROPENDESC *pMixDesc = (MIXEROPENDESC *) MapPtrToProcess((PVOID)dwParam1, GetCallerProcess());

	ASSERT(pMixer && pdwUser);

	if (!pMixDesc)
	{
		SetLastError(ERROR_INVALID_PARAMETER);
		return MMSYSERR_INVALPARAM;
	}
	
	pMixer->dwInstance = pMixDesc->dwInstance;
	pMixer->hProcess = GetCallerProcess();
	pMixer->pfnMixerCallback = (PDRVCALLBACK)pMixDesc->dwCallback;
	*pdwUser = 0;	// not really used
	return MMSYSERR_NOERROR;
}


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

Function:

	mix_handle_GETDEVCAPS

Description:

	Gets the device capabilities

Arguments:

	PMIXER_CONTEXT pMixer :  pointer to the mixer context structure
	DWORD dwUser : returned by the app (not used)
	DWORD dwParam1 : pointer to a MIXERCAPS struct where the info is returned
	DWORD dwParam2 :

Return Value: DWORD
-------------------------------------------------------------------*/
DWORD mix_handle_GETDEVCAPS(PMIXER_CONTEXT pMixer, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
{
	PMIXERCAPS pMixCaps = (PMIXERCAPS) MapPtrToProcess((PMIXERCAPS) dwParam1, GetCallerProcess());
	ASSERT(pMixer);
	if (!pMixCaps)
	{
		SetLastError(ERROR_INVALID_PARAMETER);
		return MMSYSERR_INVALPARAM;
	}
	// set mixer capabilites
	pMixCaps->wMid = DRIVER_WMID;
	pMixCaps->wPid = MM_MSFT_WDMAUDIO_MIXER;
	pMixCaps->fdwSupport = 0;
	pMixCaps->cDestinations = DESTINATION_LINES_COUNT;
	pMixCaps->vDriverVersion = DRIVER_VERSION;	// version 1.1
	_tcsncpy(pMixCaps->szPname, MIXERDRIVER_NAME, MAXPNAMELEN);
	pMixCaps->szPname[MAXPNAMELEN - 1] = 0;
	return MMSYSERR_NOERROR;
}


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

Function:

	mix_handle_CLOSE

Description:

	handles a mixerClose call from mixapi.lib. It does not deallocate the mixer context; that happens
	in MIX_Close, which is called when the calling app calls CloseHandle on the handle returned by
	CreateFile("MIX1:",...)

Arguments:

	PMIXER_CONTEXT pMixer :  pointer to the mixer context structure
	DWORD dwUser : returned by the app (not used)
	DWORD dwParam1 : not used
	DWORD dwParam2 : not used

Return Value: DWORD
-------------------------------------------------------------------*/
DWORD mix_handle_CLOSE(PMIXER_CONTEXT pMixer, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
{
	ASSERT(pMixer);

	pMixer->dwInstance = 0;
	//pMixer->hMixer = NULL;
	pMixer->pfnMixerCallback = NULL;
	
	return MMSYSERR_NOERROR;
}


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

Function:

	mix_handle_GETLINEINFO

Description:

	Gets info about a mixer line

Arguments:

	PMIXER_CONTEXT pMixer :  pointer to the mixer context structure
	DWORD dwUser : returned by the app (not used)
	DWORD dwParam1 : pointer to a MIXERLINE struct that gets filled with the line info
	DWORD dwParam2 : flags that describe the info requested

Return Value: DWORD
-------------------------------------------------------------------*/
DWORD mix_handle_GETLINEINFO(PMIXER_CONTEXT pMixer, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
{
	MIXER_LINES mxLine;
	LPMIXERLINE pTempLine;
	LPMIXERLINE pLine = (LPMIXERLINE) MapPtrToProcess((PVOID)dwParam1, GetCallerProcess());

	ASSERT(pMixer);

	if (!pLine)
	{
		MIXERRMSG("Bad pLine in mix_handle_GETLINEINFO");
		goto badparms;
	}

	if (pLine->cbStruct < sizeof(MIXERLINE) )
	{
		MIXERRMSG("Bad pLine cbStruct in mix_handle_GETLINEINFO");
		goto badparms;
	}

	// what line does the user want info about?
	
	switch (dwParam2 & MIXER_GETLINEINFOF_QUERYMASK)
	{
	case MIXER_GETLINEINFOF_DESTINATION:
		// the caller wants info about a destination line
		if (pLine->dwSource != 0|| pLine->dwDestination >= DESTINATION_LINES_COUNT)
			// be paranoid; the docs say dwSource must needs be 0 in this case
		{
			MIXERRMSG("Bad pLine line in mix_handle_GETLINEINFO");
			goto badparms;
		}
		mxLine = (MIXER_LINES) pLine->dwDestination;
		// fill in info
 		break;
	case MIXER_GETLINEINFOF_SOURCE:
		// the user wants info about a source line (the one that's associated to destination line pLine->dwDestination
		{
			pTempLine = FindMixerLine(pLine->dwDestination);
			if (!pTempLine)
			{
				MIXERRMSG1("Unknown line ID in mix_handle_GETLINEINFO: %d", pLine->dwDestination);
				goto badparms;
			}
			if (pLine->dwSource >= pTempLine->cConnections)
			{
				MIXERRMSG2("Bad pLine dwSource (%d) in mix_handle_GETLINEINFO (max %d)",
					pLine->dwSource, pTempLine->cConnections);
				goto badparms;
			}
			mxLine = g_Connections[pLine->dwDestination][pLine->dwSource];
			// fill in the info
		}
		break;
	case MIXER_GETLINEINFOF_LINEID:
		if (pLine->dwLineID >= LINES_COUNT)
		{
			MIXERRMSG("Bad pLine dwLineID in mix_handle_GETLINEINFO");
			goto badparms;
		}
		mxLine = (MIXER_LINES) pLine->dwLineID;
		break;
	case MIXER_GETLINEINFOF_COMPONENTTYPE:
		{
			// search the first line that supports the type of component requested
			int i; 
			mxLine = NO_CONNECTION;
			for (i = 0; i < LINES_COUNT; i++)
			{
				pTempLine = FindMixerLine(i);
				if (!pTempLine)
					continue;
				if (pTempLine->dwComponentType == pLine->dwComponentType)
				{
					mxLine = (MIXER_LINES) i;
					break;
				}
			}
			if (mxLine == NO_CONNECTION)
			{
				return MIXERR_INVALLINE;
			}
		}
		break;
	case MIXER_GETLINEINFOF_TARGETTYPE:
		{
			// search the first line that supports the type of component requested
			int i; 
			mxLine = NO_CONNECTION;
			for (i = 0; i < LINES_COUNT; i++)
			{
				pTempLine = FindMixerLine(i);
				if (!pTempLine)
					continue;
				if (pTempLine->Target.dwType == pLine->dwComponentType)
				{
					mxLine = (MIXER_LINES) i;
					break;
				}
			}
			if (mxLine == NO_CONNECTION)
			{
				return MIXERR_INVALLINE;
			}
		}
		break;
	default:
		MIXERRMSG1("Unknown param in mix_handle_GETLINEINFO: %d", dwParam2);
		return MMSYSERR_NOTSUPPORTED;
	}

	pTempLine = FindMixerLine(mxLine);
	pLine->dwLineID = pTempLine->dwLineID;
	pLine->dwComponentType = pTempLine->dwComponentType;
	pLine->cChannels = pTempLine->cChannels;
	pLine->cConnections = pTempLine->cConnections;
	pLine->cControls = pTempLine->cControls;
	pLine->dwDestination = pTempLine->dwDestination;
	pLine->dwSource = pTempLine->dwSource;
	_tcscpy(pLine->szShortName, pTempLine->szShortName);
	_tcscpy(pLine->szName, pTempLine->szName);

	pLine->Target.dwType = pTempLine->Target.dwType;
	pLine->Target.dwDeviceID = pTempLine->Target.dwDeviceID;
	pLine->Target.wMid = pTempLine->Target.wMid;
	pLine->Target.wPid = pTempLine->Target.wPid;
	pLine->Target.vDriverVersion = pTempLine->Target.vDriverVersion;
	pLine->fdwLine = pTempLine->fdwLine;
	_tcscpy(pLine->Target.szPname, pTempLine->Target.szPname);

	return MMSYSERR_NOERROR;

badparms:
	MIXERRMSG("Bad parameters in mix_handle_GETLINEINFO");
	SetLastError(ERROR_INVALID_PARAMETER);
	return MMSYSERR_INVALPARAM;
}


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

Function:

	mix_handle_GETLINECONTROLS

Description:

	Gets info about the controls of a line

Arguments:

	PMIXER_CONTEXT pMixer :  pointer to the mixer context structure
	DWORD dwUser : returned by the app (not used)
	DWORD dwParam1 : pointer to a MIXERLINECONTROLS structure that is filled with the controls info
	DWORD dwParam2 : flags that describe the information requested

Return Value: DWORD
-------------------------------------------------------------------*/
DWORD mix_handle_GETLINECONTROLS(PMIXER_CONTEXT pMixer, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
{
	LPMIXERLINECONTROLS pLineControl = (LPMIXERLINECONTROLS)MapPtrToProcess((PVOID)dwParam1, 
						GetCallerProcess());
	LPMIXERCONTROL pMixerControl;
	DWORD i;

	ASSERT(pMixer);

	if (!pLineControl)
	{
		MIXERRMSG("Bad pLineControl in mix_handle_GETLINECONTROLS");
		goto badparms;
	}
	pMixerControl = (LPMIXERCONTROL)MapPtrToProcess(pLineControl->pamxctrl, GetCallerProcess());

	if (pLineControl->cbStruct < sizeof(MIXERLINECONTROLS) || pLineControl->cControls < 1 || pMixerControl == NULL)
	{
		MIXERRMSG("Bad pMixerControl in mix_handle_GETLINECONTROLS");
		goto badparms;
	}
	
	// first identify the control

	switch (dwParam2 & MIXER_GETLINECONTROLSF_QUERYMASK)
	{
	case MIXER_GETLINECONTROLSF_ALL:
		{
			int nControls;
			LPMIXERLINE pTempLine;
			MIXMSG("mix_handle_GETLINECONTROLS: MIXER_GETLINECONTROLSF_ALL");
			//the caller wants all of this line's controls
			if (pLineControl->dwLineID >= LINES_COUNT)
			{
				WARNMSG("Bad pLineControl dwLineID in mix_handle_GETLINECONTROLS");
				return MIXERR_INVALLINE;
			}
			
			// does the line have any controls?
			pTempLine = FindMixerLine(pLineControl->dwLineID);
			if (!pTempLine)
			{
				WARNMSG("Unknown pLineControl dwLineID in mix_handle_GETLINECONTROLS");
				return MIXERR_INVALLINE;
			}
			if (pTempLine->cControls == 0 || 
				pTempLine->cControls > pLineControl->cControls)
			{
				WARNMSG("Line has no controls in mix_handle_GETLINECONTROLS");
				return MIXERR_INVALLINE;
			}
			
			// all seems ok; let's find the first line control
			for (nControls = i = 0; i < sizeof(g_Controls)/sizeof(g_Controls[0]); i++)
			{
				if (g_Controls[i].dwLineID == pLineControl->dwLineID)
				{
					CopyControlStruct(&pMixerControl[nControls++], i);
				}
			}
		}
		break;
	case MIXER_GETLINECONTROLSF_ONEBYID:
		MIXMSG1("mix_handle_GETLINECONTROLS: MIXER_GETLINECONTROLSF_ONEBYID: %d", pLineControl->dwControlID);
		if (pLineControl->dwControlID >= sizeof(g_Controls)/sizeof(g_Controls[0]))
			return MIXERR_INVALCONTROL;
		// the ID is the index of the control in the g_Controls table;
		if (pLineControl->cControls != 1)
			goto badparms;
		CopyControlStruct(pMixerControl, pLineControl->dwControlID);
		break;
	case MIXER_GETLINECONTROLSF_ONEBYTYPE:
		MIXMSG2("mix_handle_GETLINECONTROLS: MIXER_GETLINECONTROLSF_ONEBYTYPE: line %d, type %d", 
			pLineControl->dwLineID, pLineControl->dwControlType);
		if (pLineControl->cControls != 1)
			goto badparms;
		for (i = 0; i < sizeof(g_Controls)/sizeof(g_Controls[0]); i++)
		{
			if (g_Controls[i].dwLineID == pLineControl->dwLineID && 
				(g_Controls[i].dwControlType & MIXERCONTROL_CT_CLASS_MASK) == 
					(pLineControl->dwControlType & MIXERCONTROL_CT_CLASS_MASK))
			{
				CopyControlStruct(pMixerControl, i);
				break;
			}
		}
		// did we find any?
		if (i == sizeof(g_Controls)/sizeof(g_Controls[0]))
		{
			// no
			WARNMSG("No control of requested type");
			return MIXERR_INVALCONTROL;
		}
		break;
	default:
		return MMSYSERR_INVALFLAG;
	}

	return MMSYSERR_NOERROR;

badparms:
	MIXERRMSG("Bad parameters in mix_handle_GETLINECONTROLS");
	SetLastError(ERROR_INVALID_PARAMETER);
	return MMSYSERR_INVALPARAM;
}


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

Function:

	mix_handle_GETCONTROLDETAILS

Description:

	Gets detailed information about a control

Arguments:

	PMIXER_CONTEXT pMixer :  pointer to the mixer context structure
	DWORD dwUser : returned by the app (not used)
	DWORD dwParam1 : pointer to the MIXERCONTROLDETAILS structure where the function returns info
	DWORD dwParam2 : flags that describe the information requested

Return Value: DWORD
-------------------------------------------------------------------*/
DWORD mix_handle_GETCONTROLDETAILS(PMIXER_CONTEXT pMixer, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
{
	LPMIXERCONTROLDETAILS pControlDetails = (LPMIXERCONTROLDETAILS) MapPtrToProcess((PVOID)dwParam1, GetCallerProcess());
	DWORD dwRet = NO_ERROR;

	PDRIVER_CONTEXT pDriverContext = g_pDriverContext;
	ASSERT(pDriverContext);

	if (!pControlDetails)
		goto badparms;

	if (pControlDetails->cbStruct < sizeof(MIXERCONTROLDETAILS))
		goto badparms;
	if (pControlDetails->dwControlID >= MAX_CONTROLS)
	{
		MIXERRMSG1("mix_handle_GETCONTROLDETAILS: Bad control ID: %d", pControlDetails->dwControlID);

		return MIXERR_INVALCONTROL;
	}

	switch (dwParam2 & MIXER_GETCONTROLDETAILSF_QUERYMASK)
	{

⌨️ 快捷键说明

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