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

📄 prophnd.cpp

📁 AC97 Sample Driver and Related Code Samples. This directory contains a sample AC97 adapter driver a
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            // impossible. If you would store the volume like sndvol gives it
            // to you and you return it on a get, then the balance slider
            // moves and stays at the position the user wanted it. However,
            // if you return the actual volume the balance slider will jump
            // back to the position that the HW can do (play with it to see
            // how it works).
            //
            if (lLevel > lMaximum) lLevel = lMaximum;
            if (lLevel < lMinimum) lLevel = lMinimum;
            
            // First update the node cache.
            if ((channel == CHAN_LEFT) || (channel == CHAN_MASTER))
            {
                that->stNodeCache[NodeDef].bLeftValid = -1;
                that->stNodeCache[NodeDef].lLeft = lLevel;
            }
            if ((channel == CHAN_RIGHT) || (channel == CHAN_MASTER))
            {
                that->stNodeCache[NodeDef].bRightValid = -1;
                that->stNodeCache[NodeDef].lRight = lLevel;
            }
            
            //
            // If we have a master mono, then we have to program the speaker
            // volumes a little different.
            // Check for master mono (surround or headphone present) and
            // if one of the speaker volumes is requested.
            //
            if ((that->AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT) ||
                 that->AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT)) &&
                ((NodeDef == NODE_VIRT_MASTERMONO_VOLUME) || (NodeDef == NODE_LFE_VOLUME) ||
                 (NodeDef == NODE_CENTER_VOLUME) || (NodeDef == NODE_FRONT_VOLUME) ||
                 (NodeDef == NODE_SURROUND_VOLUME) || (NodeDef == NODE_HPOUT_VOLUME)))
            {
                //
                // For master mono we have to update all speaker volumes.
                //
                if (NodeDef == NODE_VIRT_MASTERMONO_VOLUME)
                {
                    // Update all speaker volumes.
                    ntStatus = SetMultichannelVolume (that, NODE_FRONT_VOLUME);
                    if (that->AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
                        ntStatus = SetMultichannelVolume (that, NODE_HPOUT_VOLUME);
                    if (that->AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT))
                        ntStatus = SetMultichannelVolume (that, NODE_SURROUND_VOLUME);
                    if (that->AdapterCommon->GetPinConfig (PINC_CENTER_LFE_PRESENT))
                    {
                        ntStatus = SetMultichannelVolume (that, NODE_CENTER_VOLUME);
                        ntStatus = SetMultichannelVolume (that, NODE_LFE_VOLUME);
                    }
                }
                else    // update the individual speaker volume only.
                {
                    ntStatus = SetMultichannelVolume (that, NodeDef);
                }
            }
            else    // This is for all other volumes (or no master mono present).
            {
                // calculate the dB.dB value.

                // The nodes are calculated differently.
                switch (NodeDef)
                {
                    // for record controls we calculate it 'reverse'.
                    case NODE_VIRT_MASTER_INPUT_VOLUME1:
                    case NODE_VIRT_MASTER_INPUT_VOLUME2:
                    case NODE_VIRT_MASTER_INPUT_VOLUME3:
                    case NODE_VIRT_MASTER_INPUT_VOLUME4:
                    case NODE_VIRT_MASTER_INPUT_VOLUME5:
                    case NODE_VIRT_MASTER_INPUT_VOLUME6:
                    case NODE_VIRT_MASTER_INPUT_VOLUME7:
                    case NODE_VIRT_MASTER_INPUT_VOLUME8:
                        // read the wavein selector.
                        ntStatus = that->AdapterCommon->ReadCodecRegister (
                                that->AdapterCommon->GetNodeReg (NODE_WAVEIN_SELECT),
                                &wRegister);
                        if (!NT_SUCCESS (ntStatus))
                            return ntStatus;
    
                        // mask out every unused bit.
                        wRegister &= (that->AdapterCommon->GetNodeMask (
                                NODE_WAVEIN_SELECT) & AC97REG_MASK_RIGHT);
    
                        // check if the volume that we change belongs to the active
                        // (selected) virtual channel.
                        // Tricky: If the virtual nodes are not defined consecutively
                        // this comparision will fail.
                        if ((NodeDef - NODE_VIRT_MASTER_INPUT_VOLUME1) != wRegister)
                            return ntStatus;
                        
                        // fall through for calculation.

                    case NODE_MICIN_VOLUME:
                        wRegister = (WORD)(((lLevel + uStep / 2) - lMinimum) / uStep);
                        break;

                    case NODE_VIRT_MONOOUT_VOLUME1:
                    case NODE_VIRT_MONOOUT_VOLUME2:
                        // read the monoout selector.
                        ntStatus = that->AdapterCommon->ReadCodecRegister (
                                that->AdapterCommon->GetNodeReg (NODE_MONOOUT_SELECT),
                                &wRegister);
                        if (!NT_SUCCESS (ntStatus))
                            return ntStatus;
    
                        // mask out every unused bit.
                        wRegister &= that->AdapterCommon->GetNodeMask (NODE_MONOOUT_SELECT);
    
                        // check if the volume that we change belongs to the active
                        // (selected) virtual channel.
                        // Note: Monout select is set if we want to prg. MIC (Volume2).
                        if ((!wRegister && (NodeDef == NODE_VIRT_MONOOUT_VOLUME2)) ||
                            (wRegister && (NodeDef == NODE_VIRT_MONOOUT_VOLUME1)))
                            return ntStatus;
                    
                        // fall through for calculation.
                    default:
                        wRegister = (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep);
                        break;
                }

                // Oops - NODE_PCBEEP_VOLUME doesn't use bit0. We have to adjust.
                if (NodeDef == NODE_PCBEEP_VOLUME)
                    wRegister <<= 1;
    
                // write the stuff (with mask!).
                // Note: mono channels are 'master' here (see fake above).
                // this makes sure that left and right channel is prg. for the virt.
                // controls. On controls that only have the right channel, the left
                // channel programming does nothing cause the mask will be zero.
                if ((channel == CHAN_LEFT) || (channel == CHAN_MASTER))
                {
                    // write only left.
                    ntStatus = that->AdapterCommon->WriteCodecRegister (
                        that->AdapterCommon->GetNodeReg (NodeDef),
                        wRegister << 8,
                        that->AdapterCommon->GetNodeMask (NodeDef) & AC97REG_MASK_LEFT);
                    // immediately return on error
                    if (!NT_SUCCESS (ntStatus))
                        return ntStatus;
                }
    
                if ((channel == CHAN_RIGHT) || (channel == CHAN_MASTER))
                {
                    // write only right.
                    ntStatus = that->AdapterCommon->WriteCodecRegister (
                        that->AdapterCommon->GetNodeReg (NodeDef),
                        wRegister,
                        that->AdapterCommon->GetNodeMask (NodeDef) & AC97REG_MASK_RIGHT);
                    // immediately return on error
                    if (!NT_SUCCESS (ntStatus))
                        return ntStatus;
                }

                // For the virtual controls, which are in front of a muxer, there
                // is no mute control displayed. But we have a HW mute control, so
                // what we do is enabling this mute when the user moves the slider
                // down to the bottom and disabling it on every other position.
                // We do this only for the "mono muxer", the recording mutes will
                // never be muted.
                // Tricky: Master input virtual controls must be defined consecutively.
                if ((NodeDef >= NODE_VIRT_MASTER_INPUT_VOLUME1) &&
                    (NodeDef <= NODE_VIRT_MASTER_INPUT_VOLUME8))
                {
                    // disable the mute; this only works because the mute and volume
                    // share the same register.
                    ntStatus = that->AdapterCommon->WriteCodecRegister (
                        that->AdapterCommon->GetNodeReg (NodeDef),
                        0, AC97REG_MASK_MUTE);
    
                    // Just in case.
                    that->UpdateRecordMute ();
                }

                if ((NodeDef == NODE_VIRT_MONOOUT_VOLUME1) ||
                    (NodeDef == NODE_VIRT_MONOOUT_VOLUME2))
                {
                    // these are only mono controls so checking one entry is enough.
                    if ( that->stNodeCache[NodeDef].bLeftValid &&
                        (that->stNodeCache[NodeDef].lLeft <= lMinimum))
                    {
                        // set the mute; this only works because the mute and volume
                        // share the same register.
                        ntStatus = that->AdapterCommon->WriteCodecRegister (
                            that->AdapterCommon->GetNodeReg (NodeDef),
                            AC97REG_MASK_MUTE, AC97REG_MASK_MUTE);
                    }
                    else
                    {
                        // clear the mute; this only works because the mute and volume
                        // share the same register.
                        ntStatus = that->AdapterCommon->WriteCodecRegister (
                            that->AdapterCommon->GetNodeReg (NodeDef),
                            0, AC97REG_MASK_MUTE);
                    }
                }
            }
            
            DOUT (DBG_PROPERTY, ("SET: %s(%s) -> 0x%x", NodeStrings[NodeDef],
                    channel==CHAN_LEFT ? "L" : channel==CHAN_RIGHT ? "R" : "M",
                    *Level));
            
            // ntStatus was set with the read call! whatever this is, return it.
        }
    }
    else
    {
        if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
        {
            ntStatus = BasicSupportHandler (PropertyRequest);
        }
    }

    return ntStatus;
}

