📄 miniport.cpp
字号:
_DbgPrintF(DEBUGLVL_VERBOSE,("CMiniportMidiFM::MiniportMidiFMResume"));
KeAcquireSpinLock(&m_SpinLock,&oldIrql);
// We never touch these--set them to the default value anyway.
// AD_LSI
SoundMidiSendFM(m_PortBase, AD_LSI, m_SavedRegValues[AD_LSI]);
// AD_LSI2
SoundMidiSendFM(m_PortBase, AD_LSI2, m_SavedRegValues[AD_LSI2]);
// AD_TIMER1
SoundMidiSendFM(m_PortBase, AD_TIMER1, m_SavedRegValues[AD_TIMER1]);
// AD_TIMER2
SoundMidiSendFM(m_PortBase, AD_TIMER2, m_SavedRegValues[AD_TIMER2]);
// AD_MASK
SoundMidiSendFM(m_PortBase, AD_MASK, m_SavedRegValues[AD_MASK]);
// AD_CONNECTION
SoundMidiSendFM(m_PortBase, AD_CONNECTION, m_SavedRegValues[AD_CONNECTION]);
// AD_NEW
SoundMidiSendFM(m_PortBase, AD_NEW, m_SavedRegValues[AD_NEW]);
// AD_NTS
SoundMidiSendFM(m_PortBase, AD_NTS, m_SavedRegValues[AD_NTS]);
// AD_DRUM
SoundMidiSendFM(m_PortBase, AD_DRUM, m_SavedRegValues[AD_DRUM]);
for (i = 0; i <= 0x15; i++)
{
if ((i & 0x07) <= 0x05)
{
// AD_MULT
// AD_MULT2
SoundMidiSendFM(m_PortBase, AD_MULT + i, m_SavedRegValues[AD_MULT + i]);
SoundMidiSendFM(m_PortBase, AD_MULT2 + i, m_SavedRegValues[AD_MULT2 + i]);
// AD_LEVEL
// AD_LEVEL2
// turn off all the oscillators
SoundMidiSendFM(m_PortBase, AD_LEVEL + i, m_SavedRegValues[AD_LEVEL + i]);
SoundMidiSendFM(m_PortBase, AD_LEVEL2 + i, m_SavedRegValues[AD_LEVEL2 + i]);
// AD_AD
// AD_AD2
SoundMidiSendFM(m_PortBase, AD_AD + i, m_SavedRegValues[AD_AD + i]);
SoundMidiSendFM(m_PortBase, AD_AD2 + i, m_SavedRegValues[AD_AD2 + i]);
// AD_SR
// AD_SR2
SoundMidiSendFM(m_PortBase, AD_SR + i, m_SavedRegValues[AD_SR + i]);
SoundMidiSendFM(m_PortBase, AD_SR2 + i, m_SavedRegValues[AD_SR2 + i]);
// AD_WAVE
// AD_WAVE2
SoundMidiSendFM(m_PortBase, AD_WAVE + i, m_SavedRegValues[AD_WAVE + i]);
SoundMidiSendFM(m_PortBase, AD_WAVE2 + i, m_SavedRegValues[AD_WAVE2 + i]);
}
}
for (i = 0; i <= 0x08; i++)
{
// AD_FNUMBER
// AD_FNUMBER2
SoundMidiSendFM(m_PortBase, AD_FNUMBER + i, m_SavedRegValues[AD_FNUMBER + i]);
SoundMidiSendFM(m_PortBase, AD_FNUMBER2 + i, m_SavedRegValues[AD_FNUMBER2 + i]);
// AD_FEEDBACK
// AD_FEEDBACK2
SoundMidiSendFM(m_PortBase, AD_FEEDBACK + i, m_SavedRegValues[AD_FEEDBACK + i]);
SoundMidiSendFM(m_PortBase, AD_FEEDBACK2 + i, m_SavedRegValues[AD_FEEDBACK2 + i]);
// AD_BLOCK
// AD_BLOCK2
SoundMidiSendFM(m_PortBase, AD_BLOCK + i, m_SavedRegValues[AD_BLOCK + i]);
SoundMidiSendFM(m_PortBase, AD_BLOCK2 + i, m_SavedRegValues[AD_BLOCK2 + i]);
}
KeReleaseSpinLock(&m_SpinLock,oldIrql);
_DbgPrintF(DEBUGLVL_VERBOSE,("Done with CMiniportMidiFM::MiniportMidiFMResume"));
}
#pragma code_seg()
void
CMiniportMidiFM::
Opl3_BoardReset()
{
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
BYTE i;
_DbgPrintF(DEBUGLVL_VERBOSE,("CMiniportMidiFM::Opl3_BoardReset"));
/* ---- silence the chip -------- */
/* tell the FM chip to use 4-operator mode, and
fill in any other random variables */
SoundMidiSendFM(m_PortBase, AD_NEW, 0x01);
SoundMidiSendFM(m_PortBase, AD_MASK, 0x60);
SoundMidiSendFM(m_PortBase, AD_CONNECTION, 0x00);
SoundMidiSendFM(m_PortBase, AD_NTS, 0x00);
/* turn off the drums, and use high vibrato/modulation */
SoundMidiSendFM(m_PortBase, AD_DRUM, 0xc0);
/* turn off all the oscillators */
for (i = 0; i <= 0x15; i++)
{
if ((i & 0x07) <= 0x05)
{
SoundMidiSendFM(m_PortBase, AD_LEVEL + i, 0x3f);
SoundMidiSendFM(m_PortBase, AD_LEVEL2 + i, 0x3f);
}
};
/* turn off all the voices */
for (i = 0; i <= 0x08; i++)
{
SoundMidiSendFM(m_PortBase, AD_BLOCK + i, 0x00);
SoundMidiSendFM(m_PortBase, AD_BLOCK2 + i, 0x00);
};
}
// ==============================================================================
// PinDataRangesStream
// Structures indicating range of valid format values for streaming pins.
// ==============================================================================
static
KSDATARANGE_MUSIC PinDataRangesStream[] =
{
{
{
sizeof(KSDATARANGE_MUSIC),
0,
0,
0,
STATICGUIDOF(KSDATAFORMAT_TYPE_MUSIC),
STATICGUIDOF(KSDATAFORMAT_SUBTYPE_MIDI),
STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE)
},
STATICGUIDOF(KSMUSIC_TECHNOLOGY_FMSYNTH),
NUM2VOICES,
NUM2VOICES,
0xffffffff
}
};
// ==============================================================================
// PinDataRangePointersStream
// List of pointers to structures indicating range of valid format values
// for streaming pins.
// ==============================================================================
static
PKSDATARANGE PinDataRangePointersStream[] =
{
PKSDATARANGE(&PinDataRangesStream[0])
};
// ==============================================================================
// PinDataRangesBridge
// Structures indicating range of valid format values for bridge pins.
// ==============================================================================
static
KSDATARANGE PinDataRangesBridge[] =
{
{
sizeof(KSDATARANGE),
0,
0,
0,
STATICGUIDOF(KSDATAFORMAT_TYPE_MUSIC),
STATICGUIDOF(KSDATAFORMAT_SUBTYPE_MIDI_BUS),
STATICGUIDOF(KSDATAFORMAT_SPECIFIER_NONE)
}
};
// ==============================================================================
// PinDataRangePointersBridge
// List of pointers to structures indicating range of valid format values
// for bridge pins.
// ==============================================================================
static
PKSDATARANGE PinDataRangePointersBridge[] =
{
&PinDataRangesBridge[0]
};
// ==============================================================================
// MiniportPins
// List of pins.
// ==============================================================================
static
PCPIN_DESCRIPTOR MiniportPins[] =
{
{
1,1,1, // InstanceCount
NULL, // AutomationTable
{ // KsPinDescriptor
0, // InterfacesCount
NULL, // Interfaces
0, // MediumsCount
NULL, // Mediums
SIZEOF_ARRAY(PinDataRangePointersStream), // DataRangesCount
PinDataRangePointersStream, // DataRanges
KSPIN_DATAFLOW_IN, // DataFlow
KSPIN_COMMUNICATION_SINK, // Communication
(GUID *) &KSCATEGORY_SYNTHESIZER, // Category
NULL, // Name
0 // Reserved
}
},
{
0,0,0, // InstanceCount
NULL, // AutomationTable
{ // KsPinDescriptor
0, // InterfacesCount
NULL, // Interfaces
0, // MediumsCount
NULL, // Mediums
SIZEOF_ARRAY(PinDataRangePointersBridge), // DataRangesCount
PinDataRangePointersBridge, // DataRanges
KSPIN_DATAFLOW_OUT, // DataFlow
KSPIN_COMMUNICATION_NONE, // Communication
(GUID *) &KSCATEGORY_AUDIO, // Category
NULL, // Name
0 // Reserved
}
}
};
/*****************************************************************************
* PropertiesVolume
*****************************************************************************
* Properties for volume controls.
*/
static
PCPROPERTY_ITEM PropertiesVolume[] =
{
{
&KSPROPSETID_Audio,
KSPROPERTY_AUDIO_VOLUMELEVEL,
KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT,
PropertyHandler_Level
},
{
&KSPROPSETID_Audio,
KSPROPERTY_AUDIO_CPU_RESOURCES,
KSPROPERTY_TYPE_GET,
PropertyHandler_CpuResources
}
};
/*****************************************************************************
* AutomationVolume
*****************************************************************************
* Automation table for volume controls.
*/
DEFINE_PCAUTOMATION_TABLE_PROP(AutomationVolume,PropertiesVolume);
// ==============================================================================
// MiniportNodes
// List of nodes.
// ==============================================================================
static
PCNODE_DESCRIPTOR MiniportNodes[] =
{
{
// synth node, #0
0, // Flags
NULL, // AutomationTable
&KSNODETYPE_SYNTHESIZER,// Type
NULL // Name TODO: fill in with correct GUID
},
{
// volume node, #1
0, // Flags
&AutomationVolume, // AutomationTable
&KSNODETYPE_VOLUME, // Type
NULL // Name TODO: fill in with correct GUID
}
};
// ==============================================================================
// MiniportConnections
// List of connections.
// ==============================================================================
/*****************************************************************************
* Table of topology unit connections.
*
* Pin numbering is technically arbitrary, but the convention established here
* is to number a solitary output pin 0 (looks like an 'o') and a solitary
* input pin 1 (looks like an 'i'). Even destinations, which have no output,
* have an input pin numbered 1 and no pin 0.
*
* Nodes are more likely to have multiple ins than multiple outs, so the more
* general rule would be that inputs are numbered >=1. If a node has multiple
* outs, none of these conventions apply.
*
* Nodes have at most one control value. Mixers are therefore simple summing
* nodes with no per-pin levels. Rather than assigning a unique pin to each
* input to a mixer, all inputs are connected to pin 1. This is acceptable
* because there is no functional distinction between the inputs.
*
* There are no multiplexers in this topology, so there is no opportunity to
* give an example of a multiplexer. A multiplexer should have a single
* output pin (0) and multiple input pins (1..n). Its control value is an
* integer in the range 1..n indicating which input is connected to the
* output.
*
* In the case of connections to pins, as opposed to connections to nodes, the
* node is identified as PCFILTER_NODE and the pin number identifies the
* particular filter pin.
*****************************************************************************
*/
enum {
eFMSynthNode = 0,
eFMVolumeNode
};
enum {
eFMNodeOutput = 0,
eFMNodeInput = 1
};
enum {
eFilterInput = eFMNodeOutput,
eBridgeOutput = eFMNodeInput
};
static
PCCONNECTION_DESCRIPTOR MiniportConnections[] =
{
// FromNode, FromPin, ToNode, ToPin
{ PCFILTER_NODE, eFilterInput, eFMSynthNode, eFMNodeInput }, // Stream in to synth.
{ eFMSynthNode, eFMNodeOutput, PCFILTER_NODE, eBridgeOutput } // Synth to bridge out.
};
// different connection struct for volume version
static
PCCONNECTION_DESCRIPTOR MiniportWithVolConnections[] =
{
// FromNode, FromPin, ToNode, ToPin
{ PCFILTER_NODE, eFilterInput, eFMSynthNode, eFMNodeInput }, // Stream in to synth.
{ eFMSynthNode, eFMNodeOutput, eFMVolumeNode, eFMNodeInput }, // Synth to volume.
{ eFMVolumeNode, eFMNodeOutput, PCFILTER_NODE, eBridgeOutput } // volume to bridge out.
};
////////////////////////////////////////////////////////////////////////////////
// MiniportCategories
//
// List of categories.
static
GUID MiniportCategories[] =
{
STATICGUIDOF(KSCATEGORY_AUDIO),
STATICGUIDOF(KSCATEGORY_RENDER),
STATICGUIDOF(KSCATEGORY_SYNTHESIZER)
};
// ==============================================================================
// MiniportDescription
// Complete description of the miniport.
// ==============================================================================
static
PCFILTER_DESCRIPTOR MiniportFilterDescriptor =
{
0, // Version
NULL, // AutomationTable
sizeof(PCPIN_DESCRIPTOR), // PinSize
SIZEOF_ARRAY(MiniportPins), // PinCount
MiniportPins, // Pins
sizeof(PCNODE_DESCRIPTOR), // NodeSize
1, // NodeCount - no volume node
MiniportNodes, // Nodes
SIZEOF_ARRAY(MiniportConnections), // ConnectionCount
MiniportConnections, // Connections
SIZEOF_ARRAY(MiniportCategories), // CategoryCount
MiniportCategories // Categories
};
static
PCFILTER_DESCRIPTOR MiniportFilterWithVolDescriptor =
{
0, // Version
NULL, // AutomationTable
sizeof(PCPIN_DESCRIPTOR), // PinSize
SIZEOF_ARRAY(MiniportPins), // PinCount
MiniportPins, // Pins
sizeof(PCNODE_DESCRIPTOR), // NodeSize
2, // NodeCount - extra volume node
MiniportNodes, // Nodes
SIZEOF_ARRAY(MiniportWithVolConnections), // ConnectionCount
MiniportWithVolConnections, // Connections
0, // CategoryCount
NULL // Categories
};
#pragma code_seg("PAGE")
// ==============================================================================
// CMiniportMidiFM::GetDescription()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -