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

📄 mixfunc.cpp

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	case MIXER_GETCONTROLDETAILSF_VALUE:
		MIXMSG1("mix_handle_GETCONTROLDETAILS: MIXER_GETCONTROLDETAILSF_VALUE: control %d",
			pControlDetails->dwControlID);

		{
			DWORD dwRet;
			switch(g_Controls[pControlDetails->dwControlID].dwControlType)
			{
			case MIXERCONTROL_CONTROLTYPE_MUX:
			case MIXERCONTROL_CONTROLTYPE_MUTE:
				{
					MIXERCONTROLDETAILS_BOOLEAN *pDetails = (MIXERCONTROLDETAILS_BOOLEAN *)
						MapPtrToProcess(pControlDetails->paDetails, GetCallerProcess());
					
					if (!pDetails || pControlDetails->cbDetails < sizeof(MIXERCONTROLDETAILS_BOOLEAN))
					{
						MIXERRMSG2("mix_handle_GETCONTROLDETAILS: Bad parms: pointer: 0x%8.8x, size %d",
							pDetails, pControlDetails->cbDetails);
						
						goto badparms;
					}
					
					if (IsBadWritePtr((LPVOID)pDetails, sizeof(MIXERCONTROLDETAILS_BOOLEAN)))
					{
						MIXERRMSG("mix_handle_GETCONTROLDETAILS: Bad pointer");
						goto badparms;
					}
					
					if (g_Controls[pControlDetails->dwControlID].dwControlType == MIXERCONTROL_CONTROLTYPE_MUX)
					{
						DWORD fValue;
						dwRet = GetMuxValue(pDriverContext,	pControlDetails->dwControlID, &fValue);
						pDetails->fValue = fValue;
						
					}
					else	// mute
					{
						int fValue;
						dwRet = GetMixerMute(pDriverContext, pControlDetails->dwControlID, &fValue);
						pDetails->fValue = fValue;
					}
				}
				break;
			case MIXERCONTROL_CONTROLTYPE_VOLUME:
				{
					MIXERCONTROLDETAILS_UNSIGNED *pDetails = (MIXERCONTROLDETAILS_UNSIGNED *)
						MapPtrToProcess(pControlDetails->paDetails, GetCallerProcess());
					
					// for UNIFORM controls (in our case, MUTE and MUX), there needs be only one 
					// MIXERCONTROLDETAILS_xxx structure; for non uniform controls
					// we need one structure for each channel
					
					if (!pDetails || pControlDetails->cbDetails < sizeof(MIXERCONTROLDETAILS_UNSIGNED))
						goto badparms;

					if (IsBadWritePtr((LPVOID)pDetails,  pControlDetails->cChannels * pControlDetails->cbDetails))
					{
						MIXERRMSG("mix_handle_GETCONTROLDETAILS: Bad pointer");
						goto badparms;
					}
					
					dwRet = GetMixerVolume(pDriverContext,
						pControlDetails->dwControlID,
						&(pDetails[LEFT_CHANNEL].dwValue), &(pDetails[RIGHT_CHANNEL].dwValue));

					// scale values (if scaling window handle set; see scalevol.h for details)

				}
				break;
			case MIXERCONTROL_CONTROLTYPE_UNSIGNED:	// only one of that type: the ZV port sample rate
				{
					MIXERCONTROLDETAILS_UNSIGNED *pDetails = (MIXERCONTROLDETAILS_UNSIGNED *)
						MapPtrToProcess(pControlDetails->paDetails, GetCallerProcess());
					
					if (!pDetails || pControlDetails->cbDetails < sizeof(MIXERCONTROLDETAILS_UNSIGNED))
						goto badparms;

					if (IsBadWritePtr((LPVOID)pDetails, sizeof(MIXERCONTROLDETAILS_UNSIGNED)))
					{
						MIXERRMSG("mix_handle_GETCONTROLDETAILS: Bad pointer");
						goto badparms;
					}
					
					dwRet = GetUnsignedValue(pDriverContext,
						pControlDetails->dwControlID,
						&(pDetails->dwValue));
				}
				break;
			default:
				MIXERRMSG1("mix_handle_GETCONTROLDETAILS: Bad control type: %d",
					g_Controls[pControlDetails->dwControlID].dwControlType);
				ASSERT(FALSE);
			}
		}
		break;
	case MIXER_GETCONTROLDETAILSF_LISTTEXT:
		MIXMSG1("mix_handle_GETCONTROLDETAILS: MIXER_GETCONTROLDETAILSF_LISTTEXT: control %d",
			pControlDetails->dwControlID);
		switch(g_Controls[pControlDetails->dwControlID].dwControlType)
		{
		case MIXERCONTROL_CONTROLTYPE_MUX:
			{
				int i;
				MIXERCONTROLDETAILS_LISTTEXT *pDetails = (MIXERCONTROLDETAILS_LISTTEXT *)
					MapPtrToProcess(pControlDetails->paDetails, GetCallerProcess());
				
				if (!pDetails || pControlDetails->cbDetails < sizeof(MIXERCONTROLDETAILS_LISTTEXT))
					goto badparms;

				if (IsBadWritePtr(pDetails->szName, MIXER_LONG_NAME_CHARS))
				{
					MIXERRMSG("mix_handle_GETCONTROLDETAILS: Bad pointer");
					goto badparms;
				}

				// get the current mux'ed line ID and name
				for (i = 0; i < MAX_MULTIPLEXERS; i++)
				{
					if (g_Multiplexers[i].dwMuxID == pControlDetails->dwControlID)
					{
						DWORD dwValue;
						LPMIXERLINE pTempLine;
						dwRet = GetMuxValue(pDriverContext, pControlDetails->dwControlID, &dwValue);
						if (NO_ERROR != dwRet)
						{
							SetLastError(dwRet);
							return MIXERR_INVALCONTROL; // not supported or another error
						}

						pDetails->dwParam1 = g_Multiplexers[i].muxedLines[dwValue];
						pTempLine = FindMixerLine(pDetails->dwParam1);
						if (!pTempLine)
						{
							MIXERRMSG1("mix_handle_GETCONTROLDETAILS: Bad line ID: %d", pDetails->dwParam1);
							return MIXERR_INVALLINE;
						}
						_tcscpy(pDetails->szName, pTempLine->szName);
						break;
					}
				}
				ASSERT(i < MAX_MULTIPLEXERS);
			}
			break;
		default:	// can't do MIXER_GETCONTROLDETAILSF_LISTTEXT on volume or mute controls
			goto badparms;
		}
		break;
	default:
		return MMSYSERR_INVALFLAG;
	}

	if (dwRet != NO_ERROR)
	{
		SetLastError(dwRet);
		return MMSYSERR_NODRIVER;
	}

	return MMSYSERR_NOERROR;

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


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

Function:

	mix_handle_SETCONTROLDETAILS

Description:

	Sets a control's value

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 describing the control
	DWORD dwParam2 : flags that describe the value to be set

Return Value: DWORD
-------------------------------------------------------------------*/
DWORD mix_handle_SETCONTROLDETAILS(PMIXER_CONTEXT pMixer, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
{
	// this is where the real work is!
	LPMIXERCONTROLDETAILS pControlDetails = (LPMIXERCONTROLDETAILS) MapPtrToProcess((PVOID)dwParam1, GetCallerProcess());
	PDRIVER_CONTEXT pDriverContext = g_pDriverContext;
	ASSERT(pMixer && pDriverContext);

	if (!pControlDetails)
		goto badparms;

	if (pControlDetails->cbStruct < sizeof(MIXERCONTROLDETAILS))
		goto badparms;

	if (pControlDetails->dwControlID >= MAX_CONTROLS)
	{
		MIXERRMSG1("mix_handle_SETCONTROLDETAILS: Bad control ID: %d", pControlDetails->dwControlID);
		return MIXERR_INVALCONTROL;
	}

	switch (dwParam2 & MIXER_SETCONTROLDETAILSF_QUERYMASK )
	{
	case MIXER_SETCONTROLDETAILSF_VALUE:
		{
			DWORD dwRet;
			switch(g_Controls[pControlDetails->dwControlID].dwControlType)
			{
			case MIXERCONTROL_CONTROLTYPE_MUX:
			case MIXERCONTROL_CONTROLTYPE_MUTE:
				{
					MIXERCONTROLDETAILS_BOOLEAN *pDetails = (MIXERCONTROLDETAILS_BOOLEAN *)
						MapPtrToProcess(pControlDetails->paDetails, GetCallerProcess());
					
					if (!pDetails || pControlDetails->cbDetails < sizeof(MIXERCONTROLDETAILS_BOOLEAN))
						goto badparms;
					
					if (g_Controls[pControlDetails->dwControlID].dwControlType == MIXERCONTROL_CONTROLTYPE_MUX)
					{
						dwRet = SetMuxValue(pDriverContext,
							pControlDetails->dwControlID, 
							pDetails->fValue);
						
					}
					else	// mute
					{
						dwRet = SetMixerMute(pDriverContext, 
							pControlDetails->dwControlID,
							pDetails->fValue);
					}
				}
				break;
			case MIXERCONTROL_CONTROLTYPE_VOLUME:
				{
					MIXERCONTROLDETAILS_UNSIGNED *pDetails = (MIXERCONTROLDETAILS_UNSIGNED *)
						MapPtrToProcess(pControlDetails->paDetails, GetCallerProcess());
					
					// for UNIFORM controls (in our case, MUTE and MUX), there needs be only one 
					// MIXERCONTROLDETAILS_xxx structure; for non uniform controls
					// we need one structure for each channel

					if (!pDetails || 
						pControlDetails->cbDetails < sizeof(MIXERCONTROLDETAILS_UNSIGNED))
						goto badparms;

					if (IsBadWritePtr((LPVOID)pDetails,  pControlDetails->cChannels * pControlDetails->cbDetails))
					{
						MIXERRMSG("error: Bad pointer in mix_handle_SETCONTROLDETAILS");
						goto badparms;
					}

					if (pControlDetails->cChannels == 1)
						pDetails[RIGHT_CHANNEL].dwValue = pDetails[LEFT_CHANNEL].dwValue;

					if (pDetails[LEFT_CHANNEL].dwValue > MAX_ATTENUATION ||
							pDetails[RIGHT_CHANNEL].dwValue > MAX_ATTENUATION)
						goto badparms;

					dwRet = SetMixerVolume(pDriverContext,
						pControlDetails->dwControlID,
						pDetails[LEFT_CHANNEL].dwValue, pDetails[RIGHT_CHANNEL].dwValue);

				}
				break;
			case MIXERCONTROL_CONTROLTYPE_UNSIGNED:
				{
					MIXERCONTROLDETAILS_UNSIGNED *pDetails = (MIXERCONTROLDETAILS_UNSIGNED *)
						MapPtrToProcess(pControlDetails->paDetails, GetCallerProcess());
					
					if (!pDetails || pControlDetails->cbDetails < sizeof(MIXERCONTROLDETAILS_UNSIGNED))
						goto badparms;

					dwRet = SetUnsignedValue(pDriverContext,
						pControlDetails->dwControlID,
						pDetails->dwValue);
				}
				break;
			default:
				MIXERRMSG2("mix_handle_SETCONTROLDETAILS: Control %d, unknown type: 0x%8.8x", pControlDetails->dwControlID, 
					g_Controls[pControlDetails->dwControlID].dwControlType);
				dwRet = ERROR_NOT_SUPPORTED;
			}
			
			if (dwRet != NO_ERROR)
			{
				SetLastError(dwRet);
				return MMSYSERR_NODRIVER;
			}
		}
		break;
	default:
		return MMSYSERR_INVALFLAG;
	}

	// all seems ok; call registered callbacks (if any)

	{
		PMIXER_CONTEXT pMix = pDriverContext->pMixerContextList;
		CALLBACKINFO cbi;
		DWORD dwOldPermissions = SetProcPermissions(0xFFFFFFFF);
		while (pMix)
		{
			if (pMix->pfnMixerCallback)
			{
				cbi.hProc   = (PVOID) pMix->hProcess;
				cbi.pfn     = (FARPROC) pMix->pfnMixerCallback;
				cbi.pvArg0  = (PVOID) pMix;	// the first parameter is here
				__try
				{
					PerformCallBack(&cbi, MM_MIXM_CONTROL_CHANGE, pMix->dwInstance, pControlDetails->dwControlID, 0);
				} 
				__except(EXCEPTION_EXECUTE_HANDLER) 
				{
					MIXERRMSG("Callback error!");
				}
			}
			pMix = pMix->pNext;
		}
	    SetProcPermissions(dwOldPermissions );
	}
	return MMSYSERR_NOERROR;

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


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

Function:

	CopyControlStruct

Description:

	

Arguments:

	PMIXERCONTROL pMixerControl :
	int iIndex :

Return Value: void
-------------------------------------------------------------------*/
void CopyControlStruct(PMIXERCONTROL pMixerControl, int iIndex)
{

	pMixerControl->cbStruct = sizeof(MIXERCONTROL);
	pMixerControl->dwControlID = iIndex;
//	pMixerControl->dwControlType = g_Controls[iIndex].dwControlType & (MIXERCONTROL_CT_SUBCLASS_MASK | MIXERCONTROL_CT_CLASS_MASK); 
	pMixerControl->dwControlType = g_Controls[iIndex].dwControlType; 
	// the volume controls act separately on the two channels (i.e., you can have different volumes on left and right)
	// the mute and mux are uniform: they act the same on both channels
	pMixerControl->fdwControl = (MIXERCONTROL_CONTROLTYPE_VOLUME == g_Controls[iIndex].dwControlType)?
								0:
								MIXERCONTROL_CONTROLF_UNIFORM; 
	pMixerControl->cMultipleItems = 0; 
	_tcscpy(pMixerControl->szShortName, g_Controls[iIndex].szShortName);
	_tcscpy(pMixerControl->szName, g_Controls[iIndex].szName); 
//	pMixerControl->Bounds.dwMinimum = g_Controls[iIndex].dwMinimum; 
//	pMixerControl->Bounds.dwMaximum = g_Controls[iIndex].dwMaximum;
	
	// [CC - 7/23/1999 ] see comments in csmix.h
	pMixerControl->Bounds.dwMinimum = 0; 
	pMixerControl->Bounds.dwMaximum = MAX_ATTENUATION;
	pMixerControl->Metrics.cSteps = MAX_ATTENUATION;
}

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

Function:

	mix_FreeMixer

Description:

	Frees a mixer device context and removes it from the contexts list

Arguments:

	PMIXER_CONTEXT pMixer :  pointer to the mixer context structure

Return Value: BOOL
-------------------------------------------------------------------*/
BOOL mix_FreeMixer(PMIXER_CONTEXT pMixer)
{
	BOOL retval = TRUE;
	PMIXER_CONTEXT pTemp, pPrev = NULL;
	
	LockMixerList();
	pTemp = g_pDriverContext->pMixerContextList;

	while(pTemp)
	{
		if (pTemp == pMixer)
			break;
		pPrev = pTemp;
		pTemp = pTemp->pNext;
	}
	
	if (NULL == pTemp)
	{	// the device wasn't found in the list
		RETAILMSG( 1, (TEXT("Error: mix_FreeMixer: bad Open Handle 0x%08x\r\n"), pMixer) );
		SetLastError( ERROR_INVALID_HANDLE );
		retval = FALSE;
	}
	else
	{	// device found, pTemp points to it, and pPrev points to the previous one in the list
		// unless it's the first one, in which case pPrev is null
		if (pPrev)
			pPrev->pNext = pTemp->pNext;
		else
			g_pDriverContext->pMixerContextList = pTemp->pNext;

		LocalFree(pTemp);
	}

	UnlockMixerList();

	return retval;
}



#if 0
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Function:

	ScaleValues

Description:

	Scales the values to be transmitted to the hardware
	Currently calls the GI tv application to do the work;
	this may change in the future
	
Arguments:

	PMIXER_CONTEXT pMixer :	the driver context
	DWORD dwControlIndex :				the index in the g_Controls array of the control to be scaled
	DWORD *pdwLeft :					the 
	DWORD *pdwRight :
	UMSG bDirectConversion :

Return Value: void
-------------------------------------------------------------------*/
void ScaleValues(PMIXER_CONTEXT pMixer, DWORD dwControlIndex,
				 DWORD *pdwLeft, DWORD *pdwRight, BOOL bDirectConversion)
{
	// is scaling to be done for all channels? It makes sense for TV audio, but not for others
	/*
	
	  if (dwControlIndex != 0)
		return;
	*/
	if (IsWindow(pDriverContext->hHookWnd))
	{
		DWORD dwVal = SendMessage(pDriverContext->hHookWnd, // the window of the GI tv app
			bDirectConversion?	
				WM_SCALEDIRECT:			// convert from application data to hardware data
				WM_SCALEINVERSE,		// convert from hardware to app data
			MAKELONG(g_Controls[dwControlIndex].dwMinimum,
			g_Controls[dwControlIndex].dwMaximum),	// minimum and maximum values the hardware accepts for the control
			MAKELONG(*pdwRight, *pdwLeft));	// values to be scaled

		// check the received values against the bounds
		if (GET_LEFT_CHANNEL(dwVal) >= min(g_Controls[dwControlIndex].dwMinimum,
				g_Controls[dwControlIndex].dwMaximum) &&
			GET_LEFT_CHANNEL(dwVal) <= max(g_Controls[dwControlIndex].dwMinimum,
				g_Controls[dwControlIndex].dwMaximum) &&
			GET_RIGHT_CHANNEL(dwVal) >= min(g_Controls[dwControlIndex].dwMinimum,
				g_Controls[dwControlIndex].dwMaximum) &&
			GET_RIGHT_CHANNEL(dwVal) <= max(g_Controls[dwControlIndex].dwMinimum,
				g_Controls[dwControlIndex].dwMaximum))
		{	// Ok, set those values
			*pdwRight = GET_RIGHT_CHANNEL(dwVal);
			*pdwLeft = GET_LEFT_CHANNEL(dwVal);

			RETAILMSG(1, (TEXT("ScaleValues: Got scaled values: (%d, %d)\r\n"),
					*pdwLeft,
					*pdwRight));
		}
		else
		{	// received values are bad, ignore them
			RETAILMSG(1, (TEXT("ScaleValues: Got bad scaled values: (%d, %d)\r\n"),
					GET_LEFT_CHANNEL(dwVal),
					GET_RIGHT_CHANNEL(dwVal)));
		}
	}
}
#endif

⌨️ 快捷键说明

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