/*****************************************************************************
 * CMiniportTopologyICH::PropertyHandler_Tone
 *****************************************************************************
 * Accesses a KSAUDIO_TONE property.
 * This function (property handler) is called by portcls every time there is a
 * get, set or basic support request for the node. The connection between the
 * node type and the property handler is made in the automation table which is
 * referenced when you register the node.
 * We use this property handler for all tone controls displayed at the advanced
 * property dialog in sndvol32 and the 3D controls displayed and exposed as
 * normal volume controls.
 */
NTSTATUS CMiniportTopologyICH::PropertyHandler_Tone
(
    IN      PPCPROPERTY_REQUEST   PropertyRequest
)
{
    PAGED_CODE ();

    ASSERT (PropertyRequest);

    DOUT (DBG_PRINT, ("[CMiniportTopologyICH::PropertyHandler_Tone]"));

    NTSTATUS        ntStatus = STATUS_INVALID_PARAMETER;
    TopoNodes       NodeDef;
    LONG            lMinimum, lMaximum;
    ULONG           uStep;
     // The major target is the object pointer to the topology miniport.
   CMiniportTopologyICH *that =
        (CMiniportTopologyICH *) PropertyRequest->MajorTarget;

    ASSERT (that);

    // validate node
    if (PropertyRequest->Node == (ULONG)-1)
        return ntStatus;

    // do the appropriate action for the request.

    // we should do a get or a set?
    if ((PropertyRequest->Verb & KSPROPERTY_TYPE_GET) ||
        (PropertyRequest->Verb & KSPROPERTY_TYPE_SET))
    {
        // validate parameters
        if ((PropertyRequest->InstanceSize < sizeof(LONG)) ||
            (PropertyRequest->ValueSize < sizeof(LONG)))
            return ntStatus;

        // get the buffer
        PLONG Level = (PLONG)PropertyRequest->Value;

        // Switch on the node id. This is just for parameter checking.
        // If something goes wrong, we will immideately return with
        // ntStatus, which is STATUS_INVALID_PARAMETER.
        switch(NodeDef = that->TransNodeNrToNodeDef (PropertyRequest->Node))
        {
            case NODE_BASS:
                // check type.
                if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_BASS)
                    return ntStatus;
                break;

            case NODE_TREBLE:
                // check type.
                if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_TREBLE)
                    return ntStatus;
                break;

            case NODE_VIRT_3D_CENTER:
            case NODE_VIRT_3D_DEPTH:
                // check 3D control
                if (!that->AdapterCommon->GetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE)
                    && (NodeDef == NODE_VIRT_3D_CENTER))
                    return ntStatus;
                if (!that->AdapterCommon->GetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE)
                    && (NodeDef == NODE_VIRT_3D_DEPTH))
                    return ntStatus;
                // check type
                if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_VOLUMELEVEL)
                    return ntStatus;
                // check channel
                if (*(PLONG(PropertyRequest->Instance)) == CHAN_RIGHT)
                    return ntStatus;
                break;
            
            case NODE_INVALID:
            default:
                // Ooops
                DOUT (DBG_ERROR, ("PropertyHandler_Tone: Invalid node requested."));
                return ntStatus;
        }

        // Now, do some action!

⌨️ 快捷键说明

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