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

📄 ac97mixer.cpp

📁 EP931X系列的WinCE声卡驱动源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
// -----------------------------------------------------------------------------
//
//      THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//      ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//      THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//      PARTICULAR PURPOSE.
//  
// -----------------------------------------------------------------------------

#include "wavecommon.h"
#include "ac97regs.h"
#define NELEMS(a) (sizeof(a)/sizeof((a)[0]))

#define LOGICAL_VOLUME_MAX  0x10000
#define LOGICAL_VOLUME_MIN  0

// #define ZONE_MXDM 0

#ifdef DEBUG

// DEBUG-only support for displaying control type codes in readable form

typedef struct 
{
    DWORD   val;
    PWSTR   str;
} MMSYSCODE;

#define MXCTYPE(typ) {typ, TEXT(#typ)}

MMSYSCODE ctype_table[] =
{
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_CUSTOM),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_BASS),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_EQUALIZER),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_FADER),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_TREBLE),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_VOLUME),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_MIXER),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_MUX),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_SINGLESELECT),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_BOOLEANMETER),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_PEAKMETER),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_SIGNEDMETER),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_DECIBELS),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_PERCENT),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_SIGNED),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_UNSIGNED),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_PAN),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_QSOUNDPAN),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_SLIDER),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_BOOLEAN),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_BUTTON),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_LOUDNESS),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_MONO),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_MUTE),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_ONOFF),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_STEREOENH),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_MICROTIME),
    MXCTYPE(MIXERCONTROL_CONTROLTYPE_MILLITIME),
};

PWSTR
COMPTYPE(DWORD dwValue)
{ int i;

    for (i = 0; i < NELEMS(ctype_table); i++) {
        if (ctype_table[i].val == dwValue) {
            return ctype_table[i].str;
        }
    }
    return TEXT("<unknown>");

}

#else
#define COMPTYPE(n) TEXT("<>")
#endif

// destinations
enum {
    LINE_OUT = 0x80,
    PCM_IN,
    CD,
    LINE_IN,
    MIC,
    AUX,
    PCM_OUT,
    STEREO_MIX,
    // unsupported lines - defined in AC97 spec, but not supported in this driver
    VIDEO,
    MONO_MIX,
    PHONE,
    NOLINE   = 0xff // doesn't HAVE to be FF, but makes it easier to see
};
// mixer line ID are 16-bit values formed by concatenating the source and destination line indices
// 
#define MXLINEID(dst,src)       ((USHORT) ((USHORT)(dst) | (((USHORT) (src)) << 8)))
#define GET_MXLINE_SRC(lineid)  ((lineid) >> 8)
#define GET_MXLINE_DST(lineid)  ((lineid) & 0xff)
#define GET_MXCONTROL_ID(ctl)   ((ctl)-g_controls)

const USHORT
g_dst_lines[] = 
    {
    MXLINEID(LINE_OUT,NOLINE),
    MXLINEID(PCM_IN,NOLINE)
};

const USHORT
g_LINE_OUT_sources[] = 
{
    MXLINEID(LINE_OUT,CD),
    MXLINEID(LINE_OUT,LINE_IN),
    MXLINEID(LINE_OUT,MIC),
    MXLINEID(LINE_OUT,AUX),
    MXLINEID(LINE_OUT,PCM_OUT)
};

const USHORT
g_PCM_IN_sources[] = 
{
    MXLINEID(PCM_IN,CD),
    MXLINEID(PCM_IN,LINE_IN),
    MXLINEID(PCM_IN,MIC),
    MXLINEID(PCM_IN,AUX),
    MXLINEID(PCM_IN,STEREO_MIX)
};

// MXLINEDESC corresponds to MIXERLINE, but is designed to conserve space

typedef struct tagMXLINEDESC  const * PMXLINEDESC, MXLINEDESC;
typedef struct tagMXCONTROLDESC  const * PMXCONTROLDESC, MXCONTROLDESC;

struct tagMXLINEDESC { 
    DWORD dwComponentType; 
    PCWSTR szShortName; 
    PCWSTR szName; 
    DWORD ucFlags; 
    USHORT const * pSources;
    USHORT usLineID;
    UINT8 ucChannels; 
    UINT8 ucConnections; 
    UINT8 ucControls; 
    DWORD   dwTargetType;
    UINT8   ucDstIndex;
    UINT8   ucSrcIndex;
} ; 



    // Destinations: 
    //      LINE_OUT - line out jack
    //      PCM_IN - input to ADC
    // Sources:
    //  CD - CD_IN connector
    //  AUX - AUX_IN connector
    //  MIC - MIC jack
    //  LINE_IN - LINE_IN jack
    //  VIDEO - VIDEO_IN connctor
    //  PCM_OUT - output of DAC0+DAC1
    //  MIX_OUT - mix of (MIC, LINE_IN, PCM_OUT, VIDEO, CD, AUX)


// MXCONTROLDESC is driver shorthand for Volume and Mute MIXERCONTROL
struct tagMXCONTROLDESC
{
    PWSTR   szName;
    DWORD   dwType;
    USHORT  usLineID;           // line that owns this control
    USHORT  usMask;             // mask for valid range for this codec register
    UCHAR   ucCodecRegister;    // address of AC97 register for this control
};

#define MXCE(dst,src,nme,type,mask,reg) {TEXT(nme),type,MXLINEID(dst,src),mask,reg}

#define MUTE_BIT    0x8000

const MXCONTROLDESC
g_controls[] = {
    MXCE(LINE_OUT,NOLINE,   "Master Volume",    MIXERCONTROL_CONTROLTYPE_VOLUME,  0x000f, AC97_MASTER_VOLUME),
    MXCE(LINE_OUT,NOLINE,   "Master Mute",      MIXERCONTROL_CONTROLTYPE_MUTE,    0x8000, AC97_MASTER_VOLUME),

    MXCE(PCM_IN,NOLINE,     "Record Select",    MIXERCONTROL_CONTROLTYPE_MUX,          5, AC97_RECORD_SELECT),

    // LINE_OUT source controls
    MXCE(LINE_OUT,CD,       "CD Volume",        MIXERCONTROL_CONTROLTYPE_VOLUME,  0x001f, AC97_CD_VOLUME),
    MXCE(LINE_OUT,CD,       "CD Mute",          MIXERCONTROL_CONTROLTYPE_MUTE,    0x8000, AC97_CD_VOLUME),

    MXCE(LINE_OUT,LINE_IN,  "Line In Volume",   MIXERCONTROL_CONTROLTYPE_VOLUME,  0x001f, AC97_LINEIN_VOLUME),
    MXCE(LINE_OUT,LINE_IN,  "Line In Mute",     MIXERCONTROL_CONTROLTYPE_MUTE,    0x8000, AC97_LINEIN_VOLUME),

    MXCE(LINE_OUT,MIC,      "Mic Volume",       MIXERCONTROL_CONTROLTYPE_VOLUME,  0x001f, AC97_MIC_VOLUME),
    MXCE(LINE_OUT,MIC,      "Mic Mute",         MIXERCONTROL_CONTROLTYPE_MUTE,    0x8000, AC97_MIC_VOLUME),
    MXCE(LINE_OUT,MIC,      "Mic Boost",        MIXERCONTROL_CONTROLTYPE_ONOFF,   0x0004, AC97_MIC_VOLUME),

    MXCE(LINE_OUT,AUX,      "Aux Volume",       MIXERCONTROL_CONTROLTYPE_VOLUME,  0x001f, AC97_AUX_VOLUME),
    MXCE(LINE_OUT,AUX,      "Aux Mute",         MIXERCONTROL_CONTROLTYPE_MUTE,    0x8000, AC97_AUX_VOLUME),

    MXCE(LINE_OUT,PCM_OUT,  "Digital Volume",   MIXERCONTROL_CONTROLTYPE_VOLUME,  0x001f, AC97_PCMOUT_VOLUME),
    MXCE(LINE_OUT,PCM_OUT,  "Digital Mute",     MIXERCONTROL_CONTROLTYPE_MUTE,    0x8000, AC97_PCMOUT_VOLUME),

    // PCM_IN source controls

    // AC97 spec indicates that none of the inputs to the input MUX have Volume/Mute capabilities,
    // but that the driver should create a "virtual" volume/mute control for each mux input
    // When the application changes the MUX input line, the driver is responsible for
    // adjusting the Record Gain register accordingly.

    MXCE(PCM_IN,CD,         "CD Volume",        MIXERCONTROL_CONTROLTYPE_VOLUME,  0x000f, AC97_RECORD_GAIN),

    MXCE(PCM_IN,LINE_IN,    "Line In Volume",   MIXERCONTROL_CONTROLTYPE_VOLUME,  0x000f, AC97_RECORD_GAIN),

    MXCE(PCM_IN,STEREO_MIX, "Stereo Mix Volume",MIXERCONTROL_CONTROLTYPE_VOLUME,  0x000f, AC97_RECORD_GAIN),

    MXCE(PCM_IN,MIC,        "Mic Volume",       MIXERCONTROL_CONTROLTYPE_VOLUME,  0x000f, AC97_RECORD_GAIN),
    MXCE(PCM_IN,MIC,        "Mic Boost",        MIXERCONTROL_CONTROLTYPE_ONOFF,   0x0040, AC97_MIC_VOLUME),

    MXCE(PCM_IN,AUX,        "Aux Volume",       MIXERCONTROL_CONTROLTYPE_VOLUME,  0x000f, AC97_RECORD_GAIN),

};
const int ncontrols = NELEMS(g_controls);

// MuxIndexToLine
// this table translates indices from the AC97_RECORD_SELECT (0x1A) register to line IDs
// note that not all entries in the table correspond to lines that are implemented
const USHORT MuxIndexToLine[] =
{
    MXLINEID(PCM_IN,MIC),
    MXLINEID(PCM_IN,CD),
    MXLINEID(PCM_IN,VIDEO),
    MXLINEID(PCM_IN,AUX),
    MXLINEID(PCM_IN,LINE_IN),
    MXLINEID(PCM_IN,STEREO_MIX),
    MXLINEID(PCM_IN,MONO_MIX),
    MXLINEID(PCM_IN,PHONE),
};


// mixerline ID
#define _MXLE(id,dst,src,flags,comptype,nch,ncnx,nctrl,sname,lname,target,sarray)\
    {comptype,\
    TEXT(sname),TEXT(lname),\
    flags, \
    sarray,\
    id,\
    nch,ncnx,nctrl,\
    target,\
    dst,src}

// declare a destination line
#define MXLED(id,dst,flags,comptype,nch,nctrl,sname,lname,target)\
    _MXLE(MXLINEID(id,NOLINE),dst,NOLINE,flags,comptype,nch,NELEMS(g_##id##_sources),nctrl,sname,lname,target,g_##id##_sources)\

// declar a source line
#define MXSLE(id,dst,src,flags,comptype,nch,nctrl,sname,lname,target)\
    _MXLE(id,dst,src,flags,comptype,nch,0,nctrl,sname,lname,target,NULL)\


const MXLINEDESC 
g_mixerline[] = 
{
    // dst line 0 - speaker out
    MXLED(LINE_OUT, 0,
        MIXERLINE_LINEF_ACTIVE, // no flags
        MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,
        2, // stereo
        2, // controls
        "Volume Control","Volume Control",
        MIXERLINE_TARGETTYPE_WAVEOUT
        ),
    // dst line 1 - PCM input
    MXLED(PCM_IN, 1,
        MIXERLINE_LINEF_ACTIVE, // flags
        MIXERLINE_COMPONENTTYPE_DST_WAVEIN,
        2, // stereo
        1, // 1 control (MUX) - the AC97 record gain register is virtualized across all mux inputs
        "Recording Contr","Recording Control",
        MIXERLINE_TARGETTYPE_WAVEIN
        ),

    // ----------------------
    // LINE_OUT Sources Lines
    // ----------------------

    // src line 0 - CD
    MXSLE(MXLINEID(LINE_OUT,CD), 0, 0,
        MIXERLINE_LINEF_ACTIVE | MIXERLINE_LINEF_SOURCE, // flags
        MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC,
        2,2,
        "CD Audio","CD Audio",
        MIXERLINE_TARGETTYPE_UNDEFINED
        ),
    // src line 1 - LINE IN
    MXSLE(MXLINEID(LINE_OUT,LINE_IN), 0, 1,
        MIXERLINE_LINEF_ACTIVE | MIXERLINE_LINEF_SOURCE, // flags
        MIXERLINE_COMPONENTTYPE_SRC_LINE,
        2,2,
        "Line In","Line In",
        MIXERLINE_TARGETTYPE_UNDEFINED
        ),
    // src line 2 - Microphone
    MXSLE(MXLINEID(LINE_OUT,MIC), 0, 2,
        MIXERLINE_LINEF_ACTIVE | MIXERLINE_LINEF_SOURCE, // flags
        MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE,
        1,3,
        "Mic","Microphone",
        MIXERLINE_TARGETTYPE_WAVEIN
        ),
    // src line 3 - Aux
    MXSLE(MXLINEID(LINE_OUT,AUX), 0, 3,
        MIXERLINE_LINEF_ACTIVE | MIXERLINE_LINEF_SOURCE, // flags
        MIXERLINE_COMPONENTTYPE_SRC_ANALOG,
        2,2,
        "Aux","Aux Volume",
        MIXERLINE_TARGETTYPE_UNDEFINED
        ),
    // src line 4 - Aux
    MXSLE(MXLINEID(LINE_OUT,PCM_OUT), 0, 4,
        MIXERLINE_LINEF_ACTIVE | MIXERLINE_LINEF_SOURCE, // flags
        MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT,
        2,2,
        "Digital","Digital Volume",
        MIXERLINE_TARGETTYPE_UNDEFINED
        ),


    // ----------------------
    // PCM_IN Sources Lines
    // ----------------------

    // src line 0 - CD
    MXSLE(MXLINEID(PCM_IN, CD), 1, 0,
        MIXERLINE_LINEF_ACTIVE | MIXERLINE_LINEF_SOURCE, // flags
        MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC,
        2,1,
        "CD Audio","CD Audio",
        MIXERLINE_TARGETTYPE_UNDEFINED
        ),
    // src line 1 - LINE IN
    MXSLE(MXLINEID(PCM_IN, LINE_IN), 1, 1,
        MIXERLINE_LINEF_ACTIVE | MIXERLINE_LINEF_SOURCE, // flags
        MIXERLINE_COMPONENTTYPE_SRC_LINE,
        2,1,
        "Line In","Line In",
        MIXERLINE_TARGETTYPE_UNDEFINED
        ),
    // src line 2 - Microphone
    MXSLE(MXLINEID(PCM_IN, MIC), 1, 2,
        MIXERLINE_LINEF_ACTIVE | MIXERLINE_LINEF_SOURCE, // flags
        MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE,
        2,2,
        "Microphone","Microphone",
        MIXERLINE_TARGETTYPE_WAVEIN
        ),
    // src line 3 - Aux
    MXSLE(MXLINEID(PCM_IN, AUX), 1, 3,
        MIXERLINE_LINEF_ACTIVE | MIXERLINE_LINEF_SOURCE, // flags
        MIXERLINE_COMPONENTTYPE_SRC_ANALOG,
        2,1,

⌨️ 快捷键说明

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