📄 mixerdrv.cpp
字号:
wcscpy(pDst->szName, pSrc->szName);
wcscpy(pDst->szShortName, pSrc->szName);
pDst->dwControlType = pSrc->dwType;
pDst->cMultipleItems = 0;
switch(pSrc->dwType) {
case MIXERCONTROL_CONTROLTYPE_VOLUME:
pDst->fdwControl = 0;
pDst->Metrics.cSteps = LOGICAL_VOLUME_STEPS;
pDst->Bounds.lMaximum = LOGICAL_VOLUME_MAX;
pDst->Bounds.lMinimum = LOGICAL_VOLUME_MIN;
break;
case MIXERCONTROL_CONTROLTYPE_ONOFF:
case MIXERCONTROL_CONTROLTYPE_MUTE:
pDst->fdwControl = MIXERCONTROL_CONTROLF_UNIFORM;
pDst->Metrics.cSteps = 0;
pDst->Bounds.lMaximum = 1;
pDst->Bounds.lMinimum = 0;
break;
default:
DEBUGMSG(ZONE_ERROR, (TEXT("Unexpected control type %08x\r\n"), pSrc->dwType));
ASSERT(0);
}
}
static PMIXER_CALLBACK g_pHead; // list of open mixer instances
void
PerformMixerCallbacks(DWORD dwMessage, DWORD dwId)
{
PMIXER_CALLBACK pCurr;
for (pCurr = g_pHead; pCurr != NULL; pCurr = pCurr->pNext) {
if (pCurr->pfnCallback != NULL) {
DEBUGMSG(ZONE_HWMIXER, (TEXT("MixerCallback(%d)\r\n"), dwId));
pCurr->pfnCallback(pCurr->hmx, dwMessage, 0, dwId, 0);
}
}
}
DWORD
wdev_MXDM_GETDEVCAPS (PMIXERCAPS pCaps, DWORD dwSize)
{
pCaps->wMid = MM_MICROSOFT;
pCaps->wPid = MM_MSFT_WSS_MIXER;
wcscpy(pCaps->szPname, DEVICE_NAME);
pCaps->vDriverVersion = DRIVER_VERSION;
pCaps->cDestinations = NELEMS(g_dst_lines);
pCaps->fdwSupport = 0;
return MMSYSERR_NOERROR;
}
DWORD
wdev_MXDM_OPEN (PDWORD phMixer, PMIXEROPENDESC pMOD, DWORD dwFlags)
{
PMIXER_CALLBACK pNew;
pNew = (PMIXER_CALLBACK) LocalAlloc(LMEM_FIXED, sizeof(MIXER_CALLBACK));
if (pNew == NULL) {
ERRMSG("wdev_MXDM_OPEN: out of memory");
return MMSYSERR_NOMEM;
}
pNew->hmx = (DWORD) pMOD->hmx;
if (dwFlags & CALLBACK_FUNCTION) {
pNew->pfnCallback = (PFNDRIVERCALL) pMOD->dwCallback;
}
else {
pNew->pfnCallback = NULL;
}
pNew->pNext = g_pHead;
g_pHead = pNew;
*phMixer = (DWORD) pNew;
return MMSYSERR_NOERROR;
}
DWORD
wdev_MXDM_CLOSE (DWORD dwHandle)
{
PMIXER_CALLBACK pCurr, pPrev;
pPrev = NULL;
for (pCurr = g_pHead; pCurr != NULL; pCurr = pCurr->pNext) {
if (pCurr == (PMIXER_CALLBACK) dwHandle) {
if (pPrev == NULL) {
// we're deleting the first item
g_pHead = pCurr->pNext;
}
else {
pPrev->pNext = pCurr->pNext;
}
LocalFree(pCurr);
break;
}
pPrev = pCurr;
}
return MMSYSERR_NOERROR;
}
DWORD
wdev_MXDM_GETLINEINFO(PMIXERLINE pQuery, DWORD dwFlags)
{ int i;
// pQuery is validated by API - points to accessible, properly sized MIXERLINE structure
// result - assume failure
PMXLINEDESC pFound = NULL;
MMRESULT mmRet = MIXERR_INVALLINE;
USHORT usLineID = NOLINE;
switch (dwFlags & MIXER_GETLINEINFOF_QUERYMASK) {
case MIXER_GETLINEINFOF_DESTINATION:
DEBUGMSG(ZONE_HWMIXER, (TEXT("GetMixerLineInfo DESTINATION %x\r\n"), pQuery->dwDestination));
{
if (pQuery->dwDestination >= NELEMS(g_dst_lines)) {
DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineInfo: invalid destination line %d\r\n"), pQuery->dwDestination));
return MIXERR_INVALLINE;
}
usLineID = g_dst_lines[pQuery->dwDestination];
}
break;
case MIXER_GETLINEINFOF_LINEID:
DEBUGMSG(ZONE_HWMIXER, (TEXT("GetMixerLineInfo LINEID %x\r\n"), pQuery->dwLineID));
usLineID = (USHORT) pQuery->dwLineID;
break;
case MIXER_GETLINEINFOF_SOURCE:
DEBUGMSG(ZONE_HWMIXER, (TEXT("GetMixerLineInfo SOURCE %x %x\r\n"), pQuery->dwDestination, pQuery->dwSource));
{
PMXLINEDESC pLine;
// look up the destination line, then index into it's source table
// to find the indexed source.
if (pQuery->dwDestination >= NELEMS(g_dst_lines)) {
DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineInfo: invalid destination line %d\r\n"), pQuery->dwDestination));
return MIXERR_INVALLINE;
}
pLine = LookupMxLine(g_dst_lines[pQuery->dwDestination]);
if (pLine == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineInfo: inconsistent internal mixer line table\r\n")));
return MMSYSERR_ERROR;
}
if (pQuery->dwSource >= pLine->ucConnections) {
DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineInfo: invalid source line %d\r\n"), pQuery->dwSource));
return MIXERR_INVALLINE;
}
usLineID = pLine->pSources[pQuery->dwSource];
}
break;
case MIXER_GETLINEINFOF_COMPONENTTYPE:
DEBUGMSG(ZONE_HWMIXER, (TEXT("GetMixerLineInfo COMPONENT\r\n")));
break;
case MIXER_GETLINEINFOF_TARGETTYPE:
DEBUGMSG(ZONE_HWMIXER, (TEXT("GetMixerLineInfo TARGET\r\n")));
// valid query, but we're not going to form usLineID
break;
default:
DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineInfo: invalid query %08x\r\n"), dwFlags & MIXER_GETLINEINFOF_QUERYMASK));
return MMSYSERR_INVALPARAM;
}
switch (dwFlags & MIXER_GETLINEINFOF_QUERYMASK) {
case MIXER_GETLINEINFOF_COMPONENTTYPE:
// scan for line of proper type
for (i = 0; i < nlines; i++) {
if (g_mixerline[i].dwComponentType == pQuery->dwComponentType) {
pFound = &g_mixerline[i];
break;
}
}
#ifdef DEBUG
if (pFound == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineInfo: no line of component type %08x\r\n"), pQuery->dwComponentType));
}
#endif
break;
case MIXER_GETLINEINFOF_TARGETTYPE:
// scan for target type
for (i = 0; i < nlines; i++) {
if (g_mixerline[i].dwTargetType == pQuery->Target.dwType) {
pFound = &g_mixerline[i];
break;
}
}
#ifdef DEBUG
if (pFound == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineInfo: no line of target type %08x\r\n"), pQuery->Target.dwType));
}
#endif
break;
case MIXER_GETLINEINFOF_DESTINATION:
case MIXER_GETLINEINFOF_LINEID:
case MIXER_GETLINEINFOF_SOURCE:
pFound = LookupMxLine(usLineID);
if (pFound == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineInfo: invalid line ID %08x\r\n"), usLineID));
return MMSYSERR_ERROR;
}
break;
default:
// should never happen - we filter for this in the first switch()
break;
}
if (pFound != NULL) {
pQuery->cChannels = pFound->ucChannels;
pQuery->cConnections = pFound->ucConnections;
pQuery->cControls = pFound->ucControls;
pQuery->dwComponentType = pFound->dwComponentType;
pQuery->dwLineID = pFound->usLineID;
pQuery->dwDestination = pFound->ucDstIndex;
pQuery->dwSource = pFound->ucSrcIndex;
pQuery->fdwLine = pFound->ucFlags;
pQuery->Target.dwDeviceID = 0;
pQuery->Target.dwType = pFound->dwTargetType;
pQuery->Target.vDriverVersion = DRIVER_VERSION;
pQuery->Target.wMid = MM_MICROSOFT;
pQuery->Target.wPid = MM_MSFT_WSS_MIXER;
wcscpy(pQuery->szName, pFound->szName);
wcscpy(pQuery->szShortName, pFound->szShortName);
wcscpy(pQuery->Target.szPname, DEVICE_NAME);
mmRet = MMSYSERR_NOERROR;
DEBUGMSG(ZONE_HWMIXER, (TEXT("GetMixerLineInfo: \"%s\" %08x\r\n"), pFound->szName, pFound->ucFlags));
}
return mmRet;
}
DWORD
wdev_MXDM_GETLINECONTROLS (PMIXERLINECONTROLS pQuery, DWORD dwFlags)
{
UINT i;
PMIXERCONTROL pDstControl = pQuery->pamxctrl;
USHORT usLineID = (USHORT) pQuery->dwLineID;
DWORD dwCount = pQuery->cControls;
switch (dwFlags & MIXER_GETLINECONTROLSF_QUERYMASK) {
case MIXER_GETLINECONTROLSF_ALL:
DEBUGMSG(ZONE_HWMIXER, (TEXT("GetMixerLineControls: ALL %x\r\n"), usLineID));
// retrieve all controls for the line pQuery->dwLineID
{
PMXLINEDESC pFound = LookupMxLine(usLineID);
if (pFound == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineControls: invalid line ID %04x\r\n"), usLineID));
return MIXERR_INVALLINE;
}
if (pFound->ucControls != dwCount) {
DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineControls: incorrect number of controls. Expect %d, found %d.\r\n"),dwCount,pFound->ucControls));
return MMSYSERR_INVALPARAM;
}
for (i = 0; i < ncontrols && dwCount > 0; i++) {
PMXCONTROLDESC pSrcControl = &g_controls[i];
if (pSrcControl->usLineID == usLineID) {
CopyMixerControl(pDstControl, pSrcControl, i);
pDstControl++;
dwCount--;
}
}
}
break;
case MIXER_GETLINECONTROLSF_ONEBYID:
DEBUGMSG(ZONE_HWMIXER, (TEXT("GetMixerLineControls: ONEBYID %x\r\n"), pQuery->dwControlID));
// retrieve the control specified by pQuery->dwControlID
if (pQuery->dwControlID >= ncontrols) {
DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineControls: invalid control ID %d (max %d)\r\n"), pQuery->dwControlID, ncontrols));
return MIXERR_INVALCONTROL;
}
if (dwCount < 1) {
DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineControls: control count must be nonzero\r\n")));
return MMSYSERR_INVALPARAM;
}
CopyMixerControl(pDstControl, &g_controls[pQuery->dwControlID], pQuery->dwControlID);
pQuery->dwLineID = g_controls[pQuery->dwControlID].usLineID;
break;
case MIXER_GETLINECONTROLSF_ONEBYTYPE:
// retrieve the control specified by pQuery->dwLineID and pQuery->dwControlType
{
UINT index;
PMXLINEDESC pFound = LookupMxLine(usLineID);
if (pFound == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineControls: invalid line ID %04x\r\n"), usLineID));
return MIXERR_INVALLINE;
}
DEBUGMSG(ZONE_HWMIXER, (TEXT("GetMixerLineControls: ONEBYTYPE %x \"%s\"\r\n"), usLineID, pFound->szName));
if (dwCount < 1) {
DEBUGMSG(ZONE_ERROR, (TEXT("GetMixerLineControls: control count must be non zero\r\n")));
return MMSYSERR_INVALPARAM;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -