ReactOS 0.4.16-dev-109-gf4cb10f
CAC97MiniportTopology Class Reference

#include <mintopo.h>

Inheritance diagram for CAC97MiniportTopology:
Collaboration diagram for CAC97MiniportTopology:

Public Member Functions

 DECLARE_STD_UNKNOWN ()
 
 DEFINE_STD_CONSTRUCTOR (CAC97MiniportTopology)
 
 ~CAC97MiniportTopology ()
 
 STDMETHODIMP_ (NTSTATUS) GetPhysicalConnectionPins(OUT PULONG WaveOutSource
 
 STDMETHODIMP_ (void) SetCopyProtectFlag(BOOL flag)
 

Static Public Member Functions

static NTSTATUS GetDBValues (IN PADAPTERCOMMON, IN TopoNodes Node, OUT LONG *plMinimum, OUT LONG *plMaximum, OUT ULONG *puStep)
 
static NTSTATUS SetMultichannelMute (IN CAC97MiniportTopology *that, IN TopoNodes Mute)
 
static NTSTATUS SetMultichannelVolume (IN CAC97MiniportTopology *that, IN TopoNodes Volume)
 
static NTSTATUS NTAPI PropertyHandler_OnOff (IN PPCPROPERTY_REQUEST PropertyRequest)
 
static NTSTATUS BasicSupportHandler (IN PPCPROPERTY_REQUEST PropertyRequest)
 
static NTSTATUS NTAPI PropertyHandler_Level (IN PPCPROPERTY_REQUEST PropertyRequest)
 
static NTSTATUS NTAPI PropertyHandler_Tone (IN PPCPROPERTY_REQUEST PropertyRequest)
 
static NTSTATUS NTAPI PropertyHandler_Ulong (IN PPCPROPERTY_REQUEST PropertyRequest)
 
static NTSTATUS NTAPI PropertyHandler_CpuResources (IN PPCPROPERTY_REQUEST PropertyRequest)
 

Public Attributes

 IMP_IMiniportTopology
 
OUT PULONG WaveInDest
 
OUT PULONG OUT PULONG MicInDest
 
- Public Attributes inherited from CUnknown
union {
   IUnknown   IUnknown
 
   INonDelegatingUnknown   INonDelegatingUnknown
 
}; 
 
LONG m_ref_count
 
PUNKNOWN m_outer_unknown
 

Private Member Functions

NTSTATUS BuildTopology (void)
 
NTSTATUS BuildPinDescriptors (void)
 
NTSTATUS BuildNodeDescriptors (void)
 
NTSTATUS BuildConnectionDescriptors (void)
 
TopoNodes TransNodeNrToNodeDef (IN int Node)
 
int TransNodeDefToNodeNr (IN TopoNodes Node)
 
TopoPins TransPinNrToPinDef (IN int Pin)
 
int TransPinDefToPinNr (IN TopoPins Pin)
 
void SetNodeTranslation (IN int NodeNr, IN TopoNodes NodeDef)
 
void SetPinTranslation (IN int PinNr, IN TopoPins PinDef)
 
void UpdateRecordMute (void)
 

Private Attributes

PADAPTERCOMMON AdapterCommon
 
PPCFILTER_DESCRIPTOR FilterDescriptor
 
PPCPIN_DESCRIPTOR PinDescriptors
 
PPCNODE_DESCRIPTOR NodeDescriptors
 
PPCCONNECTION_DESCRIPTOR ConnectionDescriptors
 
tPinTranslationTable stPinTrans [PIN_TOP_ELEMENT]
 
tNodeTranslationTable stNodeTrans [NODE_TOP_ELEMENT]
 
tNodeCache stNodeCache [NODE_TOP_ELEMENT]
 
BOOL m_bCopyProtectFlag
 

Detailed Description

Definition at line 94 of file mintopo.h.

Constructor & Destructor Documentation

◆ ~CAC97MiniportTopology()

CAC97MiniportTopology::~CAC97MiniportTopology ( )

Definition at line 356 of file mintopo.cpp.

357{
358 PAGED_CODE ();
359
360 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::~CAC97MiniportTopology]"));
361
362 // release all the stuff that we had referenced or allocated.
363 if (AdapterCommon)
364 {
365 // Notify the AdapterCommon that we go away.
366 AdapterCommon->SetMiniportTopology (NULL);
367 AdapterCommon->Release ();
369 }
370
372 {
375 }
376
378 {
381 }
382
383 if (NodeDescriptors)
384 {
387 }
388
389 if (PinDescriptors)
390 {
393 }
394}
#define PAGED_CODE()
PPCNODE_DESCRIPTOR NodeDescriptors
Definition: mintopo.h:101
PPCFILTER_DESCRIPTOR FilterDescriptor
Definition: mintopo.h:99
PPCPIN_DESCRIPTOR PinDescriptors
Definition: mintopo.h:100
PADAPTERCOMMON AdapterCommon
Definition: mintopo.h:98
PPCCONNECTION_DESCRIPTOR ConnectionDescriptors
Definition: mintopo.h:102
#define NULL
Definition: types.h:112
#define DOUT(lvl, strings)
Definition: debug.h:82
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ _Strict_type_match_ POOL_TYPE _In_opt_ ULONG PoolTag
Definition: wdfmemory.h:164
#define DBG_PRINT(ppi, ch, level)
Definition: win32kdebug.h:169

Member Function Documentation

◆ BasicSupportHandler()

NTSTATUS CAC97MiniportTopology::BasicSupportHandler ( IN PPCPROPERTY_REQUEST  PropertyRequest)
static

Definition at line 579 of file prophnd.cpp.

583{
584 PAGED_CODE ();
585
586 ASSERT (PropertyRequest);
587
588 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::BasicSupportHandler]"));
589
591 // The major target is the object pointer to the topology miniport.
593 (CAC97MiniportTopology *) PropertyRequest->MajorTarget;
594
595 ASSERT (that);
596
597
598 // if there is enough space for a KSPROPERTY_DESCRIPTION information
599 if (PropertyRequest->ValueSize >= (sizeof(KSPROPERTY_DESCRIPTION)))
600 {
601 // we return a KSPROPERTY_DESCRIPTION structure.
602 PKSPROPERTY_DESCRIPTION PropDesc = (PKSPROPERTY_DESCRIPTION)PropertyRequest->Value;
603
607 PropDesc->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION) +
611 PropDesc->PropTypeSet.Id = VT_I4;
612 PropDesc->PropTypeSet.Flags = 0;
613 PropDesc->MembersListCount = 1;
614 PropDesc->Reserved = 0;
615
616 // if return buffer can also hold a range description, return it too
617 if (PropertyRequest->ValueSize >= (sizeof(KSPROPERTY_DESCRIPTION) +
619 {
620 // fill in the members header
622
624 Members->MembersSize = sizeof(KSPROPERTY_STEPPING_LONG);
625 Members->MembersCount = 1;
626 Members->Flags = 0;
627
628 // fill in the stepped range
630
631 ntStatus = GetDBValues (that->AdapterCommon,
632 that->TransNodeNrToNodeDef (PropertyRequest->Node),
633 &Range->Bounds.SignedMinimum,
634 &Range->Bounds.SignedMaximum,
635 &Range->SteppingDelta);
636
637 Range->Reserved = 0;
638
639 // set the return value size
640 PropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION) +
643
644 DOUT (DBG_PROPERTY, ("BASIC_SUPPORT: %s max=0x%x min=0x%x step=0x%x",
645 NodeStrings[that->TransNodeNrToNodeDef (PropertyRequest->Node)],
646 Range->Bounds.SignedMaximum, Range->Bounds.SignedMinimum,
647 Range->SteppingDelta));
648 } else
649 {
650 // we hadn't enough space for the range information;
651 // set the return value size
652 PropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION);
653 }
654
655 ntStatus = STATUS_SUCCESS;
656 }
657 else if (PropertyRequest->ValueSize >= sizeof(ULONG))
658 {
659 // if return buffer can hold a ULONG, return the access flags
660 PULONG AccessFlags = (PULONG)PropertyRequest->Value;
661
662 *AccessFlags = KSPROPERTY_TYPE_BASICSUPPORT |
665
666 // set the return value size
667 PropertyRequest->ValueSize = sizeof(ULONG);
668 ntStatus = STATUS_SUCCESS;
669 }
670
671 // In case there was not even enough space for a ULONG in the return buffer,
672 // we fail this request with STATUS_INVALID_DEVICE_REQUEST.
673 // Any other case will return STATUS_SUCCESS.
674 return ntStatus;
675}
LONG NTSTATUS
Definition: precomp.h:26
static NTSTATUS GetDBValues(IN PADAPTERCOMMON, IN TopoNodes Node, OUT LONG *plMinimum, OUT LONG *plMaximum, OUT ULONG *puStep)
Definition: prophnd.cpp:156
TopoNodes TransNodeNrToNodeDef(IN int Node)
Definition: mintopo.h:135
@ VT_I4
Definition: compat.h:2298
const int DBG_PROPERTY
Definition: debug.h:29
#define KSPROPERTY_TYPE_SET
Definition: dmksctrl.h:43
#define KSPROPERTY_TYPE_BASICSUPPORT
Definition: dmksctrl.h:45
#define KSPROPERTY_TYPE_GET
Definition: dmksctrl.h:42
#define KSPROPERTY_MEMBER_STEPPEDRANGES
Definition: ks.h:1559
#define KSPROPTYPESETID_General
Definition: ks.h:858
struct KSPROPERTY_STEPPING_LONG * PKSPROPERTY_STEPPING_LONG
struct KSPROPERTY_DESCRIPTION * PKSPROPERTY_DESCRIPTION
struct KSPROPERTY_MEMBERSHEADER * PKSPROPERTY_MEMBERSHEADER
#define ASSERT(a)
Definition: mode.c:44
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
ULONG Id
Definition: dmksctrl.h:77
ULONG Flags
Definition: dmksctrl.h:78
GUID Set
Definition: dmksctrl.h:76
ULONG DescriptionSize
Definition: ks.h:1540
KSIDENTIFIER PropTypeSet
Definition: ks.h:1541
ULONG MembersListCount
Definition: ks.h:1542
Definition: range.c:39
uint32_t * PULONG
Definition: typedefs.h:59
uint32_t ULONG
Definition: typedefs.h:59

Referenced by PropertyHandler_Level(), and PropertyHandler_Tone().

◆ BuildConnectionDescriptors()

NTSTATUS CAC97MiniportTopology::BuildConnectionDescriptors ( void  )
private

Definition at line 1580 of file mintopo.cpp.

1581{
1582// Improvement would be to not use a Macro, use (inline) function instead.
1583
1584// for node to node connections
1585#define INIT_NN_CONN( cptr, fnode, fpin, tnode, tpin ) \
1586 cptr->FromNode = TransNodeDefToNodeNr (fnode); \
1587 cptr->FromNodePin = fpin; \
1588 cptr->ToNode = TransNodeDefToNodeNr (tnode); \
1589 cptr->ToNodePin = tpin; \
1590 cptr++,ConnectionCount++
1591
1592// for filter pin to node connections
1593#define INIT_FN_CONN( cptr, fpin, tnode, tpin ) \
1594 cptr->FromNode = KSFILTER_NODE; \
1595 cptr->FromNodePin = TransPinDefToPinNr (fpin); \
1596 cptr->ToNode = TransNodeDefToNodeNr (tnode); \
1597 cptr->ToNodePin = tpin; \
1598 cptr++,ConnectionCount++
1599
1600// for node to filter pin connections
1601#define INIT_NF_CONN( cptr, fnode, fpin, tpin ) \
1602 cptr->FromNode = TransNodeDefToNodeNr (fnode); \
1603 cptr->FromNodePin = fpin; \
1604 cptr->ToNode = KSFILTER_NODE; \
1605 cptr->ToNodePin = TransPinDefToPinNr (tpin); \
1606 cptr++,ConnectionCount++
1607
1608 PAGED_CODE ();
1609
1610 NTSTATUS ntStatus = STATUS_SUCCESS;
1611 ULONG ConnectionCount = 0;
1612
1613 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::BuildConnectionDescriptors]"));
1614
1615 // allocate our descriptor memory
1619 {
1621
1622 // build the wave out (coming in) path
1623
1624 // PIN_WAVEOUT_SOURCE -> NODE_WAVEOUT_VOLUME
1625 INIT_FN_CONN (CurrentConnection, PIN_WAVEOUT_SOURCE, NODE_WAVEOUT_VOLUME, 1);
1626
1627 // NODE_WAVEOUT_VOLUME -> NODE_WAVEOUT_MUTE
1628 INIT_NN_CONN (CurrentConnection, NODE_WAVEOUT_VOLUME, 0, NODE_WAVEOUT_MUTE, 1);
1629
1630 // NODE_WAVEOUT_MUTE -> NODE_MAIN_MIX
1631 INIT_NN_CONN (CurrentConnection, NODE_WAVEOUT_MUTE, 0, NODE_MAIN_MIX, 1);
1632
1633 // build the PC beeper path
1634 if (AdapterCommon->GetPinConfig (PINC_PCBEEP_PRESENT))
1635 {
1636 // PIN_PCBEEP_SOURCE -> NODE_PCBEEP_VOLUME
1637 INIT_FN_CONN (CurrentConnection, PIN_PCBEEP_SOURCE, NODE_PCBEEP_VOLUME, 1);
1638
1639 // NODE_PCBEEP_VOLUME -> NODE_PCBEEP_MUTE
1640 INIT_NN_CONN (CurrentConnection, NODE_PCBEEP_VOLUME, 0, NODE_PCBEEP_MUTE, 1);
1641
1642 // NODE_PCBEEP_MUTE -> NODE_BEEP_MIX
1643 INIT_NN_CONN (CurrentConnection, NODE_PCBEEP_MUTE, 0, NODE_BEEP_MIX, 2);
1644 }
1645
1646 // build the phone path
1647 if (AdapterCommon->GetPinConfig (PINC_PHONE_PRESENT))
1648 {
1649 // PIN_PHONE_SOURCE -> NODE_PHONE_VOLUME
1650 INIT_FN_CONN (CurrentConnection, PIN_PHONE_SOURCE, NODE_PHONE_VOLUME, 1);
1651
1652 // NODE_PHONE_VOLUME -> NODE_PHONE_MUTE
1653 INIT_NN_CONN (CurrentConnection, NODE_PHONE_VOLUME, 0, NODE_PHONE_MUTE, 1);
1654
1655 // NODE_PHONE_MUTE -> LINEOUT_BEEP_MIX
1656 INIT_NN_CONN (CurrentConnection, NODE_PHONE_MUTE, 0, NODE_BEEP_MIX, 3);
1657
1658 // PIN_PHONE_SOURCE pin -> NODE_VIRT_MASTER_INPUT_VOLUME8
1660
1661 // NODE_VIRT_MASTER_INPUT_VOLUME8 -> NODE_WAVEIN_SELECT
1663 }
1664
1665 // build MIC path
1666 if (AdapterCommon->GetPinConfig (PINC_MIC_PRESENT))
1667 {
1668 // build the MIC selector in case we have 2 MICs
1669 if (AdapterCommon->GetPinConfig (PINC_MIC2_PRESENT))
1670 {
1671 // PIN_MIC_SOURCE pin -> NODE_MIC_SELECT
1672 INIT_FN_CONN (CurrentConnection, PIN_MIC_SOURCE, NODE_MIC_SELECT, 1);
1673
1674 // NODE_MIC_SELECT -> NODE_MIC_BOOST
1675 INIT_NN_CONN (CurrentConnection, NODE_MIC_SELECT, 0, NODE_MIC_BOOST, 1);
1676 }
1677 else
1678 {
1679 // PIN_MIC_SOURCE pin -> NODE_MIC_SELECT
1680 INIT_FN_CONN (CurrentConnection, PIN_MIC_SOURCE, NODE_MIC_BOOST, 1);
1681 }
1682
1683 // NODE_MIC_BOOST -> NODE_MIC_VOLUME
1684 INIT_NN_CONN (CurrentConnection, NODE_MIC_BOOST, 0, NODE_MIC_VOLUME, 1);
1685
1686 // NODE_MIC_VOLUME -> NODE_MIC_MUTE
1687 INIT_NN_CONN (CurrentConnection, NODE_MIC_VOLUME, 0, NODE_MIC_MUTE, 1);
1688
1689 // NODE_MIC_MUTE -> NODE_MAIN_MIX
1690 INIT_NN_CONN (CurrentConnection, NODE_MIC_MUTE, 0, NODE_MAIN_MIX, 2);
1691
1692 // NODE_MIC_BOOST -> NODE_VIRT_MASTER_INPUT_VOLUME1
1694
1695 // NODE_VIRT_MASTER_INPUT_VOLUME1 -> NODE_WAVEIN_SELECT
1697 }
1698
1699 // build the line in path
1700 if (AdapterCommon->GetPinConfig (PINC_LINEIN_PRESENT))
1701 {
1702 // PIN_LINEIN_SOURCE -> NODE_LINEIN_VOLUME
1703 INIT_FN_CONN (CurrentConnection, PIN_LINEIN_SOURCE, NODE_LINEIN_VOLUME, 1);
1704
1705 // NODE_LINEIN_VOLUME -> NODE_LINEIN_MUTE
1706 INIT_NN_CONN (CurrentConnection, NODE_LINEIN_VOLUME, 0, NODE_LINEIN_MUTE, 1);
1707
1708 // NODE_LINEIN_MUTE -> NODE_MAIN_MIX
1709 INIT_NN_CONN (CurrentConnection, NODE_LINEIN_MUTE, 0, NODE_MAIN_MIX, 3);
1710
1711 // PIN_LINEIN_SOURCE pin -> NODE_VIRT_MASTER_INPUT_VOLUME5
1713
1714 // NODE_VIRT_MASTER_INPUT_VOLUME5 -> NODE_WAVEIN_SELECT
1716 }
1717
1718 // build the CD path
1719 if (AdapterCommon->GetPinConfig (PINC_CD_PRESENT))
1720 {
1721 // PIN_CD_SOURCE -> NODE_CD_VOLUME
1722 INIT_FN_CONN (CurrentConnection, PIN_CD_SOURCE, NODE_CD_VOLUME, 1);
1723
1724 // NODE_CD_VOLUME -> NODE_CD_MUTE
1725 INIT_NN_CONN (CurrentConnection, NODE_CD_VOLUME, 0, NODE_CD_MUTE, 1);
1726
1727 // NODE_CD_MUTE -> NODE_MAIN_MIX
1728 INIT_NN_CONN (CurrentConnection, NODE_CD_MUTE, 0, NODE_MAIN_MIX, 4);
1729
1730 // PIN_CD_SOURCE pin -> NODE_VIRT_MASTER_INPUT_VOLUME2
1732
1733 // NODE_VIRT_MASTER_INPUT_VOLUME2 -> NODE_WAVEIN_SELECT
1735 }
1736
1737 // build the video path
1738 if (AdapterCommon->GetPinConfig (PINC_VIDEO_PRESENT))
1739 {
1740 // PIN_VIDEO_SOURCE -> NODE_VIDEO_VOLUME
1741 INIT_FN_CONN (CurrentConnection, PIN_VIDEO_SOURCE, NODE_VIDEO_VOLUME, 1);
1742
1743 // NODE_VIDEO_VOLUME -> NODE_VIDEO_MUTE
1744 INIT_NN_CONN (CurrentConnection, NODE_VIDEO_VOLUME, 0, NODE_VIDEO_MUTE, 1);
1745
1746 // NODE_VIDEO_MUTE -> NODE_MAIN_MIX
1747 INIT_NN_CONN (CurrentConnection, NODE_VIDEO_MUTE, 0, NODE_MAIN_MIX, 5);
1748
1749 // PIN_VIDEO_SOURCE pin -> NODE_VIRT_MASTER_INPUT_VOLUME3
1751
1752 // NODE_VIRT_MASTER_INPUT_VOLUME3 -> NODE_WAVEIN_SELECT
1754 }
1755
1756 // build the AUX path
1757 if (AdapterCommon->GetPinConfig (PINC_AUX_PRESENT))
1758 {
1759 // PIN_AUX_SOURCE pin -> NODE_AUX_VOLUME
1760 INIT_FN_CONN (CurrentConnection, PIN_AUX_SOURCE, NODE_AUX_VOLUME, 1);
1761
1762 // NODE_AUX_VOLUME -> NODE_AUX_MUTE
1763 INIT_NN_CONN (CurrentConnection, NODE_AUX_VOLUME, 0, NODE_AUX_MUTE, 1);
1764
1765 // NODE_AUX_MUTE -> NODE_MAIN_MIX
1766 INIT_NN_CONN (CurrentConnection, NODE_AUX_MUTE, 0, NODE_MAIN_MIX, 6);
1767
1768 // PIN_AUX_SOURCE pin -> NODE_VIRT_MASTER_INPUT_VOLUME4
1770
1771 // NODE_VIRT_MASTER_INPUT_VOLUME4 -> NODE_WAVEIN_SELECT
1773 }
1774
1775 // and build the head phone output.
1776 // we connect the headphones like an input so that it's in the playback panel.
1777 if (AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
1778 {
1779 // from whatever -> NODE_HPOUT_VOLUME
1780 INIT_FN_CONN (CurrentConnection, PIN_HPOUT_SOURCE, NODE_HPOUT_VOLUME, 1);
1781
1782 // NODE_HPOUT_VOLUME -> NODE_HPOUT_MUTE
1783 INIT_NN_CONN (CurrentConnection, NODE_HPOUT_VOLUME, 0, NODE_HPOUT_MUTE, 1);
1784
1785 // NODE_HPOUT_MUTE -> PIN_HPOUT_DEST pin
1786 INIT_NN_CONN( CurrentConnection, NODE_HPOUT_MUTE, 0, NODE_MAIN_MIX, 9);
1787 }
1788
1789 // build the 3D path
1790 if (AdapterCommon->GetNodeConfig (NODEC_3D_PRESENT))
1791 {
1792 // Figure out what the main 3D line is.
1793 if (AdapterCommon->GetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE))
1794 {
1795 if (AdapterCommon->GetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE))
1796 {
1797 // PIN_VIRT_3D_DEPTH_SOURCE -> NODE_VIRT_3D_ENABLE
1799
1800 // NODE_VIRT_3D_ENABLE -> NODE_VIRT_WAVEOUT_3D_BYPASS
1802
1803 // NODE_VIRT_WAVEOUT_3D_BYPASS -> NODE_VIRT_3D_DEPTH
1805
1806 // NODE_VIRT_3D_DEPTH -> NODE_MAIN_MIX
1807 INIT_NN_CONN (CurrentConnection, NODE_VIRT_3D_DEPTH, 0, NODE_MAIN_MIX, 7);
1808
1809 // PIN_VIRT_3D_CENTER_SOURCE -> NODE_VIRT_3D_CENTER
1811
1812 // NODE_VIRT_3D_CENTER -> NODE_MAIN_MIX
1813 INIT_NN_CONN (CurrentConnection, NODE_VIRT_3D_CENTER, 0, NODE_MAIN_MIX, 8);
1814 }
1815 else
1816 {
1817 // PIN_VIRT_3D_CENTER_SOURCE -> NODE_VIRT_3D_ENABLE
1819
1820 // NODE_VIRT_3D_ENABLE -> NODE_VIRT_WAVEOUT_3D_BYPASS
1822
1823 // NODE_VIRT_WAVEOUT_3D_BYPASS -> NODE_VIRT_3D_CENTER
1825
1826 // NODE_VIRT_3D_CENTER -> NODE_MAIN_MIX
1827 INIT_NN_CONN (CurrentConnection, NODE_VIRT_3D_CENTER, 0, NODE_MAIN_MIX, 8);
1828 }
1829 }
1830 else
1831 {
1832 // PIN_VIRT_3D_DEPTH_SOURCE -> NODE_VIRT_3D_ENABLE
1834
1835 // NODE_VIRT_3D_ENABLE -> NODE_VIRT_WAVEOUT_3D_BYPASS
1837
1838 // NODE_VIRT_WAVEOUT_3D_BYPASS -> NODE_VIRT_3D_DEPTH
1840
1841 // NODE_VIRT_3D_DEPTH -> NODE_MAIN_MIX
1842 INIT_NN_CONN (CurrentConnection, NODE_VIRT_3D_DEPTH, 0, NODE_MAIN_MIX, 7);
1843 }
1844 }
1845
1846 // build the 4 or 6 channel controls
1847
1848 // In case of multichannel or headphone we have "front speakers" volume/mute.
1849 if (AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT) ||
1850 AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
1851 {
1852 // PIN_VIRT_FRONT_SOURCE -> NODE_FRONT_VOLUME
1853 INIT_FN_CONN (CurrentConnection, PIN_VIRT_FRONT_SOURCE, NODE_FRONT_VOLUME, 1);
1854
1855 // NODE_FRONT_VOLUME -> NODE_FRONT_MUTE
1856 INIT_NN_CONN (CurrentConnection, NODE_FRONT_VOLUME, 0, NODE_FRONT_MUTE, 1);
1857
1858 // NODE_FRONT_MUTE -> NODE_MAIN_MIX
1859 INIT_NN_CONN (CurrentConnection, NODE_FRONT_MUTE, 0, NODE_MAIN_MIX, 10);
1860 }
1861
1862 // Check for surround volumes
1863 if (AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT))
1864 {
1865 // PIN_VIRT_SURROUND -> NODE_SURROUND_VOLUME
1867
1868 // NODE_SURROUND_VOLUME -> NODE_SURROUND_MUTE
1869 INIT_NN_CONN (CurrentConnection, NODE_SURROUND_VOLUME, 0, NODE_SURROUND_MUTE, 1);
1870
1871 // NODE_SURROUND_MUTE -> NODE_MAIN_MIX
1872 INIT_NN_CONN (CurrentConnection, NODE_SURROUND_MUTE, 0, NODE_MAIN_MIX, 11);
1873
1874 // check also for the center and LFE volumes
1875 if (AdapterCommon->GetPinConfig (PINC_CENTER_LFE_PRESENT))
1876 {
1877 // PIN_VIRT_CENTER -> NODE_CENTER_VOLUME
1879
1880 // NODE_CENTER_VOLUME -> NODE_CENTER_MUTE
1881 INIT_NN_CONN (CurrentConnection, NODE_CENTER_VOLUME, 0, NODE_CENTER_MUTE, 1);
1882
1883 // NODE_CENTER_MUTE -> NODE_MAIN_MIX
1884 INIT_NN_CONN (CurrentConnection, NODE_CENTER_MUTE, 0, NODE_MAIN_MIX, 12);
1885
1886 // PIN_VIRT_LFE -> NODE_LFE_VOLUME
1887 INIT_FN_CONN (CurrentConnection, PIN_VIRT_LFE_SOURCE, NODE_LFE_VOLUME, 1);
1888
1889 // NODE_LFE_VOLUME -> NODE_LFE_MUTE
1890 INIT_NN_CONN (CurrentConnection, NODE_LFE_VOLUME, 0, NODE_LFE_MUTE, 1);
1891
1892 // NODE_LFE_MUTE -> NODE_MAIN_MIX
1893 INIT_NN_CONN (CurrentConnection, NODE_LFE_MUTE, 0, NODE_MAIN_MIX, 13);
1894 }
1895 }
1896
1897 // helper node variable.
1898 TopoNodes ConnectFromNode;
1899
1900 // all connections go from this one
1901 ConnectFromNode = NODE_MAIN_MIX;
1902
1903 // build the beeper & phone mix
1904 if (AdapterCommon->GetPinConfig (PINC_PCBEEP_PRESENT) ||
1905 AdapterCommon->GetPinConfig (PINC_PHONE_PRESENT))
1906 {
1907 // last node -> NODE_BEEP_MIX
1908 INIT_NN_CONN (CurrentConnection, ConnectFromNode, 0, NODE_BEEP_MIX, 1);
1909
1910 // next connection from this point.
1911 ConnectFromNode = NODE_BEEP_MIX;
1912 }
1913
1914 // build the tone control path
1915 if (AdapterCommon->GetNodeConfig (NODEC_TONE_PRESENT))
1916 {
1917 // last node -> NODE_BASS
1918 INIT_NN_CONN (CurrentConnection, ConnectFromNode, 0, NODE_BASS, 1);
1919
1920 // NODE_BASS -> NODE_TREBLE
1921 INIT_NN_CONN (CurrentConnection, NODE_BASS, 0, NODE_TREBLE, 1);
1922
1923 // remember the last node
1924 ConnectFromNode = NODE_TREBLE;
1925
1926 // build the loudness control
1927 if (AdapterCommon->GetNodeConfig (NODEC_LOUDNESS_PRESENT))
1928 {
1929 // last node -> NODE_LOUDNESS
1930 INIT_NN_CONN (CurrentConnection, ConnectFromNode, 0, NODE_LOUDNESS, 1);
1931
1932 // remember the last node
1933 ConnectFromNode = NODE_LOUDNESS;
1934 }
1935
1936 // build the simulated stereo control
1937 if (AdapterCommon->GetNodeConfig (NODEC_SIMUL_STEREO_PRESENT))
1938 {
1939 // last node -> NODE_SIMUL_STEREO
1940 INIT_NN_CONN (CurrentConnection, ConnectFromNode, 0, NODE_SIMUL_STEREO, 1);
1941
1942 // remember the last node
1943 ConnectFromNode = NODE_SIMUL_STEREO;
1944 }
1945 }
1946
1947 //build the master volume output.
1948
1949 // In case of multichannel or headphone we use a master mono control.
1950 if (AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT) ||
1951 AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
1952 {
1953 // build the connection from whatever to NODE_VIRT_MASTERMONO_VOLUME
1954 INIT_NN_CONN (CurrentConnection, ConnectFromNode, 0, NODE_VIRT_MASTERMONO_VOLUME, 1);
1955
1956 // NODE_VIRT_MASTERMONO_VOLUME -> NODE_VIRT_MASTERMONO_MUTE
1958
1959 // NODE_VIRT_MASTERMONO_MUTE -> PIN_MASTEROUT_DEST pin
1961 }
1962 else
1963 {
1964 // build the connection from whatever to NODE_MASTEROUT_VOLUME
1965 INIT_NN_CONN (CurrentConnection, ConnectFromNode, 0, NODE_MASTEROUT_VOLUME, 1);
1966
1967 // NODE_MASTEROUT_VOLUME -> NODE_MASTEROUT_MUTE
1968 INIT_NN_CONN (CurrentConnection, NODE_MASTEROUT_VOLUME, 0, NODE_MASTEROUT_MUTE, 1);
1969
1970 // NODE_MASTEROUT_MUTE -> PIN_MASTEROUT_DEST pin
1971 INIT_NF_CONN( CurrentConnection, NODE_MASTEROUT_MUTE, 0, PIN_MASTEROUT_DEST);
1972 }
1973
1974 // now complete the input muxer path
1975
1976 // PIN_VIRT_TONE_MIX_MONO_SOURCE -> NODE_VIRT_MASTER_INPUT_VOLUME7
1978
1979 // NODE_VIRT_MASTER_INPUT_VOLUME7 -> NODE_WAVEIN_SELECT
1981
1982 // PIN_VIRT_TONE_MIX_SOURCE -> NODE_VIRT_MASTER_INPUT_VOLUME6
1984
1985 // NODE_VIRT_MASTER_INPUT_VOLUME6 -> NODE_WAVEIN_SELECT
1987
1988 // NODE_WAVEIN_SELECT -> PIN_WAVEIN_DEST
1989 INIT_NF_CONN( CurrentConnection, NODE_WAVEIN_SELECT, 0, PIN_WAVEIN_DEST);
1990
1991 // build the mic output path (for record control)
1992 if (AdapterCommon->GetPinConfig (PINC_MIC_PRESENT) &&
1993 AdapterCommon->GetPinConfig (PINC_MICIN_PRESENT))
1994 {
1995 // NODE_MIC_BOOST -> NODE_MICIN_VOLUME
1996 INIT_NN_CONN (CurrentConnection, NODE_MIC_BOOST, 0, NODE_MICIN_VOLUME, 1);
1997
1998 // NODE_MICIN_VOLUME -> NODE_MICIN_MUTE
1999 INIT_NN_CONN (CurrentConnection, NODE_MICIN_VOLUME, 0, NODE_MICIN_MUTE, 1);
2000
2001 // NODE_MICIN_MUTE -> PIN_MICIN_DEST
2002 INIT_NF_CONN( CurrentConnection, NODE_MICIN_MUTE, 0, PIN_MICIN_DEST);
2003 }
2004
2005 // build the mono path
2006 if (AdapterCommon->GetPinConfig (PINC_MONOOUT_PRESENT))
2007 {
2008 // PIN_VIRT_3D_MIX_MONO_SOURCE -> NODE_MONOOUT_SMIX
2010
2011 // NODE_VIRT_MONOOUT_VOLUME1 -> NODE_MONOOUT_SELECT
2013
2014 if (AdapterCommon->GetPinConfig (PINC_MIC_PRESENT))
2015 {
2016 // NODE_MIC_BOOST -> NODE_VIRT_MONOOUT_VOLUME2
2017 INIT_NN_CONN (CurrentConnection, NODE_MIC_BOOST, 0, NODE_VIRT_MONOOUT_VOLUME2, 1);
2018
2019 // NODE_VIRT_MONOOUT_VOLUME2 -> NODE_MONOOUT_SELECT
2021 }
2022
2023 // NODE_MONOOUT_SELECT -> PIN_MONOOUT_DEST
2024 INIT_NF_CONN( CurrentConnection, NODE_MONOOUT_SELECT, 0, PIN_MONOOUT_DEST);
2025 }
2026
2027 // add the connections to the filter descriptor
2028 FilterDescriptor->ConnectionCount = ConnectionCount;
2030 } else
2031 {
2033 }
2034
2035 return ntStatus;
2036
2037#undef INIT_NN_CONN
2038#undef INIT_FN_CONN
2039#undef INIT_NF_CONN
2040}
#define INIT_NN_CONN(cptr, fnode, fpin, tnode, tpin)
#define INIT_NF_CONN(cptr, fnode, fpin, tpin)
#define INIT_FN_CONN(cptr, fpin, tnode, tpin)
@ PINC_LINEIN_PRESENT
Definition: shared.h:72
@ PINC_MONOOUT_PRESENT
Definition: shared.h:69
@ PINC_VIDEO_PRESENT
Definition: shared.h:66
@ PINC_MIC2_PRESENT
Definition: shared.h:65
@ PINC_PCBEEP_PRESENT
Definition: shared.h:63
@ PINC_PHONE_PRESENT
Definition: shared.h:64
@ PINC_AUX_PRESENT
Definition: shared.h:67
@ PINC_SURROUND_PRESENT
Definition: shared.h:74
@ PINC_CENTER_LFE_PRESENT
Definition: shared.h:75
@ PINC_HPOUT_PRESENT
Definition: shared.h:68
@ PINC_CD_PRESENT
Definition: shared.h:73
@ PINC_MICIN_PRESENT
Definition: shared.h:70
@ PINC_MIC_PRESENT
Definition: shared.h:71
TopoNodes
Definition: shared.h:186
@ NODE_MASTEROUT_VOLUME
Definition: shared.h:215
@ NODE_HPOUT_MUTE
Definition: shared.h:218
@ NODE_TREBLE
Definition: shared.h:212
@ NODE_WAVEOUT_MUTE
Definition: shared.h:188
@ NODE_PHONE_VOLUME
Definition: shared.h:192
@ NODE_VIRT_MASTER_INPUT_VOLUME1
Definition: shared.h:223
@ NODE_MICIN_MUTE
Definition: shared.h:232
@ NODE_LFE_MUTE
Definition: shared.h:238
@ NODE_BEEP_MIX
Definition: shared.h:210
@ NODE_VIRT_MONOOUT_VOLUME1
Definition: shared.h:220
@ NODE_PHONE_MUTE
Definition: shared.h:193
@ NODE_MIC_BOOST
Definition: shared.h:195
@ NODE_WAVEIN_SELECT
Definition: shared.h:222
@ NODE_HPOUT_VOLUME
Definition: shared.h:217
@ NODE_VIRT_MONOOUT_VOLUME2
Definition: shared.h:221
@ NODE_CENTER_MUTE
Definition: shared.h:236
@ NODE_LFE_VOLUME
Definition: shared.h:237
@ NODE_VIRT_MASTER_INPUT_VOLUME3
Definition: shared.h:225
@ NODE_VIRT_MASTER_INPUT_VOLUME8
Definition: shared.h:230
@ NODE_SIMUL_STEREO
Definition: shared.h:214
@ NODE_VIRT_MASTERMONO_MUTE
Definition: shared.h:242
@ NODE_AUX_VOLUME
Definition: shared.h:204
@ NODE_PCBEEP_MUTE
Definition: shared.h:191
@ NODE_VIRT_3D_CENTER
Definition: shared.h:207
@ NODE_LINEIN_VOLUME
Definition: shared.h:198
@ NODE_MIC_MUTE
Definition: shared.h:197
@ NODE_VIRT_WAVEOUT_3D_BYPASS
Definition: shared.h:189
@ NODE_VIRT_3D_ENABLE
Definition: shared.h:209
@ NODE_VIRT_MASTER_INPUT_VOLUME2
Definition: shared.h:224
@ NODE_CD_VOLUME
Definition: shared.h:200
@ NODE_FRONT_VOLUME
Definition: shared.h:239
@ NODE_MIC_VOLUME
Definition: shared.h:196
@ NODE_BASS
Definition: shared.h:211
@ NODE_LINEIN_MUTE
Definition: shared.h:199
@ NODE_VIRT_MASTER_INPUT_VOLUME6
Definition: shared.h:228
@ NODE_PCBEEP_VOLUME
Definition: shared.h:190
@ NODE_VIRT_MASTER_INPUT_VOLUME5
Definition: shared.h:227
@ NODE_LOUDNESS
Definition: shared.h:213
@ NODE_VIDEO_MUTE
Definition: shared.h:203
@ NODE_CENTER_VOLUME
Definition: shared.h:235
@ NODE_CD_MUTE
Definition: shared.h:201
@ NODE_VIRT_MASTER_INPUT_VOLUME7
Definition: shared.h:229
@ NODE_WAVEOUT_VOLUME
Definition: shared.h:187
@ NODE_FRONT_MUTE
Definition: shared.h:240
@ NODE_VIRT_MASTERMONO_VOLUME
Definition: shared.h:241
@ NODE_VIRT_3D_DEPTH
Definition: shared.h:208
@ NODE_SURROUND_VOLUME
Definition: shared.h:233
@ NODE_MASTEROUT_MUTE
Definition: shared.h:216
@ NODE_SURROUND_MUTE
Definition: shared.h:234
@ NODE_VIDEO_VOLUME
Definition: shared.h:202
@ NODE_MONOOUT_SELECT
Definition: shared.h:219
@ NODE_AUX_MUTE
Definition: shared.h:205
@ NODE_MICIN_VOLUME
Definition: shared.h:231
@ NODE_VIRT_MASTER_INPUT_VOLUME4
Definition: shared.h:226
@ NODE_MIC_SELECT
Definition: shared.h:194
@ NODE_MAIN_MIX
Definition: shared.h:206
@ NODEC_3D_DEPTH_ADJUSTABLE
Definition: shared.h:95
@ NODEC_TONE_PRESENT
Definition: shared.h:86
@ NODEC_3D_CENTER_ADJUSTABLE
Definition: shared.h:94
@ NODEC_LOUDNESS_PRESENT
Definition: shared.h:87
@ NODEC_3D_PRESENT
Definition: shared.h:85
@ NODEC_SIMUL_STEREO_PRESENT
Definition: shared.h:88
@ PIN_LINEIN_SOURCE
Definition: shared.h:118
@ PIN_VIRT_CENTER_SOURCE
Definition: shared.h:128
@ PIN_VIRT_3D_CENTER_SOURCE
Definition: shared.h:122
@ PIN_PCBEEP_SOURCE
Definition: shared.h:115
@ PIN_VIRT_TONE_MIX_SOURCE
Definition: shared.h:125
@ PIN_MICIN_DEST
Definition: shared.h:135
@ PIN_VIRT_LFE_SOURCE
Definition: shared.h:129
@ PIN_MIC_SOURCE
Definition: shared.h:117
@ PIN_VIDEO_SOURCE
Definition: shared.h:120
@ PIN_VIRT_TONE_MIX_MONO_SOURCE
Definition: shared.h:126
@ PIN_AUX_SOURCE
Definition: shared.h:121
@ PIN_CD_SOURCE
Definition: shared.h:119
@ PIN_WAVEOUT_SOURCE
Definition: shared.h:114
@ PIN_VIRT_SURROUND_SOURCE
Definition: shared.h:127
@ PIN_PHONE_SOURCE
Definition: shared.h:116
@ PIN_MONOOUT_DEST
Definition: shared.h:133
@ PIN_VIRT_3D_MIX_MONO_SOURCE
Definition: shared.h:124
@ PIN_VIRT_FRONT_SOURCE
Definition: shared.h:130
@ PIN_VIRT_3D_DEPTH_SOURCE
Definition: shared.h:123
@ PIN_WAVEIN_DEST
Definition: shared.h:134
@ PIN_HPOUT_SOURCE
Definition: shared.h:132
@ PIN_MASTEROUT_DEST
Definition: shared.h:131
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
const int TOPO_MAX_CONNECTIONS
Definition: mintopo.h:42
struct PCCONNECTION_DESCRIPTOR * PPCCONNECTION_DESCRIPTOR
ULONG ConnectionCount
Definition: portcls.h:362
const PCCONNECTION_DESCRIPTOR * Connections
Definition: portcls.h:363
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158

Referenced by BuildTopology().

◆ BuildNodeDescriptors()

NTSTATUS CAC97MiniportTopology::BuildNodeDescriptors ( void  )
private

Definition at line 978 of file mintopo.cpp.

979{
980// Improvement would be to not use a Macro, use (inline) function instead.
981#define INIT_NODE( node, nodeptr, type, name, automation, index ) \
982 nodeptr->Type = (GUID*) type; \
983 nodeptr->Name = (GUID*) name; \
984 nodeptr->AutomationTable = automation; \
985 SetNodeTranslation (index++, node); \
986 nodeptr++
987
988 PAGED_CODE ();
989
990 NTSTATUS ntStatus = STATUS_SUCCESS;
991
992 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::BuildNodeDescriptors]"));
993
994 // allocate our descriptor memory
997 if (NodeDescriptors)
998 {
1000 ULONG Index = 0;
1001
1002 //
1003 // set default node descriptor parameters
1004 //
1006 sizeof(PCNODE_DESCRIPTOR));
1007
1008 // We don't have loopback mode currently. It is only used for testing anyway.
1009
1010 // Add the NODE_WAVEOUT_VOLUME node
1012 CurrentNode,
1015 &AutomationVolume,
1016 Index);
1017
1018 // add the NODE_WAVEOUT_MUTE node
1020 CurrentNode,
1023 &AutomationMute,
1024 Index);
1025
1026 // add the PCBEEP nodes
1027 if (AdapterCommon->GetPinConfig (PINC_PCBEEP_PRESENT))
1028 {
1029 // add the NODE_PCBEEP_VOLUME node
1031 CurrentNode,
1034 &AutomationVolume,
1035 Index);
1036
1037 // add the NODE_PCBEEP_MUTE node
1039 CurrentNode,
1042 &AutomationMute,
1043 Index);
1044 }
1045
1046 // add the PHONE nodes
1047 if (AdapterCommon->GetPinConfig (PINC_PHONE_PRESENT))
1048 {
1049 // add the NODE_PHONE_VOLUME node
1051 CurrentNode,
1054 &AutomationVolume,
1055 Index);
1056
1057 // add the NODE_PHONE_MUTE node
1059 CurrentNode,
1062 &AutomationMute,
1063 Index);
1064 }
1065
1066 // add the MIC nodes
1067 if (AdapterCommon->GetPinConfig (PINC_MIC_PRESENT))
1068 {
1069 if (AdapterCommon->GetPinConfig (PINC_MIC2_PRESENT))
1070 {
1071 // add the NODE_MIC_SELECT node
1073 CurrentNode,
1076 &AutomationSpecial,
1077 Index);
1078 }
1079
1080 // add the NODE_MIC_BOOST node
1082 CurrentNode,
1085 &AutomationSpecial,
1086 Index);
1087
1088 // add the NODE_MIC_VOLUME node
1090 CurrentNode,
1093 &AutomationVolume,
1094 Index);
1095
1096 // add the NODE_MIC_MUTE node
1098 CurrentNode,
1101 &AutomationMute,
1102 Index);
1103 }
1104
1105 if (AdapterCommon->GetPinConfig (PINC_LINEIN_PRESENT))
1106 {
1107 // add the NODE_LINEIN_VOLUME node
1109 CurrentNode,
1112 &AutomationVolume,
1113 Index);
1114
1115 // add the NODE_LINEIN_MUTE node
1117 CurrentNode,
1120 &AutomationMute,
1121 Index);
1122 }
1123
1124 if (AdapterCommon->GetPinConfig (PINC_CD_PRESENT))
1125 {
1126 // add the NODE_CD_VOLUME node
1128 CurrentNode,
1131 &AutomationVolume,
1132 Index);
1133
1134 // add the NODE_CD_MUTE node
1136 CurrentNode,
1139 &AutomationMute,
1140 Index);
1141 }
1142
1143 // add the VIDEO nodes
1144 if (AdapterCommon->GetPinConfig (PINC_VIDEO_PRESENT))
1145 {
1146 // add the NODE_VIDEO_VOLUME node
1148 CurrentNode,
1151 &AutomationVolume,
1152 Index);
1153
1154 // add the NODE_VIDEO_MUTE node
1156 CurrentNode,
1159 &AutomationMute,
1160 Index);
1161 }
1162
1163 // add the AUX nodes
1164 if (AdapterCommon->GetPinConfig (PINC_AUX_PRESENT))
1165 {
1166 // add the NODE_AUX_VOLUME node
1168 CurrentNode,
1171 &AutomationVolume,
1172 Index);
1173
1174 // add the NODE_AUX_MUTE node
1176 CurrentNode,
1179 &AutomationMute,
1180 Index);
1181 }
1182
1183 // add the NODE_MAIN_MIX node
1185 CurrentNode,
1188 NULL,
1189 Index);
1190
1191 // add the 3D nodes
1192 if (AdapterCommon->GetNodeConfig (NODEC_3D_PRESENT))
1193 {
1194 if (AdapterCommon->GetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE))
1195 {
1196 // add the NODE_VIRT_3D_CENTER node
1198 CurrentNode,
1201 &Automation3D,
1202 Index);
1203 }
1204
1205 if (AdapterCommon->GetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE) ||
1206 (!AdapterCommon->GetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE) &&
1207 !AdapterCommon->GetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE)))
1208 {
1209 // add the NODE_VIRT_3D_DEPTH node
1211 CurrentNode,
1214 &Automation3D,
1215 Index);
1216 }
1217
1218 // add the NODE_VIRT_3D_ENABLE node
1220 CurrentNode,
1223 &AutomationSpecial,
1224 Index);
1225
1226 // add the NODE_VIRT_WAVEOUT_3D_BYPASS node
1228 CurrentNode,
1231 &AutomationSpecial,
1232 Index);
1233 }
1234
1235 if (AdapterCommon->GetPinConfig (PINC_PCBEEP_PRESENT) ||
1236 AdapterCommon->GetPinConfig (PINC_PHONE_PRESENT))
1237 {
1238 // add the NODE_BEEP_MIX node
1240 CurrentNode,
1243 NULL,
1244 Index);
1245 }
1246
1247 // add the tone nodes
1248 if (AdapterCommon->GetNodeConfig (NODEC_TONE_PRESENT))
1249 {
1250 // add the NODE_BASS node
1252 CurrentNode,
1255 &AutomationTone,
1256 Index);
1257
1258 // add the NODE_TREBLE node
1260 CurrentNode,
1263 &AutomationTone,
1264 Index);
1265
1266 if (AdapterCommon->GetNodeConfig (NODEC_LOUDNESS_PRESENT))
1267 {
1268 // add the NODE_LOUDNESS node
1270 CurrentNode,
1272 NULL,
1273 &AutomationSpecial,
1274 Index);
1275 }
1276
1277 if (AdapterCommon->GetNodeConfig (NODEC_SIMUL_STEREO_PRESENT))
1278 {
1279 // add the NODE_SIMUL_STEREO node
1281 CurrentNode,
1284 &AutomationSpecial,
1285 Index);
1286 }
1287 }
1288
1289 // Add a "Front Speaker" volume/mute if we have surround or headphones.
1290 // The "Master" volume/mute will be mono then
1291 if (AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT) ||
1292 AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
1293 {
1294 // Add the front speaker volume.
1296 CurrentNode,
1299 &AutomationVolume,
1300 Index);
1301
1302 // Add the front speaker mute.
1304 CurrentNode,
1307 &AutomationMute,
1308 Index);
1309
1310 // Add the master mono out volume.
1312 CurrentNode,
1315 &AutomationVolume,
1316 Index);
1317
1318 // Add the master mono out volume.
1320 CurrentNode,
1323 &AutomationMute,
1324 Index);
1325 }
1326 else
1327 {
1328 // add the NODE_MASTEROUT_VOLUME node
1330 CurrentNode,
1333 &AutomationVolume,
1334 Index);
1335
1336 // add the NODE_MASTEROUT_MUTE node
1338 CurrentNode,
1341 &AutomationMute,
1342 Index);
1343 }
1344
1345 // Add the surround control if we have one.
1346 if (AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT))
1347 {
1348 // Add the surround volume.
1350 CurrentNode,
1353 &AutomationVolume,
1354 Index);
1355
1356 // Add the surround mute.
1358 CurrentNode,
1361 &AutomationMute,
1362 Index);
1363
1364 // Add the center and LFE control if we have one.
1365 if (AdapterCommon->GetPinConfig (PINC_CENTER_LFE_PRESENT))
1366 {
1367 // Add the center volume.
1369 CurrentNode,
1372 &AutomationVolume,
1373 Index);
1374
1375 // Add the center mute.
1377 CurrentNode,
1380 &AutomationMute,
1381 Index);
1382
1383 // Add the LFE volume.
1385 CurrentNode,
1388 &AutomationVolume,
1389 Index);
1390
1391 // Add the LFE mute.
1393 CurrentNode,
1396 &AutomationMute,
1397 Index);
1398 }
1399 }
1400
1401 // add the HPOUT nodes
1402 if (AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
1403 {
1404 // add the NODE_HPOUT_VOLUME node
1406 CurrentNode,
1409 &AutomationVolume,
1410 Index);
1411
1412 // add the NODE_HPOUT_MUTE node
1414 CurrentNode,
1417 &AutomationMute,
1418 Index);
1419 }
1420
1421 // add the NODE_WAVEIN_SELECT node
1423 CurrentNode,
1426 &AutomationMux,
1427 Index);
1428
1429 if (AdapterCommon->GetPinConfig (PINC_MIC_PRESENT))
1430 {
1431 // add the NODE_VIRT_MASTER_INPUT_VOLUME1 node
1433 CurrentNode,
1436 &AutomationVolume,
1437 Index);
1438 }
1439
1440 if (AdapterCommon->GetPinConfig (PINC_CD_PRESENT))
1441 {
1442 // add the NODE_VIRT_MASTER_INPUT_VOLUME2 node
1444 CurrentNode,
1447 &AutomationVolume,
1448 Index);
1449 }
1450
1451 if (AdapterCommon->GetPinConfig (PINC_VIDEO_PRESENT))
1452 {
1453 // add the NODE_VIRT_MASTER_INPUT_VOLUME3 node
1455 CurrentNode,
1458 &AutomationVolume,
1459 Index);
1460 }
1461
1462 if (AdapterCommon->GetPinConfig (PINC_AUX_PRESENT))
1463 {
1464 // add the NODE_VIRT_MASTER_INPUT_VOLUME4 node
1466 CurrentNode,
1469 &AutomationVolume,
1470 Index);
1471 }
1472
1473 if (AdapterCommon->GetPinConfig (PINC_LINEIN_PRESENT))
1474 {
1475 // add the NODE_VIRT_MASTER_INPUT_VOLUME5 node
1477 CurrentNode,
1480 &AutomationVolume,
1481 Index);
1482 }
1483
1484 // add the NODE_VIRT_MASTER_INPUT_VOLUME6 node
1486 CurrentNode,
1489 &AutomationVolume,
1490 Index);
1491
1492 // add the NODE_VIRT_MASTER_INPUT_VOLUME7 node
1494 CurrentNode,
1497 &AutomationVolume,
1498 Index);
1499
1500 if (AdapterCommon->GetPinConfig (PINC_PHONE_PRESENT))
1501 {
1502 // add the NODE_VIRT_MASTER_INPUT_VOLUME8 node
1504 CurrentNode,
1507 &AutomationVolume,
1508 Index);
1509 }
1510
1511 // add the MICIN nodes
1512 if (AdapterCommon->GetPinConfig (PINC_MIC_PRESENT) &&
1513 AdapterCommon->GetPinConfig (PINC_MICIN_PRESENT))
1514 {
1515 // add the NODE_MICIN_VOLUME node
1517 CurrentNode,
1520 &AutomationVolume,
1521 Index);
1522
1523 // add the NODE_MICIN_MUTE node
1525 CurrentNode,
1528 &AutomationMute,
1529 Index);
1530 }
1531
1532 // add the MONOOUT nodes
1533 if (AdapterCommon->GetPinConfig (PINC_MONOOUT_PRESENT))
1534 {
1535 // add the NODE_MONOOUT_SELECT node
1537 CurrentNode,
1540 &AutomationMux,
1541 Index);
1542
1543 // add the NODE_VIRT_MONOOUT_VOLUME1 node
1545 CurrentNode,
1548 &AutomationVolume,
1549 Index);
1550
1551 // add the NODE_VIRT_MONOOUT_VOLUME2 node
1553 CurrentNode,
1556 &AutomationVolume,
1557 Index);
1558 }
1559
1560 // add the nodes to the filter descriptor
1564 }
1565 else
1566 {
1568 }
1569
1570 return ntStatus;
1571
1572#undef INIT_NODE
1573}
#define INIT_NODE(node, nodeptr, type, name, automation, index)
@ NODE_TOP_ELEMENT
Definition: shared.h:243
#define MYKSNAME_MAIN_MIX
Definition: guids.h:42
#define MYKSNAME_PHONE_VOLUME
Definition: guids.h:24
#define MYKSNAME_FRONT_VOLUME
Definition: guids.h:156
#define MYKSNAME_HPOUT_VOLUME
Definition: guids.h:66
#define MYKSNAME_MONOOUT_SELECT
Definition: guids.h:78
#define MYKSNAME_CENTER_VOLUME
Definition: guids.h:132
#define MYKSNAME_MICIN_MUTE
Definition: guids.h:108
#define MYKSNAME_WAVEIN_SELECT
Definition: guids.h:84
#define MYKSNAME_BEEP_MIX
Definition: guids.h:60
#define MYKSNAME_PHONE_MUTE
Definition: guids.h:30
#define MYKSNAME_HPOUT_MUTE
Definition: guids.h:72
#define MYKSNAME_SIMUL_STEREO
Definition: guids.h:114
#define MYKSNAME_WAVEOUT_3D_BYPASS
Definition: guids.h:48
#define MYKSNAME_MASTER_INPUT_VOLUME
Definition: guids.h:90
#define MYKSNAME_CENTER_MUTE
Definition: guids.h:138
#define MYKSNAME_3D_ENABLE
Definition: guids.h:54
#define MYKSNAME_MICIN_VOLUME
Definition: guids.h:102
#define MYKSNAME_LFE_MUTE
Definition: guids.h:150
#define MYKSNAME_LFE_VOLUME
Definition: guids.h:144
#define MYKSNAME_LINEIN_MUTE
Definition: guids.h:36
#define MYKSNAME_SURROUND_VOLUME
Definition: guids.h:120
#define MYKSNAME_SURROUND_MUTE
Definition: guids.h:126
#define MYKSNAME_FRONT_MUTE
Definition: guids.h:162
#define KSAUDFNAME_MONO_MIX_VOLUME
Definition: ksmedia.h:564
#define KSNODETYPE_TONE
Definition: ksmedia.h:453
#define KSAUDFNAME_PC_SPEAKER_VOLUME
Definition: ksmedia.h:514
#define KSAUDFNAME_MIC_MUTE
Definition: ksmedia.h:418
#define KSAUDFNAME_MICROPHONE_BOOST
Definition: ksmedia.h:403
#define KSNODETYPE_SUM
Definition: ksmedia.h:363
#define KSNODETYPE_LOUDNESS
Definition: ksmedia.h:398
#define KSAUDFNAME_VIDEO_MUTE
Definition: ksmedia.h:609
#define KSNODETYPE_MUX
Definition: ksmedia.h:433
#define KSAUDFNAME_AUX_MUTE
Definition: ksmedia.h:423
#define KSAUDFNAME_MASTER_VOLUME
Definition: ksmedia.h:368
#define KSAUDFNAME_STEREO_MIX_VOLUME
Definition: ksmedia.h:569
#define KSAUDFNAME_VIDEO_VOLUME
Definition: ksmedia.h:574
#define KSNODETYPE_VOLUME
Definition: ksmedia.h:338
#define KSAUDFNAME_CD_MUTE
Definition: ksmedia.h:408
#define KSNODETYPE_MUTE
Definition: ksmedia.h:348
#define KSAUDFNAME_LINE_IN_VOLUME
Definition: ksmedia.h:383
#define KSAUDFNAME_MASTER_MUTE
Definition: ksmedia.h:438
#define KSNODETYPE_AGC
Definition: ksmedia.h:267
#define KSAUDFNAME_BASS
Definition: ksmedia.h:584
#define KSAUDFNAME_WAVE_VOLUME
Definition: ksmedia.h:343
#define KSAUDFNAME_TREBLE
Definition: ksmedia.h:579
#define KSAUDFNAME_AUX_VOLUME
Definition: ksmedia.h:388
#define KSAUDFNAME_MIC_VOLUME
Definition: ksmedia.h:358
#define KSAUDFNAME_ALTERNATE_MICROPHONE
Definition: ksmedia.h:604
#define KSAUDFNAME_PC_SPEAKER_MUTE
Definition: ksmedia.h:599
#define KSAUDFNAME_CD_VOLUME
Definition: ksmedia.h:373
#define KSAUDFNAME_3D_DEPTH
Definition: ksmedia.h:589
#define KSAUDFNAME_WAVE_MUTE
Definition: ksmedia.h:353
#define KSAUDFNAME_3D_CENTER
Definition: ksmedia.h:559
struct PCNODE_DESCRIPTOR * PPCNODE_DESCRIPTOR
const PCNODE_DESCRIPTOR * Nodes
Definition: portcls.h:361
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by BuildTopology().

◆ BuildPinDescriptors()

NTSTATUS CAC97MiniportTopology::BuildPinDescriptors ( void  )
private

Definition at line 704 of file mintopo.cpp.

705{
706// Improvement would be to not use a Macro, use (inline) function instead.
707#define INIT_PIN( pin, pinptr, category, name, index ) \
708 pinptr->KsPinDescriptor.Category = (GUID*) category; \
709 pinptr->KsPinDescriptor.Name = (GUID*) name; \
710 SetPinTranslation (index++, pin); \
711 pinptr++
712
713 PAGED_CODE ();
714
715 ULONG Index;
716 PPCPIN_DESCRIPTOR CurrentPin;
717
718 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::BuildPinDescriptors]"));
719
720 // allocate our descriptor memory
723 if (!PinDescriptors)
725
726 //
727 // set default pin descriptor parameters
728 //
730
731 // spend some more time and set the pin descriptors to expected values.
732 for (CurrentPin = PinDescriptors, Index = 0; Index < PIN_TOP_ELEMENT;
733 CurrentPin++, Index++)
734 {
736 CurrentPin->KsPinDescriptor.DataRanges = PinDataRangePointersAnalogBridge;
737 CurrentPin->KsPinDescriptor.DataFlow = KSPIN_DATAFLOW_IN;
738 CurrentPin->KsPinDescriptor.Communication = KSPIN_COMMUNICATION_NONE;
739 }
740
741 //
742 // modify the individual pin descriptors
743 //
744 CurrentPin = PinDescriptors;
745 Index = 0;
746
747 // add the PIN_WAVEOUT_SOURCE pin descriptor (not optional)
749 CurrentPin,
751 NULL,
752 Index);
753
754 // add the PIN_PCBEEP_SOURCE pin descriptor (optional)
755 if (AdapterCommon->GetPinConfig (PINC_PCBEEP_PRESENT))
756 {
758 CurrentPin,
761 Index);
762 }
763
764 // add the PIN_PHONE_SOURCE pin descriptor (optional)
765 if (AdapterCommon->GetPinConfig (PINC_PHONE_PRESENT))
766 {
768 CurrentPin,
770 NULL,
771 Index);
772 }
773
774 // add the PIN_MIC_SOURCE pin descriptor (could be disabled)
775 if (AdapterCommon->GetPinConfig (PINC_MIC_PRESENT))
776 {
778 CurrentPin,
780 NULL,
781 Index);
782 }
783
784 // add the PIN_LINEIN_SOURCE pin descriptor (could be disabled)
785 if (AdapterCommon->GetPinConfig (PINC_LINEIN_PRESENT))
786 {
788 CurrentPin,
791 Index);
792 }
793
794 // add the PIN_CD_SOURCE pin descriptor (could be disabled)
795 if (AdapterCommon->GetPinConfig (PINC_CD_PRESENT))
796 {
798 CurrentPin,
801 Index);
802 }
803
804 // add the PIN_VIDEO_SOURCE pin descriptor (optional)
805 if (AdapterCommon->GetPinConfig (PINC_VIDEO_PRESENT))
806 {
808 CurrentPin,
811 Index);
812 }
813
814 // add the PIN_AUX_SOURCE pin descriptor (optional)
815 if (AdapterCommon->GetPinConfig (PINC_AUX_PRESENT))
816 {
818 CurrentPin,
821 Index);
822 }
823
824 // add the PIN_VIRT_TONE_MIX_SOURCE pin descriptor (not optional)
826 CurrentPin,
829 Index);
830
831 // add the PIN_VIRT_TONE_MIX_MONO_SOURCE pin descriptor (not optional)
833 CurrentPin,
836 Index);
837
838 // create a virt. pin for the 3D controls
839 if (AdapterCommon->GetNodeConfig (NODEC_3D_PRESENT))
840 {
841 if (AdapterCommon->GetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE))
842 {
844 CurrentPin,
847 Index);
848 }
849
850 // A weird way would be to have 3D but only fixed sliders. In that case,
851 // display one fixed slider (3D depth).
852 if (AdapterCommon->GetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE) ||
853 (!AdapterCommon->GetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE) &&
854 !AdapterCommon->GetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE)))
855 {
857 CurrentPin,
860 Index);
861 }
862 }
863
864 // Add a "Front speaker" pin if we have multichannel or headphones.
865 // We use a master mono then ...
866 if (AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT) ||
867 AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
868 {
869 // Add a "Front speaker" pin, because in multichannel we want
870 // to display a master mono that effects all channels.
872 CurrentPin,
875 Index);
876 }
877
878 // check for multichannel
879 if (AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT))
880 {
881 // Add the Rear Speaker Volume pin.
883 CurrentPin,
886 Index);
887
888 // add the Center Volume pin if we support at least 6 channel.
889 if (AdapterCommon->GetPinConfig (PINC_CENTER_LFE_PRESENT))
890 {
892 CurrentPin,
895 Index);
896
898 CurrentPin,
901 Index);
902 }
903 }
904
905 // add the PIN_MASTEROUT_DEST pin descriptor (not optional)
906 CurrentPin->KsPinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
908 CurrentPin,
911 Index);
912
913 // add the PIN_HPOUT_SOURCE pin descriptor (optional)
914 if (AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
915 {
917 CurrentPin,
919 NULL,
920 Index);
921 }
922
923 // add the PIN_WAVEIN_DEST pin descriptor (not optional)
924 CurrentPin->KsPinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
926 CurrentPin,
928 NULL,
929 Index);
930
931 // add the PIN_MICIN_DEST pin descriptor (optional)
932 if (AdapterCommon->GetPinConfig (PINC_MICIN_PRESENT) &&
933 AdapterCommon->GetPinConfig (PINC_MIC_PRESENT))
934 {
935 CurrentPin->KsPinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
937 CurrentPin,
939 NULL,
940 Index);
941 }
942
943 // add the PIN_MONOOUT_DEST pin descriptor (optional)
944 if (AdapterCommon->GetPinConfig (PINC_MONOOUT_PRESENT))
945 {
946 // add the PIN_VIRT_3D_MIX_MONO_SOURCE pin descriptor
948 CurrentPin,
951 Index);
952
953 CurrentPin->KsPinDescriptor.DataFlow = KSPIN_DATAFLOW_OUT;
954 // and the normal output pin
956 CurrentPin,
959 Index);
960 }
961
962 // add the pin descriptor informatin to the filter descriptor
966
967
968 return STATUS_SUCCESS;
969
970#undef INIT_PIN
971}
#define INIT_PIN(pin, pinptr, category, name, index)
#define SIZEOF_ARRAY(ar)
Definition: cdrom.h:1482
static PKSDATARANGE PinDataRangePointersAnalogBridge[]
Definition: miniport.cpp:49
@ PIN_TOP_ELEMENT
Definition: shared.h:136
#define MYKSNAME_CENTER
Definition: guids.h:174
#define MYKSNAME_LFE
Definition: guids.h:180
#define MYKSNAME_SURROUND
Definition: guids.h:168
#define MYKSNAME_FRONT
Definition: guids.h:186
@ KSPIN_DATAFLOW_IN
Definition: ks.h:1249
@ KSPIN_DATAFLOW_OUT
Definition: ks.h:1250
@ KSPIN_COMMUNICATION_NONE
Definition: ks.h:1254
#define KSAUDFNAME_LINE_IN
Definition: ksmedia.h:534
#define KSNODETYPE_CD_PLAYER
Definition: ksmedia.h:302
#define KSNODETYPE_MICROPHONE
Definition: ksmedia.h:297
#define KSAUDFNAME_CD_AUDIO
Definition: ksmedia.h:524
#define KSNODETYPE_ANALOG_CONNECTOR
Definition: ksmedia.h:323
#define KSAUDFNAME_MONO_OUT
Definition: ksmedia.h:594
#define KSAUDFNAME_MONO_MIX
Definition: ksmedia.h:554
#define KSAUDFNAME_VOLUME_CONTROL
Definition: ksmedia.h:428
#define KSAUDFNAME_AUX
Definition: ksmedia.h:544
#define KSAUDFNAME_STEREO_MIX
Definition: ksmedia.h:549
#define KSNODETYPE_LINE_CONNECTOR
Definition: ksmedia.h:318
#define KSAUDFNAME_PC_SPEAKER
Definition: ksmedia.h:529
#define KSCATEGORY_AUDIO
Definition: ksmedia.h:172
#define KSNODETYPE_HEADPHONES
Definition: ksmedia.h:484
#define KSAUDFNAME_VIDEO
Definition: ksmedia.h:539
#define KSNODETYPE_SPEAKER
Definition: ksmedia.h:328
#define KSNODETYPE_PHONE_LINE
Definition: ksmedia.h:519
struct PCPIN_DESCRIPTOR * PPCPIN_DESCRIPTOR
const PCPIN_DESCRIPTOR * Pins
Definition: portcls.h:358
KSPIN_DESCRIPTOR KsPinDescriptor
Definition: portcls.h:343

