📄 mixhw.cpp
字号:
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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 + -