Referenced by BuildTopology().

◆ BuildTopology()

NTSTATUS CAC97MiniportTopology::BuildTopology ( void  )
private

Definition at line 656 of file mintopo.cpp.

657{
658 PAGED_CODE ();
659
660 NTSTATUS ntStatus = STATUS_SUCCESS;
661
662 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::BuildTopology]"));
663
664 // allocate our filter descriptor
668 {
669 // clear out the filter descriptor
671
672#ifdef INCLUDE_PRIVATE_PROPERTY
673 // Set the Filter automation table.
674 FilterDescriptor->AutomationTable = &FilterAutomationPrivate;
675#endif
676
677 // build the pin list
678 ntStatus = BuildPinDescriptors ();
679 if (NT_SUCCESS (ntStatus))
680 {
681 // build the node list
682 ntStatus = BuildNodeDescriptors ();
683 if (NT_SUCCESS (ntStatus))
684 {
685 // build the connection list
686 ntStatus = BuildConnectionDescriptors ();
687 }
688 }
689 }
690 else
691 {
693 }
694
695 // that's whatever one of these build... functions returned.
696 return ntStatus;
697}
NTSTATUS BuildPinDescriptors(void)
Definition: mintopo.cpp:704
NTSTATUS BuildNodeDescriptors(void)
Definition: mintopo.cpp:978
NTSTATUS BuildConnectionDescriptors(void)
Definition: mintopo.cpp:1580
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
struct PCFILTER_DESCRIPTOR * PPCFILTER_DESCRIPTOR
const PCAUTOMATION_TABLE * AutomationTable
Definition: portcls.h:355

◆ DECLARE_STD_UNKNOWN()

CAC97MiniportTopology::DECLARE_STD_UNKNOWN ( )

◆ DEFINE_STD_CONSTRUCTOR()

CAC97MiniportTopology::DEFINE_STD_CONSTRUCTOR ( CAC97MiniportTopology  )

◆ GetDBValues()

NTSTATUS CAC97MiniportTopology::GetDBValues ( IN PADAPTERCOMMON  AdapterCommon,
IN TopoNodes  Node,
OUT LONG plMinimum,
OUT LONG plMaximum,
OUT ULONG puStep 
)
static

Definition at line 155 of file prophnd.cpp.

163{
164 PAGED_CODE();
165
166 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::GetDBValues]"));
167
168 // This is going to be simple. Check the node and return the parameters.
169 switch (Node)
170 {
171 // These nodes could have 5bit or 6bit controls, so we first
172 // have to check this.
173#ifndef __REACTOS__
175#endif
180 case NODE_LFE_VOLUME:
183 // needed for the config query
185
186 // which node to query?
190 if (Node == NODE_HPOUT_VOLUME)
196
197 // check if we have 6th bit support.
198 if (AdapterCommon->GetNodeConfig (config))
199 {
200 // 6bit control
201 *plMaximum = 0; // 0 dB
202 *plMinimum = 0xFFA18000; // -94.5 dB
203 *puStep = 0x00018000; // 1.5 dB
204 }
205 else
206 {
207 // 5bit control
208 *plMaximum = 0; // 0 dB
209 *plMinimum = 0xFFD18000; // -46.5 dB
210 *puStep = 0x00018000; // 1.5 dB
211 }
212 break;
213
215 // This virtual control gets added to the speaker volumes.
216 // We assume 5-bit volumes.
217 *plMaximum = 0; // 0 dB
218 *plMinimum = 0xFFD18000; // -46.5 dB
219 *puStep = 0x00018000; // 1.5 dB
220 break;
221
223 *plMaximum = 0; // 0 dB
224 *plMinimum = 0xFFD30000; // -45 dB
225 *puStep = 0x00030000; // 3 dB
226 break;
227
231 case NODE_CD_VOLUME:
233 case NODE_AUX_VOLUME:
235#ifdef __REACTOS__
236 // ReactOS change: use the same Decibel range as for WaveOut,
237 // to fix incorrect volume level change scaling. CORE-14780
239#endif
240 *plMaximum = 0x000C0000; // 12 dB
241 *plMinimum = 0xFFDD8000; // -34.5 dB
242 *puStep = 0x00018000; // 1.5 dB
243 break;
244
245
254 case NODE_MIC_VOLUME:
255 *plMaximum = 0x00168000; // 22.5 dB
256 *plMinimum = 0; // 0 dB
257 *puStep = 0x00018000; // 1.5 dB
258 break;
259
260 case NODE_BASS:
261 case NODE_TREBLE:
262 *plMaximum = 0x000A8000; // 10.5 dB
263 *plMinimum = 0xFFF58000; // -10.5 dB
264 *puStep = 0x00018000; // 1.5 dB
265 break;
266
267 // These nodes can be fixed or variable.
268 // Normally we won't display a fixed volume slider, but if 3D is
269 // supported and both sliders are fixed, we have to display one fixed
270 // slider for the advanced control panel.
273 if (AdapterCommon->GetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE) &&
275 {
276 *plMaximum = 0x000F0000; // +15 dB
277 *plMinimum = 0x00000000; // 0 dB
278 *puStep = 0x00010000; // 1 dB
279 }
280 else
281 if (AdapterCommon->GetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE) &&
283 {
284 *plMaximum = 0x000F0000; // +15 dB
285 *plMinimum = 0x00000000; // 0 dB
286 *puStep = 0x00010000; // 1 dB
287 }
288 else
289 {
290 // In case it is fixed, read the value and return it.
291 WORD wRegister;
292
293 // read the register
294 if (!NT_SUCCESS (AdapterCommon->ReadCodecRegister (
295 AdapterCommon->GetNodeReg (Node), &wRegister)))
296 wRegister = 0; // in case we fail.
297
298 // mask out the control
299 wRegister &= AdapterCommon->GetNodeMask (Node);
301 {
302 wRegister >>= 8;
303 }
304 // calculate the dB value.
305 *plMaximum = (DWORD)(-wRegister) << 16; // fixed value
306 *plMinimum = (DWORD)(-wRegister) << 16; // fixed value
307 *puStep = 0x00010000; // 1 dB
308 }
309 break;
310
311 case NODE_INVALID:
312 default:
313 // poeser pupe, tu.
314 DOUT (DBG_ERROR, ("GetDBValues: Invalid node requested."));
316 }
317
318 return STATUS_SUCCESS;
319}
struct config_s config
@ NODE_INVALID
Definition: shared.h:244
TopoNodeConfig
Definition: shared.h:84
@ NODEC_6BIT_CENTER_LFE_VOLUME
Definition: shared.h:93
@ NODEC_6BIT_HPOUT_VOLUME
Definition: shared.h:90
@ NODEC_6BIT_SURROUND_VOLUME
Definition: shared.h:92
@ NODEC_6BIT_MONOOUT_VOLUME
Definition: shared.h:91
@ NODEC_6BIT_MASTER_VOLUME
Definition: shared.h:89
unsigned short WORD
Definition: ntddk_ex.h:93
#define DBG_ERROR
Definition: nfs41_debug.h:78
#define DWORD
Definition: nt_native.h:44
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
Definition: dlist.c:348

Referenced by BasicSupportHandler(), PropertyHandler_Level(), PropertyHandler_Tone(), PropertyHandler_Ulong(), and SetMultichannelVolume().

◆ PropertyHandler_CpuResources()

NTSTATUS CAC97MiniportTopology::PropertyHandler_CpuResources ( IN PPCPROPERTY_REQUEST  PropertyRequest)
static

Definition at line 1631 of file prophnd.cpp.

1635{
1636 PAGED_CODE ();
1637
1638 ASSERT (PropertyRequest);
1639
1640 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::PropertyHandler_CpuResources]"));
1641
1642 CAC97MiniportTopology *that =
1643 (CAC97MiniportTopology *) PropertyRequest->MajorTarget;
1645
1646 ASSERT (that);
1647
1648 // validate node
1649 if (PropertyRequest->Node == (ULONG)-1)
1650 return ntStatus;
1651
1652 // validate the node def.
1653 if (that->TransNodeNrToNodeDef (PropertyRequest->Node) == NODE_INVALID)
1654 return ntStatus;
1655
1656 // we should do a get
1657 if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
1658 {
1659 // just return the flag.
1660 if (PropertyRequest->ValueSize >= sizeof(LONG))
1661 {
1662 *((PLONG)PropertyRequest->Value) = KSAUDIO_CPU_RESOURCES_NOT_HOST_CPU;
1663 PropertyRequest->ValueSize = sizeof(LONG);
1664 ntStatus = STATUS_SUCCESS;
1665 }
1666 else // not enough buffer.
1667 {
1668 ntStatus = STATUS_BUFFER_TOO_SMALL;
1669 }
1670 }
1671
1672 return ntStatus;
1673}
#define KSAUDIO_CPU_RESOURCES_NOT_HOST_CPU
Definition: ksmedia.h:1198
long LONG
Definition: pedump.c:60
int32_t * PLONG
Definition: typedefs.h:58
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138

◆ PropertyHandler_Level()

NTSTATUS CAC97MiniportTopology::PropertyHandler_Level ( IN PPCPROPERTY_REQUEST  PropertyRequest)
static

Definition at line 688 of file prophnd.cpp.

692{
693 PAGED_CODE ();
694
695 ASSERT (PropertyRequest);
696
697 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::PropertyHandler_Level]"));
698
700 TopoNodes NodeDef;
701 LONG channel;
703 ULONG uStep;
704 // The major target is the object pointer to the topology miniport.
706 (CAC97MiniportTopology *) PropertyRequest->MajorTarget;
707
708 ASSERT (that);
709
710 // validate node
711 if (PropertyRequest->Node == (ULONG)-1)
712 return ntStatus;
713
714 // do the appropriate action for the request.
715
716 // we should do a get or a set?
717 if ((PropertyRequest->Verb & KSPROPERTY_TYPE_GET) ||
718 (PropertyRequest->Verb & KSPROPERTY_TYPE_SET))
719 {
720 // validate parameters
721 if ((PropertyRequest->InstanceSize < sizeof(LONG)) ||
722 (PropertyRequest->ValueSize < sizeof(LONG)))
723 return ntStatus;
724
725 // get channel information
726 channel = *((PLONG)PropertyRequest->Instance);
727
728 // check channel types, return when unknown
729 // as you can see, we have no multichannel support.
730 if ((channel != CHAN_LEFT) &&
731 (channel != CHAN_RIGHT) &&
732 (channel != CHAN_MASTER))
733 return ntStatus;
734
735 // get the buffer
736 PLONG Level = (PLONG)PropertyRequest->Value;
737
738 // Switch on the node id. This is just for parameter checking.
739 // If something goes wrong, we will immideately return with
740 // ntStatus, which is STATUS_INVALID_PARAMETER.
741 switch(NodeDef = that->TransNodeNrToNodeDef (PropertyRequest->Node))
742 {
743 // these are mono channels, don't respond to a right channel
744 // request.
747 case NODE_MIC_VOLUME:
756 case NODE_LFE_VOLUME:
757 // check type
758 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_VOLUMELEVEL)
759 return ntStatus;
760 // check channel
761 if (channel == CHAN_RIGHT)
762 return ntStatus;
763 // Well, this is a fake for the routine below that should work
764 // for all nodes ... On AC97 the right channel are the LSBs and
765 // mono channels have only LSBs used. Windows however thinks that
766 // mono channels are left channels (only). So we could say here
767 // we have a right channel request (to prg. the LSBs) instead of
768 // a left channel request. But we have some controls that are HW-
769 // stereo, but exposed to the system as mono. These are the virtual
770 // volume controls in front of the wave-in muxer for the MIC, PHONE
771 // and MONO MIX signals (see to the switch:
772 // NODE_VIRT_MASTER_INPUT_VOLUME1, 7 and 8). Saying we have a MASTER
773 // request makes sure the value is prg. for left and right channel,
774 // but on HW-mono controls the right channel is prg. only, cause the
775 // mask in ac97reg.h leads to a 0-mask for left channel prg. which
776 // just does nothing ;)
777 channel = CHAN_MASTER;
778 break;
779
780 // These are stereo channels.
786 case NODE_CD_VOLUME:
788 case NODE_AUX_VOLUME:
795 // check type
796 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_VOLUMELEVEL)
797 return ntStatus;
798 // check channel; we don't support a get with master
799 if ((channel == CHAN_MASTER) &&
800 (PropertyRequest->Verb & KSPROPERTY_TYPE_GET))
801 return ntStatus;
802 break;
803
804 case NODE_INVALID:
805 default:
806 // Ooops
807 DOUT (DBG_ERROR, ("PropertyHandler_Level: Invalid node requested."));
808 return ntStatus;
809 }
810
811 // Now, do some action!
812
813 // get the registered dB values.
814 ntStatus = GetDBValues (that->AdapterCommon, NodeDef, &lMinimum,
815 &lMaximum, &uStep);
816 if (!NT_SUCCESS (ntStatus))
817 return ntStatus;
818
819 // do a get
820 if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
821 {
822 WORD wRegister;
823
824 // Read the HW register for the node except NODE_VIRT_MASTERMONO_VOLUME
825 // since this is pure virtual.
826 if (NodeDef != NODE_VIRT_MASTERMONO_VOLUME)
827 {
828 // Get the register and read it.
829 ntStatus = that->AdapterCommon->ReadCodecRegister (
830 that->AdapterCommon->GetNodeReg (NodeDef), &wRegister);
831 if (!NT_SUCCESS (ntStatus))
832 return ntStatus;
833
834 // mask out every unused bit and rotate.
835 if (channel == CHAN_LEFT)
836 {
837 wRegister = (wRegister & (that->AdapterCommon->GetNodeMask (NodeDef)
838 & AC97REG_MASK_LEFT)) >> 8;
839 }
840 else // here goes mono or stereo-right
841 {
842 wRegister &= (that->AdapterCommon->GetNodeMask (NodeDef) &
844 }
845
846 // Oops - NODE_PCBEEP_VOLUME doesn't use bit0. We have to adjust.
847 if (NodeDef == NODE_PCBEEP_VOLUME)
848 wRegister >>= 1;
849
850 // we have to translate the reg to dB.dB value.
851
852 switch (NodeDef)
853 {
854 // for record, we calculate it reverse.
864 *Level = lMinimum + uStep * wRegister;
865 break;
866 default:
867 *Level = lMaximum - uStep * wRegister;
868 break;
869 }
870
871 // For the virtual controls, which are in front of a muxer, there
872 // is no mute control displayed. But we have a HW mute control, so
873 // what we do is enabling this mute when the user moves the slider
874 // down to the bottom and disabling it on every other position.
875 // We will return a PROP_MOST_NEGATIVE value in case the slider
876 // is moved to the bottom.
877 // We do this only for the "mono muxer" since the volume there ranges
878 // from 0 to -46.5dB. The record volumes only have a range from
879 // 0 to +22.5dB and we cannot mute them when the slider is down.
880 if ((NodeDef == NODE_VIRT_MONOOUT_VOLUME1) ||
881 (NodeDef == NODE_VIRT_MONOOUT_VOLUME2))
882 {
883 // read the register again.
884 ntStatus = that->AdapterCommon->ReadCodecRegister (
885 that->AdapterCommon->GetNodeReg (NodeDef), &wRegister);
886 if (!NT_SUCCESS (ntStatus))
887 return ntStatus;
888 // return most negative value in case it is checked.
889 if (wRegister & AC97REG_MASK_MUTE)
891 }
892 }
893 else // This is master mono volume.
894 {
895 // Assume 0dB for master mono volume.
896 *Level = 0;
897 }
898
899 // when we have cache information then return this instead
900 // of the calculated value. if we don't, store the calculated
901 // value.
902 // We do that twice for master because in case we didn't set
903 // the NodeCache yet it will be set then.
904 if ((channel == CHAN_LEFT) || (channel == CHAN_MASTER))
905 {
906 if (that->stNodeCache[NodeDef].bLeftValid)
907 *Level = that->stNodeCache[NodeDef].lLeft;
908 else
909 {
910 that->stNodeCache[NodeDef].lLeft = *Level;
911 that->stNodeCache[NodeDef].bLeftValid = (BYTE)-1;
912 }
913 }
914
915 if ((channel == CHAN_RIGHT) || (channel == CHAN_MASTER))
916 {
917 if (that->stNodeCache[NodeDef].bRightValid)
918 *Level = that->stNodeCache[NodeDef].lRight;
919 else
920 {
921 that->stNodeCache[NodeDef].lRight = *Level;
922 that->stNodeCache[NodeDef].bRightValid = (BYTE)-1;
923 }
924 }
925
926 // thats all, good bye.
927 PropertyRequest->ValueSize = sizeof(LONG);
928 DOUT (DBG_PROPERTY, ("GET: %s(%s) = 0x%x",NodeStrings[NodeDef],
929 channel==CHAN_LEFT ? "L" : "R", *Level));
930
931 // ntStatus was set with the read call! whatever this is, return it.
932 }
933 else // this must be a set
934 {
935 WORD wRegister;
936 LONG lLevel = *Level;
937
938 //
939 // Check borders.
940 //
941 // These 2 lines will have a special effect on sndvol32.
942 // Whenever you move the balance slider on a volume, one channel
943 // keeps the same and the other volume channel gets descreased.
944 // With ac97 on recording controls, the default slider position
945 // is at 0dB and the range of the volume is 0dB till +22.5dB.
946 // That means that panning (moving the balance slider) is simply
947 // impossible. If you would store the volume like sndvol gives it
948 // to you and you return it on a get, then the balance slider
949 // moves and stays at the position the user wanted it. However,
950 // if you return the actual volume the balance slider will jump
951 // back to the position that the HW can do (play with it to see
952 // how it works).
953 //
954 if (lLevel > lMaximum) lLevel = lMaximum;
955 if (lLevel < lMinimum) lLevel = lMinimum;
956
957 // First update the node cache.
958 if ((channel == CHAN_LEFT) || (channel == CHAN_MASTER))
959 {
960 that->stNodeCache[NodeDef].bLeftValid = (BYTE)-1;
961 that->stNodeCache[NodeDef].lLeft = lLevel;
962 }
963 if ((channel == CHAN_RIGHT) || (channel == CHAN_MASTER))
964 {
965 that->stNodeCache[NodeDef].bRightValid = (BYTE)-1;
966 that->stNodeCache[NodeDef].lRight = lLevel;
967 }
968
969 //
970 // If we have a master mono, then we have to program the speaker
971 // volumes a little different.
972 // Check for master mono (surround or headphone present) and
973 // if one of the speaker volumes is requested.
974 //
975 if ((that->AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT) ||
976 that->AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT)) &&
977 ((NodeDef == NODE_VIRT_MASTERMONO_VOLUME) || (NodeDef == NODE_LFE_VOLUME) ||
978 (NodeDef == NODE_CENTER_VOLUME) || (NodeDef == NODE_FRONT_VOLUME) ||
979 (NodeDef == NODE_SURROUND_VOLUME) || (NodeDef == NODE_HPOUT_VOLUME)))
980 {
981 //
982 // For master mono we have to update all speaker volumes.
983 //
984 if (NodeDef == NODE_VIRT_MASTERMONO_VOLUME)
985 {
986 // Update all speaker volumes.
987 ntStatus = SetMultichannelVolume (that, NODE_FRONT_VOLUME);
988 if (that->AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
989 ntStatus = SetMultichannelVolume (that, NODE_HPOUT_VOLUME);
990 if (that->AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT))
992 if (that->AdapterCommon->GetPinConfig (PINC_CENTER_LFE_PRESENT))
993 {
994 ntStatus = SetMultichannelVolume (that, NODE_CENTER_VOLUME);
995 ntStatus = SetMultichannelVolume (that, NODE_LFE_VOLUME);
996 }
997 }
998 else // update the individual speaker volume only.
999 {
1000 ntStatus = SetMultichannelVolume (that, NodeDef);
1001 }
1002 }
1003 else // This is for all other volumes (or no master mono present).
1004 {
1005 // calculate the dB.dB value.
1006
1007 // The nodes are calculated differently.
1008 switch (NodeDef)
1009 {
1010 // for record controls we calculate it 'reverse'.
1019 // read the wavein selector.
1020 ntStatus = that->AdapterCommon->ReadCodecRegister (
1021 that->AdapterCommon->GetNodeReg (NODE_WAVEIN_SELECT),
1022 &wRegister);
1023 if (!NT_SUCCESS (ntStatus))
1024 return ntStatus;
1025
1026 // mask out every unused bit.
1027 wRegister &= (that->AdapterCommon->GetNodeMask (
1029
1030 // check if the volume that we change belongs to the active
1031 // (selected) virtual channel.
1032 // Tricky: If the virtual nodes are not defined consecutively
1033 // this comparision will fail.
1034 if ((NodeDef - NODE_VIRT_MASTER_INPUT_VOLUME1) != wRegister)
1035 return ntStatus;
1036
1037 // fall through for calculation.
1038
1039 case NODE_MICIN_VOLUME:
1040 wRegister = (WORD)(((lLevel + uStep / 2) - lMinimum) / uStep);
1041 break;
1042
1045 // read the monoout selector.
1046 ntStatus = that->AdapterCommon->ReadCodecRegister (
1047 that->AdapterCommon->GetNodeReg (NODE_MONOOUT_SELECT),
1048 &wRegister);
1049 if (!NT_SUCCESS (ntStatus))
1050 return ntStatus;
1051
1052 // mask out every unused bit.
1053 wRegister &= that->AdapterCommon->GetNodeMask (NODE_MONOOUT_SELECT);
1054
1055 // check if the volume that we change belongs to the active
1056 // (selected) virtual channel.
1057 // Note: Monout select is set if we want to prg. MIC (Volume2).
1058 if ((!wRegister && (NodeDef == NODE_VIRT_MONOOUT_VOLUME2)) ||
1059 (wRegister && (NodeDef == NODE_VIRT_MONOOUT_VOLUME1)))
1060 return ntStatus;
1061
1062 // fall through for calculation.
1063 default:
1064 wRegister = (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep);
1065 break;
1066 }
1067
1068 // Oops - NODE_PCBEEP_VOLUME doesn't use bit0. We have to adjust.
1069 if (NodeDef == NODE_PCBEEP_VOLUME)
1070 wRegister <<= 1;
1071
1072 // write the stuff (with mask!).
1073 // Note: mono channels are 'master' here (see fake above).
1074 // this makes sure that left and right channel is prg. for the virt.
1075 // controls. On controls that only have the right channel, the left
1076 // channel programming does nothing cause the mask will be zero.
1077 if ((channel == CHAN_LEFT) || (channel == CHAN_MASTER))
1078 {
1079 // write only left.
1080 ntStatus = that->AdapterCommon->WriteCodecRegister (
1081 that->AdapterCommon->GetNodeReg (NodeDef),
1082 wRegister << 8,
1083 that->AdapterCommon->GetNodeMask (NodeDef) & AC97REG_MASK_LEFT);
1084 // immediately return on error
1085 if (!NT_SUCCESS (ntStatus))
1086 return ntStatus;
1087 }
1088
1089 if ((channel == CHAN_RIGHT) || (channel == CHAN_MASTER))
1090 {
1091 // write only right.
1092 ntStatus = that->AdapterCommon->WriteCodecRegister (
1093 that->AdapterCommon->GetNodeReg (NodeDef),
1094 wRegister,
1095 that->AdapterCommon->GetNodeMask (NodeDef) & AC97REG_MASK_RIGHT);
1096 // immediately return on error
1097 if (!NT_SUCCESS (ntStatus))
1098 return ntStatus;
1099 }
1100
1101 // For the virtual controls, which are in front of a muxer, there
1102 // is no mute control displayed. But we have a HW mute control, so
1103 // what we do is enabling this mute when the user moves the slider
1104 // down to the bottom and disabling it on every other position.
1105 // We do this only for the "mono muxer", the recording mutes will
1106 // never be muted.
1107 // Tricky: Master input virtual controls must be defined consecutively.
1108 if ((NodeDef >= NODE_VIRT_MASTER_INPUT_VOLUME1) &&
1109 (NodeDef <= NODE_VIRT_MASTER_INPUT_VOLUME8))
1110 {
1111 // disable the mute; this only works because the mute and volume
1112 // share the same register.
1113 ntStatus = that->AdapterCommon->WriteCodecRegister (
1114 that->AdapterCommon->GetNodeReg (NodeDef),
1116
1117 // Just in case.
1118 that->UpdateRecordMute ();
1119 }
1120
1121 if ((NodeDef == NODE_VIRT_MONOOUT_VOLUME1) ||
1122 (NodeDef == NODE_VIRT_MONOOUT_VOLUME2))
1123 {
1124 // these are only mono controls so checking one entry is enough.
1125 if ( that->stNodeCache[NodeDef].bLeftValid &&
1126 (that->stNodeCache[NodeDef].lLeft <= lMinimum))
1127 {
1128 // set the mute; this only works because the mute and volume
1129 // share the same register.
1130 ntStatus = that->AdapterCommon->WriteCodecRegister (
1131 that->AdapterCommon->GetNodeReg (NodeDef),
1133 }
1134 else
1135 {
1136 // clear the mute; this only works because the mute and volume
1137 // share the same register.
1138 ntStatus = that->AdapterCommon->WriteCodecRegister (
1139 that->AdapterCommon->GetNodeReg (NodeDef),
1141 }
1142 }
1143 }
1144
1145 DOUT (DBG_PROPERTY, ("SET: %s(%s) -> 0x%x", NodeStrings[NodeDef],
1146 channel==CHAN_LEFT ? "L" : channel==CHAN_RIGHT ? "R" : "M",
1147 *Level));
1148
1149 // ntStatus was set with the read call! whatever this is, return it.
1150 }
1151 }
1152 else
1153 {
1154 if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
1155 {
1156 ntStatus = BasicSupportHandler (PropertyRequest);
1157 }
1158 }
1159
1160 return ntStatus;
1161}
tNodeCache stNodeCache[NODE_TOP_ELEMENT]
Definition: mintopo.h:106
static NTSTATUS BasicSupportHandler(IN PPCPROPERTY_REQUEST PropertyRequest)
Definition: prophnd.cpp:580
static NTSTATUS SetMultichannelVolume(IN CAC97MiniportTopology *that, IN TopoNodes Volume)
Definition: prophnd.cpp:77
void UpdateRecordMute(void)
Definition: mintopo.cpp:2053
#define CHAN_MASTER
Definition: interfaces.hpp:68
#define CHAN_RIGHT
Definition: interfaces.hpp:67
#define CHAN_LEFT
Definition: interfaces.hpp:66
@ KSPROPERTY_AUDIO_VOLUMELEVEL
Definition: ksmedia.h:1057
const WORD AC97REG_MASK_RIGHT
Definition: mintopo.h:49
const WORD AC97REG_MASK_MUTE
Definition: mintopo.h:50
const WORD AC97REG_MASK_LEFT
Definition: mintopo.h:48
const long PROP_MOST_NEGATIVE
Definition: mintopo.h:56
LONG lMinimum
Definition: mmsystem.h:0
LONG lMaximum
Definition: mmsystem.h:1
BYTE bLeftValid
Definition: mintopo.h:77
BYTE bRightValid
Definition: mintopo.h:78
long lLeft
Definition: mintopo.h:75
long lRight
Definition: mintopo.h:76
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56
unsigned char BYTE
Definition: xxhash.c:193

◆ PropertyHandler_OnOff()

NTSTATUS CAC97MiniportTopology::PropertyHandler_OnOff ( IN PPCPROPERTY_REQUEST  PropertyRequest)
static

Definition at line 333 of file prophnd.cpp.

337{
338 PAGED_CODE ();
339
340 ASSERT (PropertyRequest);
341
343 LONG channel;
344 TopoNodes NodeDef;
345 // The major target is the object pointer to the topology miniport.
347 (CAC97MiniportTopology *) PropertyRequest->MajorTarget;
348
349 ASSERT (that);
350
351 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::PropertyHandler_OnOff]"));
352
353 // validate node
354 if (PropertyRequest->Node == (ULONG)-1)
355 return ntStatus;
356
357 // do the appropriate action for the request.
358
359 // we should do a get or a set?
360 if ((PropertyRequest->Verb & KSPROPERTY_TYPE_GET) ||
361 (PropertyRequest->Verb & KSPROPERTY_TYPE_SET))
362 {
363 // validate parameters
364 if ((PropertyRequest->InstanceSize < sizeof(LONG)) ||
365 (PropertyRequest->ValueSize < sizeof(BOOL)))
366 return ntStatus;
367
368 // get channel
369 channel = *(PLONG)PropertyRequest->Instance;
370
371 // check channel types, return when unknown
372 // as you can see, we have no multichannel support.
373 if ((channel != CHAN_LEFT) &&
374 (channel != CHAN_RIGHT) &&
375 (channel != CHAN_MASTER))
376 return ntStatus;
377
378 // We have only mono mutes or On/Off checkboxes although they might control
379 // a stereo path. For example, we have a 1-bit mute for CD Volume. This
380 // mute controls both CD Volume channels.
381 if (channel == CHAN_RIGHT)
382 return ntStatus;
383
384 // get the buffer
385 PBOOL OnOff = (PBOOL)PropertyRequest->Value;
386
387 // Switch on the node id. This is just for parameter checking.
388 // If something goes wrong, we will immediately return with
389 // ntStatus, which is STATUS_INVALID_PARAMETER.
390 switch (NodeDef = that->TransNodeNrToNodeDef (PropertyRequest->Node))
391 {
392 // These are mutes for mono volumes.
393 case NODE_PCBEEP_MUTE:
394 case NODE_PHONE_MUTE:
395 case NODE_MIC_MUTE:
396 case NODE_MICIN_MUTE:
397 case NODE_CENTER_MUTE:
398 case NODE_LFE_MUTE:
400 // check type
401 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_MUTE)
402 return ntStatus;
403 break;
404
405 // Well, this one is a AGC, although there is no _automatic_ gain
406 // control, but we have a mic boost (which is some kind of manual
407 // gain control).
408 // The 3D Bypass is a real fake, but that's how you get check boxes
409 // on the advanced control panel.
410 // Both controls are in a mono path.
412 case NODE_MIC_BOOST:
413 // check type
414 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_AGC)
415 return ntStatus;
416 break;
417
418 // Simulated Stereo is a AGC control in a stereo path.
420 // check type
421 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_AGC)
422 return ntStatus;
423 break;
424
425 // This is a loudness control in a stereo path. We have to check the
426 // type.
427 case NODE_LOUDNESS:
428 // check type
429 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_LOUDNESS)
430 return ntStatus;
431 break;
432
433 // For 3D Enable and Mic are exposed as loudness in a mono path.
435 case NODE_MIC_SELECT:
436 // check type
437 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_LOUDNESS)
438 return ntStatus;
439 break;
440
441 // These are mutes in a stereo path.
442 // Because the HW has only one mute-bit for the stereo channel, we
443 // expose the mute as mono. this works in current OS and hopefully
444 // will work in future OS.
446 case NODE_LINEIN_MUTE:
447 case NODE_CD_MUTE:
448 case NODE_VIDEO_MUTE:
449 case NODE_AUX_MUTE:
451 case NODE_FRONT_MUTE:
453 case NODE_HPOUT_MUTE:
454 // just check the type.
455 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_MUTE)
456 return ntStatus;
457 break;
458
459 case NODE_INVALID:
460 default:
461 // Ooops.
462 DOUT (DBG_ERROR, ("PropertyHandler_OnOff: Invalid node requested."));
463 return ntStatus;
464 }
465
466 // Now, do some action!
467
468 if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
469 {
470 WORD wRegister;
471
472 // Read the HW register for the node except NODE_VIRT_MASTERMONO_MUTE,
473 // since this is pure virtual.
474 if (NodeDef != NODE_VIRT_MASTERMONO_MUTE)
475 {
476 // get the register and read it.
477 ntStatus = that->AdapterCommon->ReadCodecRegister (
478 that->AdapterCommon->GetNodeReg (NodeDef), &wRegister);
479 if (!NT_SUCCESS (ntStatus))
480 return ntStatus;
481 // Mask out every unused bit.
482 wRegister &= that->AdapterCommon->GetNodeMask (NodeDef);
483 // Store the value.
484 *OnOff = wRegister ? TRUE : FALSE;
485 }
486 else
487 {
488 // Assume no mute for master mono.
489 *OnOff = FALSE;
490 }
491
492 // When we have cache information then return this instead of the
493 // calculated value. If we don't, store the calculated value.
494 if (that->stNodeCache[NodeDef].bLeftValid)
495 *OnOff = that->stNodeCache[NodeDef].lLeft;
496 else
497 {
498 that->stNodeCache[NodeDef].lLeft = *OnOff;
499 that->stNodeCache[NodeDef].bLeftValid = (BYTE)-1;
500 }
501
502 PropertyRequest->ValueSize = sizeof(BOOL);
503 DOUT (DBG_PROPERTY, ("GET: %s = 0x%x", NodeStrings[NodeDef], *OnOff));
504
505 // Set the return code here.
506 ntStatus = STATUS_SUCCESS;
507 }
508 else // this must be a set.
509 {
510 // First update the node cache.
511 that->stNodeCache[NodeDef].bLeftValid = (BYTE)-1;
512 that->stNodeCache[NodeDef].lLeft = (*OnOff) ? TRUE : FALSE;
513
514 //
515 // If we have a master mono, then we have to program the speaker
516 // mutes a little different.
517 // Check for master mono (surround or headphone present) and
518 // if one of the speaker mutes is requested.
519 //
520 if ((that->AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT) ||
521 that->AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT)) &&
522 ((NodeDef == NODE_VIRT_MASTERMONO_MUTE) || (NodeDef == NODE_LFE_MUTE) ||
523 (NodeDef == NODE_CENTER_MUTE) || (NodeDef == NODE_FRONT_MUTE) ||
524 (NodeDef == NODE_SURROUND_MUTE) || (NodeDef == NODE_HPOUT_MUTE)))
525 {
526 //
527 // For master mono we have to update all speakers.
528 //
529 if (NodeDef == NODE_VIRT_MASTERMONO_MUTE)
530 {
531 // Update all speaker mutes.
532 ntStatus = SetMultichannelMute (that, NODE_FRONT_MUTE);
533 if (that->AdapterCommon->GetPinConfig (PINC_HPOUT_PRESENT))
534 ntStatus = SetMultichannelMute (that, NODE_HPOUT_MUTE);
535 if (that->AdapterCommon->GetPinConfig (PINC_SURROUND_PRESENT))
536 ntStatus = SetMultichannelMute (that, NODE_SURROUND_MUTE);
537 if (that->AdapterCommon->GetPinConfig (PINC_CENTER_LFE_PRESENT))
538 {
539 ntStatus = SetMultichannelMute (that, NODE_CENTER_MUTE);
540 ntStatus = SetMultichannelMute (that, NODE_LFE_MUTE);
541 }
542 }
543 else // Update the individual speaker mute.
544 {
545 ntStatus = SetMultichannelMute (that, NodeDef);
546 }
547 }
548 else
549 {
550 //
551 // For all other mutes/checkboxes just write the value to the HW.
552 //
553 ntStatus = that->AdapterCommon->WriteCodecRegister (
554 that->AdapterCommon->GetNodeReg (NodeDef),
555 (*OnOff) ? -1 : 0,
556 that->AdapterCommon->GetNodeMask (NodeDef));
557 }
558
559 DOUT (DBG_PROPERTY, ("SET: %s -> 0x%x", NodeStrings[NodeDef], *OnOff));
560
561 // ntStatus was set with the write call! whatever this is, return it.
562 }
563 }
564
565 return ntStatus;
566}
static NTSTATUS SetMultichannelMute(IN CAC97MiniportTopology *that, IN TopoNodes Mute)
Definition: prophnd.cpp:36
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
switch(r->id)
Definition: btrfs.c:3046
unsigned int BOOL
Definition: ntddk_ex.h:94
@ KSPROPERTY_AUDIO_MUTE
Definition: ksmedia.h:1066
@ KSPROPERTY_AUDIO_AGC
Definition: ksmedia.h:1074
@ KSPROPERTY_AUDIO_LOUDNESS
Definition: ksmedia.h:1076
if(dx< 0)
Definition: linetemp.h:194
#define BOOL
Definition: nt_native.h:43
BOOL * PBOOL
Definition: windef.h:161

◆ PropertyHandler_Tone()

NTSTATUS CAC97MiniportTopology::PropertyHandler_Tone ( IN PPCPROPERTY_REQUEST  PropertyRequest)
static

Definition at line 1175 of file prophnd.cpp.

1179{
1180 PAGED_CODE ();
1181
1182 ASSERT (PropertyRequest);
1183
1184 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::PropertyHandler_Tone]"));
1185
1187 TopoNodes NodeDef;
1189 ULONG uStep;
1190 // The major target is the object pointer to the topology miniport.
1191 CAC97MiniportTopology *that =
1192 (CAC97MiniportTopology *) PropertyRequest->MajorTarget;
1193
1194 ASSERT (that);
1195
1196 // validate node
1197 if (PropertyRequest->Node == (ULONG)-1)
1198 return ntStatus;
1199
1200 // do the appropriate action for the request.
1201
1202 // we should do a get or a set?
1203 if ((PropertyRequest->Verb & KSPROPERTY_TYPE_GET) ||
1204 (PropertyRequest->Verb & KSPROPERTY_TYPE_SET))
1205 {
1206 // validate parameters
1207 if ((PropertyRequest->InstanceSize < sizeof(LONG)) ||
1208 (PropertyRequest->ValueSize < sizeof(LONG)))
1209 return ntStatus;
1210
1211 // get the buffer
1212 PLONG Level = (PLONG)PropertyRequest->Value;
1213
1214 // Switch on the node id. This is just for parameter checking.
1215 // If something goes wrong, we will immideately return with
1216 // ntStatus, which is STATUS_INVALID_PARAMETER.
1217 switch(NodeDef = that->TransNodeNrToNodeDef (PropertyRequest->Node))
1218 {
1219 case NODE_BASS:
1220 // check type.
1221 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_BASS)
1222 return ntStatus;
1223 break;
1224
1225 case NODE_TREBLE:
1226 // check type.
1227 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_TREBLE)
1228 return ntStatus;
1229 break;
1230
1232 case NODE_VIRT_3D_DEPTH:
1233 // check 3D control
1234 if (!that->AdapterCommon->GetNodeConfig (NODEC_3D_CENTER_ADJUSTABLE)
1235 && (NodeDef == NODE_VIRT_3D_CENTER))
1236 return ntStatus;
1237 if (!that->AdapterCommon->GetNodeConfig (NODEC_3D_DEPTH_ADJUSTABLE)
1238 && (NodeDef == NODE_VIRT_3D_DEPTH))
1239 return ntStatus;
1240 // check type
1241 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_VOLUMELEVEL)
1242 return ntStatus;
1243 // check channel
1244 if (*(PLONG(PropertyRequest->Instance)) == CHAN_RIGHT)
1245 return ntStatus;
1246 break;
1247
1248 case NODE_INVALID:
1249 default:
1250 // Ooops
1251 DOUT (DBG_ERROR, ("PropertyHandler_Tone: Invalid node requested."));
1252 return ntStatus;
1253 }
1254
1255 // Now, do some action!
1256
1257 // get the registered DB values
1258 ntStatus = GetDBValues (that->AdapterCommon, NodeDef, &lMinimum,
1259 &lMaximum, &uStep);
1260 if (!NT_SUCCESS (ntStatus))
1261 return ntStatus;
1262
1263 // do a get
1264 if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
1265 {
1266 WORD wRegister;
1267
1268 // first get the stuff.
1269 ntStatus = that->AdapterCommon->ReadCodecRegister (
1270 that->AdapterCommon->GetNodeReg (NodeDef), &wRegister);
1271 if (!NT_SUCCESS (ntStatus))
1272 return ntStatus;
1273
1274 // mask out every unused bit.
1275 wRegister &= that->AdapterCommon->GetNodeMask (NodeDef);
1276
1277 // rotate if bass tone control or 3D center control
1278 if ((NodeDef == NODE_BASS) || (NodeDef == NODE_VIRT_3D_CENTER))
1279 wRegister >>= 8;
1280
1281 // convert from reg to dB.dB value.
1282 if ((NodeDef == NODE_VIRT_3D_CENTER) ||
1283 (NodeDef == NODE_VIRT_3D_DEPTH))
1284 {
1285 // That's for the 3D controls
1286 *Level = lMinimum + uStep * wRegister;
1287 }
1288 else
1289 {
1290 if (wRegister == 0x000F)
1291 *Level = 0; // bypass
1292 else
1293 // And that's for the tone controls
1294 *Level = lMaximum - uStep * wRegister;
1295 }
1296
1297 // when we have cache information then return this instead
1298 // of the calculated value. if we don't, store the calculated
1299 // value.
1300 if (that->stNodeCache[NodeDef].bLeftValid)
1301 *Level = that->stNodeCache[NodeDef].lLeft;
1302 else
1303 {
1304 that->stNodeCache[NodeDef].lLeft = *Level;
1305 that->stNodeCache[NodeDef].bLeftValid = (BYTE)-1;
1306 }
1307
1308 // we return a LONG
1309 PropertyRequest->ValueSize = sizeof(LONG);
1310 DOUT (DBG_PROPERTY, ("GET: %s = 0x%x", NodeStrings[NodeDef], *Level));
1311 // ntStatus was set with the read call! whatever this is, return it.
1312 }
1313 else // that must be a set
1314 {
1315 WORD wRegister;
1316 LONG lLevel = *Level;
1317
1318 // calculate the dB.dB value.
1319 // check borders.
1320 if (lLevel > lMaximum) lLevel = lMaximum;
1321 if (lLevel < lMinimum) lLevel = lMinimum;
1322
1323 // write the value to the node cache.
1324 that->stNodeCache[NodeDef].lLeft = *Level;
1325 that->stNodeCache[NodeDef].bLeftValid = (BYTE)-1;
1326
1327 // convert from dB.dB value to reg.
1328 if ((NodeDef == NODE_VIRT_3D_CENTER) ||
1329 (NodeDef == NODE_VIRT_3D_DEPTH))
1330 {
1331 // For 3D controls
1332 wRegister = (WORD)(((lLevel + uStep / 2) - lMinimum) / uStep);
1333 }
1334 else
1335 {
1336 // For tone controls
1337 wRegister = (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep);
1338 // We don't prg. 0dB Bass or 0dB Treble, instead we smartly prg.
1339 // a bypass which is reg. value 0x0F.
1340 if (wRegister == 7) // 0 dB
1341 wRegister = 0x000F; // bypass
1342 }
1343
1344 // rotate if bass tone control or 3D center control
1345 if ((NodeDef == NODE_BASS) || (NodeDef == NODE_VIRT_3D_CENTER))
1346 wRegister <<= 8;
1347
1348 // write the stuff.
1349 ntStatus = that->AdapterCommon->WriteCodecRegister (
1350 that->AdapterCommon->GetNodeReg (NodeDef),
1351 wRegister,
1352 that->AdapterCommon->GetNodeMask (NodeDef));
1353
1354 DOUT (DBG_PROPERTY,("SET: %s -> 0x%x", NodeStrings[NodeDef], *Level));
1355 // ntStatus was set with the write call! whatever this is, return in.
1356 }
1357 }
1358 else
1359 {
1360 if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
1361 {
1362 ntStatus = BasicSupportHandler (PropertyRequest);
1363 }
1364 }
1365
1366 return ntStatus;
1367}
@ KSPROPERTY_AUDIO_BASS
Definition: ksmedia.h:1067
@ KSPROPERTY_AUDIO_TREBLE
Definition: ksmedia.h:1069

◆ PropertyHandler_Ulong()

NTSTATUS CAC97MiniportTopology::PropertyHandler_Ulong ( IN PPCPROPERTY_REQUEST  PropertyRequest)
static

Definition at line 1379 of file prophnd.cpp.

1383{
1384 PAGED_CODE ();
1385
1386 ASSERT (PropertyRequest);
1387
1388 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::PropertyHandler_Ulong]"));
1389
1391 TopoNodes NodeDef;
1393 ULONG uStep;
1394 // The major target is the object pointer to the topology miniport.
1395 CAC97MiniportTopology *that =
1396 (CAC97MiniportTopology *) PropertyRequest->MajorTarget;
1397
1398 ASSERT (that);
1399
1400
1401 // validate node instance
1402 if (PropertyRequest->Node == (ULONG)-1)
1403 return ntStatus;
1404
1405 // if we should do a get or set.
1406 if ((PropertyRequest->Verb & KSPROPERTY_TYPE_GET) ||
1407 (PropertyRequest->Verb & KSPROPERTY_TYPE_SET))
1408 {
1409 // validate buffer size.
1410 if (PropertyRequest->ValueSize < sizeof(ULONG))
1411 return ntStatus;
1412
1413 // get the pointer to the buffer.
1414 PULONG PropValue = (PULONG)PropertyRequest->Value;
1415
1416 // Switch on the node id. This is just for parameter checking.
1417 // If something goes wrong, we will immideately return with
1418 // ntStatus, which is STATUS_INVALID_PARAMETER.
1419 switch(NodeDef = that->TransNodeNrToNodeDef (PropertyRequest->Node))
1420 {
1422 case NODE_WAVEIN_SELECT:
1423 // check the type
1424 if (PropertyRequest->PropertyItem->Id != KSPROPERTY_AUDIO_MUX_SOURCE)
1425 return ntStatus;
1426 break;
1427
1428 case NODE_INVALID:
1429 default:
1430 // Ooops
1431 DOUT (DBG_ERROR, ("PropertyHandler_Tone: Invalid node requested."));
1432 return ntStatus;
1433 }
1434
1435 // Now do some action!
1436
1437 // should we return the value?
1438 if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
1439 {
1440 WORD wRegister;
1441
1442 // first get the stuff.
1443 ntStatus = that->AdapterCommon->ReadCodecRegister (
1444 that->AdapterCommon->GetNodeReg (NodeDef), &wRegister);
1445 if (!NT_SUCCESS (ntStatus))
1446 return ntStatus;
1447
1448 // mask out every unused bit.
1449 wRegister &= that->AdapterCommon->GetNodeMask (NodeDef);
1450
1451 // calculate the selected pin
1452 if (NodeDef == NODE_MONOOUT_SELECT)
1453 {
1454 // for mono out we have just one bit
1455 if (wRegister)
1456 *PropValue = 2;
1457 else
1458 *PropValue = 1;
1459 }
1460 else
1461 {
1462 // the wave in muxer is a stereo muxer, so just return the
1463 // right channel (gives values 0-7) and adjust it by adding 1.
1464 *PropValue = (wRegister & AC97REG_MASK_RIGHT) + 1;
1465 }
1466
1467 // we return a LONG
1468 PropertyRequest->ValueSize = sizeof(LONG);
1469 DOUT (DBG_PROPERTY, ("GET: %s = 0x%x", NodeStrings[NodeDef],
1470 *PropValue));
1471 // ntStatus was set with the read call! whatever this is, return it.
1472 }
1473 else // that must be a set
1474 {
1475 TopoNodes VirtNode;
1476 WORD wRegister;
1477 ULONG ulSelect = *PropValue;
1478 LONG lLevel;
1479
1480 // Check the selection first.
1481 if (NodeDef == NODE_MONOOUT_SELECT)
1482 {
1483 if ((ulSelect < 1) || (ulSelect > 2))
1484 return ntStatus; // STATUS_INVALID_PARAMETER
1485 }
1486 else
1487 {
1488 if ((ulSelect < 1) || (ulSelect > 8))
1489 return ntStatus; // STATUS_INVALID_PARAMETER
1490 }
1491
1492 // calculate the register value for programming.
1493 if (NodeDef == NODE_MONOOUT_SELECT)
1494 {
1495 // for mono out we have just one bit
1496 if (ulSelect == 2)
1497 // the mask will make sure we only prg. one bit.
1498 wRegister = 0xFFFF;
1499 else
1500 // ulSelect == 1
1501 wRegister = 0;
1502 }
1503 else
1504 {
1505 // *257 is the same as: (ulSelect << 8) + ulSelect
1506 wRegister = (WORD)(ulSelect - 1) * 257;
1507 }
1508
1509 // write the stuff.
1510 ntStatus = that->AdapterCommon->WriteCodecRegister (
1511 that->AdapterCommon->GetNodeReg (NodeDef),
1512 wRegister,
1513 that->AdapterCommon->GetNodeMask (NodeDef));
1514
1515 // Store the virt. node for later use.
1516 // Tricky: Master input virtual controls must be defined consecutively.
1517 if (NodeDef == NODE_MONOOUT_SELECT)
1518 VirtNode = (TopoNodes)(NODE_VIRT_MONOOUT_VOLUME1 + (ulSelect - 1));
1519 else
1520 VirtNode = (TopoNodes)(NODE_VIRT_MASTER_INPUT_VOLUME1 + (ulSelect - 1));
1521
1522 // Virtual controls make our life more complicated. When the user
1523 // changes the input source say from CD to LiniIn, then the system just
1524 // sends a message to the input muxer that the selection changed.
1525 // Cause we have only one HW register for the input muxer, all volumes
1526 // displayed for the user are "virtualized", means they are not there,
1527 // and when the selection changes, we have to prg. the volume of the
1528 // selected input to the HW register. That's what we do now.
1529
1530 // get the registered DB values
1531 ntStatus = GetDBValues (that->AdapterCommon, VirtNode,
1532 &lMinimum, &lMaximum, &uStep);
1533 if (!NT_SUCCESS (ntStatus))
1534 return ntStatus;
1535
1536 // We can be lazy here and don't check for mono controls. Reason
1537 // is that the level handler writes the volume value for mono
1538 // controls into both the left and right node cache ;))
1539
1540 if (that->stNodeCache[VirtNode].bLeftValid &&
1541 that->stNodeCache[VirtNode].bRightValid)
1542 {
1543 // prg. left channel
1544 lLevel = that->stNodeCache[VirtNode].lLeft;
1545
1546 // calculate the dB.dB value.
1547 if (NodeDef == NODE_MONOOUT_SELECT)
1548 wRegister = (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep);
1549 else
1550 wRegister = (WORD)(((lLevel + uStep / 2) - lMinimum) / uStep);
1551
1552 // write left channel.
1553 ntStatus = that->AdapterCommon->WriteCodecRegister (
1554 that->AdapterCommon->GetNodeReg (VirtNode),
1555 wRegister << 8,
1556 that->AdapterCommon->GetNodeMask (VirtNode) & AC97REG_MASK_LEFT);
1557
1558 // prg. right channel
1559 lLevel = that->stNodeCache[VirtNode].lRight;
1560
1561 // calculate the dB.dB value.
1562 if (NodeDef == NODE_MONOOUT_SELECT)
1563 wRegister = (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep);
1564 else
1565 wRegister = (WORD)(((lLevel + uStep / 2) - lMinimum) / uStep);
1566
1567 // write right channel.
1568 ntStatus = that->AdapterCommon->WriteCodecRegister (
1569 that->AdapterCommon->GetNodeReg (VirtNode),
1570 wRegister,
1571 that->AdapterCommon->GetNodeMask (VirtNode) & AC97REG_MASK_RIGHT);
1572
1573 // For the virtual controls, which are in front of a muxer, there
1574 // is no mute control displayed. But we have a HW mute control, so
1575 // what we do is enabling this mute when the user moves the slider
1576 // down to the bottom and disabling it on every other position.
1577 // We do this only for the "mono muxer", the recording mutes will
1578 // never be muted.
1579 if (NodeDef == NODE_WAVEIN_SELECT)
1580 {
1581 // disable the mute; this only works because the mute and volume
1582 // share the same register.
1583 ntStatus = that->AdapterCommon->WriteCodecRegister (
1584 that->AdapterCommon->GetNodeReg (VirtNode),
1586
1587 that->UpdateRecordMute ();
1588 }
1589
1590 if (NodeDef == NODE_MONOOUT_SELECT)
1591 {
1592 // these are only mono controls so checking one entry is enough.
1593 if ( that->stNodeCache[VirtNode].bLeftValid &&
1594 (that->stNodeCache[VirtNode].lLeft <= lMinimum))
1595 {
1596 // set the mute; this only works because the mute and volume
1597 // share the same register.
1598 ntStatus = that->AdapterCommon->WriteCodecRegister (
1599 that->AdapterCommon->GetNodeReg (VirtNode),
1601 }
1602 else
1603 {
1604 // clear the mute; this only works because the mute and volume
1605 // share the same register.
1606 ntStatus = that->AdapterCommon->WriteCodecRegister (
1607 that->AdapterCommon->GetNodeReg (VirtNode),
1609 }
1610 }
1611 }
1612
1613 DOUT (DBG_PROPERTY, ("SET: %s -> 0x%x", NodeStrings[NodeDef],
1614 *PropValue));
1615 // ntStatus was set with the write call! whatever this is, return it.
1616 }
1617 }
1618
1619 return ntStatus;
1620}
@ KSPROPERTY_AUDIO_MUX_SOURCE
Definition: ksmedia.h:1065

◆ SetMultichannelMute()

NTSTATUS CAC97MiniportTopology::SetMultichannelMute ( IN CAC97MiniportTopology that,
IN TopoNodes  Mute 
)
static

Definition at line 35 of file prophnd.cpp.

40{
41 PAGED_CODE();
42
43 NTSTATUS ntStatus = STATUS_SUCCESS;
44 BOOL bMute;
45
46 // The first calls to SetMultichannelMute could be without valid
47 // cache information because WDMAUD might currently query the nodes
48 // (this is at system startup). When WDMAUD queried all nodes then
49 // all cache information will be valid.
50 if (that->stNodeCache[NODE_VIRT_MASTERMONO_MUTE].bLeftValid &&
51 that->stNodeCache[Mute].bLeftValid)
52 {
53 // We get the master mono mute and the mute that is to change.
54 // Then we "or" them and write the value to the register.
55 bMute = that->stNodeCache[NODE_VIRT_MASTERMONO_MUTE].lLeft ||
56 that->stNodeCache[Mute].lLeft;
57
58 ntStatus = that->AdapterCommon->WriteCodecRegister (
59 that->AdapterCommon->GetNodeReg (Mute),
60 bMute ? -1 : 0,
61 that->AdapterCommon->GetNodeMask (Mute));
62
63 DOUT (DBG_PROPERTY, ("SET: %s -> 0x%x", NodeStrings[Mute], (int)bMute));
64 }
65
66 return ntStatus;
67}

Referenced by PropertyHandler_OnOff().

◆ SetMultichannelVolume()

NTSTATUS CAC97MiniportTopology::SetMultichannelVolume ( IN CAC97MiniportTopology that,
IN TopoNodes  Volume 
)
static

Definition at line 76 of file prophnd.cpp.

81{
82 PAGED_CODE();
83
84 NTSTATUS ntStatus = STATUS_SUCCESS;
86 ULONG uStep;
87 LONG lLevel;
88 WORD wRegister;
89
90 // The first calls to SetMultichannelMute could be without valid
91 // cache information because WDMAUD might currently query the nodes
92 // (this is at system startup). When WDMAUD queried all nodes then
93 // all cache information will be valid.
94 if (that->stNodeCache[NODE_VIRT_MASTERMONO_VOLUME].bLeftValid &&
95 that->stNodeCache[NODE_VIRT_MASTERMONO_VOLUME].bRightValid &&
96 that->stNodeCache[Volume].bLeftValid &&
97 that->stNodeCache[Volume].bRightValid)
98 {
99 // We get the master mono volume and the volume that is to change.
100 // Then we substract master mono from it and write the value to the
101 // register.
102 lLevel = that->stNodeCache[Volume].lLeft +
103 that->stNodeCache[NODE_VIRT_MASTERMONO_VOLUME].lLeft;
104
105 // Translate the dB value into a register value.
106
107 // Get the registered DB values
108 ntStatus = GetDBValues (that->AdapterCommon, Volume,
109 &lMinimum, &lMaximum, &uStep);
110 if (!NT_SUCCESS(ntStatus))
111 return ntStatus;
112
113 // Check borders.
114 if (lLevel < lMinimum) lLevel = lMinimum;
115 if (lLevel > lMaximum) lLevel = lMaximum;
116
117 // Calculate the register value
118 wRegister = (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep) << 8;
119
120 // Get the right value too.
121 lLevel = that->stNodeCache[Volume].lRight +
122 that->stNodeCache[NODE_VIRT_MASTERMONO_VOLUME].lRight;
123
124 // Check borders.
125 if (lLevel < lMinimum) lLevel = lMinimum;
126 if (lLevel > lMaximum) lLevel = lMaximum;
127
128 // Add it to the register value.
129 wRegister += (WORD)(((lMaximum + uStep / 2) - lLevel) / uStep);
130
131 // Write it.
132 ntStatus = that->AdapterCommon->WriteCodecRegister (
133 that->AdapterCommon->GetNodeReg (Volume),
134 wRegister,
135 that->AdapterCommon->GetNodeMask (Volume));
136
137 DOUT (DBG_PROPERTY, ("SET: %s -> 0x%x/0x%x", NodeStrings[Volume],
138 that->stNodeCache[Volume].lLeft +
139 that->stNodeCache[NODE_VIRT_MASTERMONO_VOLUME].lLeft,
140 lLevel));
141 }
142
143 return ntStatus;
144}
UNICODE_STRING Volume
Definition: fltkernel.h:1172

Referenced by PropertyHandler_Level().

◆ SetNodeTranslation()

void CAC97MiniportTopology::SetNodeTranslation ( IN int  NodeNr,
IN TopoNodes  NodeDef 
)
inlineprivate

Definition at line 203 of file mintopo.h.

204 {
205 stNodeTrans[NodeNr].NodeDef = NodeDef;
206 stNodeTrans[NodeDef].NodeNr = NodeNr;
207 };
tNodeTranslationTable stNodeTrans[NODE_TOP_ELEMENT]
Definition: mintopo.h:105
TopoNodes NodeDef
Definition: mintopo.h:37

◆ SetPinTranslation()

void CAC97MiniportTopology::SetPinTranslation ( IN int  PinNr,
IN TopoPins  PinDef 
)
inlineprivate

Definition at line 210 of file mintopo.h.

211 {
212 stPinTrans[PinNr].PinDef = PinDef;
213 stPinTrans[PinDef].PinNr = PinNr;
214 };
tPinTranslationTable stPinTrans[PIN_TOP_ELEMENT]
Definition: mintopo.h:104
TopoPins PinDef
Definition: mintopo.h:28

◆ STDMETHODIMP_() [1/2]

CAC97MiniportTopology::STDMETHODIMP_ ( NTSTATUS  )

◆ STDMETHODIMP_() [2/2]

CAC97MiniportTopology::STDMETHODIMP_ ( void  )
inline

Definition at line 251 of file mintopo.h.

252 {
254 {
257 }
258 };
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52

◆ TransNodeDefToNodeNr()

int CAC97MiniportTopology::TransNodeDefToNodeNr ( IN TopoNodes  Node)
inlineprivate

Definition at line 152 of file mintopo.h.

153 {
154#if (DBG)
155 int n;
156
157 // check for invalid translation. could be caused by a connection
158 // to a not registered node or wrong use of nodes.
160 if (n == -1)
161 DOUT (DBG_ERROR, ("Invalid TopoNode %u.", Node));
162 return n;
163#else
164 return stNodeTrans[Node].NodeNr;
165#endif
166 };
union node Node
Definition: types.h:1255
GLdouble n
Definition: glext.h:7729

◆ TransNodeNrToNodeDef()

TopoNodes CAC97MiniportTopology::TransNodeNrToNodeDef ( IN int  Node)
inlineprivate

Definition at line 135 of file mintopo.h.

136 {
137#if (DBG)
138 TopoNodes n;
139
141 // check for invalid translation. could be caused by a connection
142 // to a not registered node or wrong use of nodes.
143 if (n == NODE_INVALID)
144 DOUT (DBG_ERROR, ("Invalid node nr %u.", Node));
145 return n;
146#else
147 return stNodeTrans[Node].NodeDef;
148#endif
149 };

Referenced by BasicSupportHandler(), PropertyHandler_CpuResources(), PropertyHandler_Level(), PropertyHandler_OnOff(), PropertyHandler_Tone(), and PropertyHandler_Ulong().

◆ TransPinDefToPinNr()

int CAC97MiniportTopology::TransPinDefToPinNr ( IN TopoPins  Pin)
inlineprivate

Definition at line 186 of file mintopo.h.

187 {
188#if (DBG)
189 int p;
190
192 // check for invalid translation. could be caused by a connection
193 // to a not registered pin or wrong use of pins.
194 if (p == -1)
195 DOUT (DBG_ERROR, ("Invalid TopoPin %u.", Pin));
196 return p;
197#else
198 return stPinTrans[Pin].PinNr;
199#endif
200 };
IN PDCB IN VBO IN ULONG IN BOOLEAN Pin
Definition: fatprocs.h:428
GLfloat GLfloat p
Definition: glext.h:8902

◆ TransPinNrToPinDef()

TopoPins CAC97MiniportTopology::TransPinNrToPinDef ( IN int  Pin)
inlineprivate

Definition at line 169 of file mintopo.h.

170 {
171#if (DBG)
172 TopoPins p;
173
175 // check for invalid translation. could be caused by a connection
176 // to a not registered pin or wrong use of pins.
177 if (p == PIN_INVALID)
178 DOUT (DBG_ERROR, ("Invalid pin nr %u.", Pin));
179 return p;
180#else
181 return stPinTrans[Pin].PinDef;
182#endif
183 };
TopoPins
Definition: shared.h:112
@ PIN_INVALID
Definition: shared.h:137

◆ UpdateRecordMute()

void CAC97MiniportTopology::UpdateRecordMute ( void  )
private

Definition at line 2053 of file mintopo.cpp.

2054{
2055 PAGED_CODE ();
2056
2057 WORD wRegister;
2058 //TopoNodes Node;
2059
2060 DOUT (DBG_PRINT, ("[CAC97MiniportTopology::UpdateRecordMute]"));
2061
2062 // Get the record muxer setting.
2063 if (!NT_SUCCESS (AdapterCommon->ReadCodecRegister (
2064 AdapterCommon->GetNodeReg (NODE_WAVEIN_SELECT), &wRegister)))
2065 return;
2066
2067 // Mask out every unused bit.
2068 wRegister &= (AdapterCommon->GetNodeMask (NODE_WAVEIN_SELECT) & AC97REG_MASK_RIGHT);
2069
2070#if 0
2071 // Calculate how we would program the mute.
2072 switch (wRegister)
2073 {
2074 // This is stereo mix.
2075 case 5:
2077 break;
2078
2079 // This is mono mix.
2080 case 6:
2082 break;
2083
2084 // Something else selected than stereo mix or mono mix.
2085 default:
2086 return;
2087 }
2088#endif
2089
2090 // Program the mute.
2091 AdapterCommon->WriteCodecRegister (AC97REG_RECORD_GAIN,
2093}
@ AC97REG_RECORD_GAIN
Definition: ac97reg.h:32

Referenced by PropertyHandler_Level(), PropertyHandler_Ulong(), and STDMETHODIMP_().

Member Data Documentation

◆ AdapterCommon

◆ ConnectionDescriptors

PPCCONNECTION_DESCRIPTOR CAC97MiniportTopology::ConnectionDescriptors
private

Definition at line 102 of file mintopo.h.

Referenced by BuildConnectionDescriptors(), and ~CAC97MiniportTopology().

◆ FilterDescriptor

PPCFILTER_DESCRIPTOR CAC97MiniportTopology::FilterDescriptor
private

◆ IMP_IMiniportTopology

CAC97MiniportTopology::IMP_IMiniportTopology

Definition at line 237 of file mintopo.h.

◆ m_bCopyProtectFlag

BOOL CAC97MiniportTopology::m_bCopyProtectFlag
private

Definition at line 107 of file mintopo.h.

Referenced by STDMETHODIMP_(), and UpdateRecordMute().

◆ MicInDest

OUT PULONG OUT PULONG CAC97MiniportTopology::MicInDest

Definition at line 247 of file mintopo.h.

◆ NodeDescriptors

PPCNODE_DESCRIPTOR CAC97MiniportTopology::NodeDescriptors
private

Definition at line 101 of file mintopo.h.

Referenced by BuildNodeDescriptors(), and ~CAC97MiniportTopology().

◆ PinDescriptors

PPCPIN_DESCRIPTOR CAC97MiniportTopology::PinDescriptors
private

Definition at line 100 of file mintopo.h.

Referenced by BuildPinDescriptors(), and ~CAC97MiniportTopology().

◆ stNodeCache

tNodeCache CAC97MiniportTopology::stNodeCache[NODE_TOP_ELEMENT]
private

◆ stNodeTrans

tNodeTranslationTable CAC97MiniportTopology::stNodeTrans[NODE_TOP_ELEMENT]
private

Definition at line 105 of file mintopo.h.

Referenced by SetNodeTranslation(), TransNodeDefToNodeNr(), and TransNodeNrToNodeDef().

◆ stPinTrans

tPinTranslationTable CAC97MiniportTopology::stPinTrans[PIN_TOP_ELEMENT]
private

Definition at line 104 of file mintopo.h.

Referenced by SetPinTranslation(), TransPinDefToPinNr(), and TransPinNrToPinDef().

◆ WaveInDest

OUT PULONG CAC97MiniportTopology::WaveInDest

Definition at line 246 of file mintopo.h.


The documentation for this class was generated from the following files: