//--------------------------------------------------------------------------- // // Module: mixer.h // // Description: // // Contains the declarations and prototypes for the Kernel Portion // of the mixer line driver (KMXL). // // //@@BEGIN_MSINTERNAL // Development Team: // D. Baumberger // // History: Date Author Comment // //@@END_MSINTERNAL // //--------------------------------------------------------------------------- // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR // PURPOSE. // // Copyright (C) Microsoft Corporation, 1997 - 1999 All Rights Reserved. // //--------------------------------------------------------------------------- #ifndef _MIXER_H_INCLUDED_ #define _MIXER_H_INCLUDED_ //#define API_TRACE //#define PARSE_TRACE #define SUPERMIX_AS_VOL /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // // M I X E R L I N E 1 6 - b i t S T R U C T U R E S // // ( A N S I ) // // // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// #ifdef WIN32 # include #else # ifndef RC_INVOKED # pragma pack(1) # endif #endif typedef struct tagMIXERLINE16 { DWORD cbStruct; /* size of MIXERLINE structure */ DWORD dwDestination; /* zero based destination index */ DWORD dwSource; /* zero based source index (if source) */ DWORD dwLineID; /* unique line id for mixer device */ DWORD fdwLine; /* state/information about line */ DWORD dwUser; /* driver specific information */ DWORD dwComponentType; /* component type line connects to */ DWORD cChannels; /* number of channels line supports */ DWORD cConnections; /* number of connections [possible] */ DWORD cControls; /* number of controls at this line */ CHAR szShortName[MIXER_SHORT_NAME_CHARS]; CHAR szName[MIXER_LONG_NAME_CHARS]; struct { DWORD dwType; /* MIXERLINE_TARGETTYPE_xxxx */ DWORD dwDeviceID; /* target device ID of device type */ WORD wMid; /* of target device */ WORD wPid; /* " */ WORD vDriverVersion; /* " */ CHAR szPname[MAXPNAMELEN]; /* " */ } Target; } MIXERLINE16, *PMIXERLINE16, *LPMIXERLINE16; typedef struct tagMIXERCONTROL16 { DWORD cbStruct; /* size in bytes of MIXERCONTROL */ DWORD dwControlID; /* unique control id for mixer device */ DWORD dwControlType; /* MIXERCONTROL_CONTROLTYPE_xxx */ DWORD fdwControl; /* MIXERCONTROL_CONTROLF_xxx */ DWORD cMultipleItems; /* if MIXERCONTROL_CONTROLF_MULTIPLE set */ CHAR szShortName[MIXER_SHORT_NAME_CHARS]; CHAR szName[MIXER_LONG_NAME_CHARS]; union { struct { LONG lMinimum; /* signed minimum for this control */ LONG lMaximum; /* signed maximum for this control */ }; struct { DWORD dwMinimum; /* unsigned minimum for this control */ DWORD dwMaximum; /* unsigned maximum for this control */ }; DWORD dwReserved[6]; } Bounds; union { DWORD cSteps; /* # of steps between min & max */ DWORD cbCustomData; /* size in bytes of custom data */ DWORD dwReserved[6]; /* !!! needed? we have cbStruct.... */ } Metrics; } MIXERCONTROL16, *PMIXERCONTROL16, *LPMIXERCONTROL16; typedef struct tagMIXERLINECONTROLS16 { DWORD cbStruct; /* size in bytes of MIXERLINECONTROLS */ DWORD dwLineID; /* line id (from MIXERLINE.dwLineID) */ union { DWORD dwControlID; /* MIXER_GETLINECONTROLSF_ONEBYID */ DWORD dwControlType; /* MIXER_GETLINECONTROLSF_ONEBYTYPE */ }; DWORD cControls; /* count of controls pmxctrl points to */ DWORD cbmxctrl; /* size in bytes of _one_ MIXERCONTROL */ LPMIXERCONTROL16 pamxctrl; /* pointer to first MIXERCONTROL array */ } MIXERLINECONTROLS16, *PMIXERLINECONTROLS16, *LPMIXERLINECONTROLS16; typedef struct tagMIXERCONTROLDETAILS_LISTTEXT16 { DWORD dwParam1; DWORD dwParam2; CHAR szName[MIXER_LONG_NAME_CHARS]; } MIXERCONTROLDETAILS_LISTTEXT16, *PMIXERCONTROLDETAILS_LISTTEXT16, *LPMIXERCONTROLDETAILS_LISTTEXT16; #ifdef WIN32 # include #else # ifndef RC_INVOKED # pragma pack() # endif #endif /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // // D E F I N E S // // // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// #define PINID_WILDCARD ( (ULONG) -2 ) #define DESTINATION_LIST ( 0x01 ) #define SOURCE_LIST ( 0x02 ) #define SLIST SINGLE_LIST_ENTRY #define PSLIST SLIST* #define MAX_CHANNELS 0xFFFF //#define MIXERCONTROL_CONTROLTYPE_BASS_BOOST 0x20012277 #define INVALID_ID ( 0xDEADBEEF ) #define TOPOLOGY_DRIVER_NAME L"\\DosDevices\\sysaudio\\MIXER" //#define TOPOLOGY_DRIVER_NAME L"\\DosDevices\\PortClass0\\TOPOLOGY" #define STR_SHORT_AGC "AGC" #define STR_AGC "Automatic Gain Control" #define STR_SHORT_LOUDNESS "Loudness" #define STR_LOUDNESS STR_SHORT_LOUDNESS #define STR_SHORT_MUTE "Mute" #define STR_MUTE STR_SHORT_MUTE #define STR_SHORT_TREBLE "Treble" #define STR_TREBLE STR_SHORT_TREBLE #define STR_SHORT_BASS "Bass" #define STR_BASS STR_SHORT_BASS #define STR_SHORT_VOLUME "Volume" #define STR_VOLUME STR_SHORT_VOLUME #define STR_SHORT_MUX "Mux" #define STR_MUX "Source Mux" #define STR_SHORT_BASS_BOOST "Bass Boost" #define STR_BASS_BOOST STR_SHORT_BASS_BOOST // // The SwapEm macro function will swap the contents of any SLIST based // list. A and B are the elements to swap. T is a temporary variable // of the same type as A and B to use a temporary storage. size is // the size of the structure in the list, including the SLIST element. // The macro does not copy the pointer stored in SLIST. // #define SwapEm(A, B, T, size) \ memcpy( ((BYTE*) (T)) + sizeof( SLIST ), \ ((BYTE*) (A)) + sizeof( SLIST ), \ size - sizeof( SLIST ) ); \ memcpy( ((BYTE*) (A)) + sizeof( SLIST ), \ ((BYTE*) (B)) + sizeof( SLIST ), \ size - sizeof( SLIST ) ); \ memcpy( ((BYTE*) (B)) + sizeof( SLIST ), \ ((BYTE*) (T)) + sizeof( SLIST ), \ size - sizeof( SLIST ) ) // // IsValidLine determines if the line pointed to by pLine is valid. A valid // line is determined by having valid Source and Dest Ids. // #define Is_Valid_Line( pLine ) ( ( pLine->SourceId != INVALID_ID ) && \ ( pLine->DestId != INVALID_ID ) ) /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // F O R W A R D R E F E R E N C E S // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// typedef struct tag_MIXERDEVICE *PMIXERDEVICE; /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // // S T R U C T U R E S // // // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// typedef struct tag_CHANNEL_STEPPING { LONG MinValue; LONG MaxValue; LONG Steps; } CHANNEL_STEPPING, *PCHANNEL_STEPPING; typedef enum tagMXLNODE_TYPE { SOURCE, DESTINATION, NODE } MXLNODE_TYPE; typedef struct tagMXLCONTROL { SLIST List; // MUST BE THE FIRST MEMBER! MIXERCONTROL Control; // The MixerControl structure for the control CONST GUID* NodeType; // The type of node this control represents ULONG Id; // The Node Id this control represents ULONG PropertyId; // The KS property used for GET/SET BOOL bScaled; // Linear->Log scaling ULONG NumChannels; PCHANNEL_STEPPING pChannelStepping; union { // // Supermixer parameters // struct { PLONG pReferenceCount; ULONG Size; PKSAUDIO_MIXCAP_TABLE pMixCaps; PKSAUDIO_MIXLEVEL pMixLevels; // Stored mix levels }; // // Parameters for muxes // struct { BOOL bPlaceholder; BOOL bHasCopy; // bHasCopy must be // set to TRUE unless // this control owns // the original mem. ULONG Count; LPMIXERCONTROLDETAILS_LISTTEXT lpmcd_lt; ULONG* pPins; }; } Parameters; #ifdef DEBUG DWORD Tag; // 'CTRL' if valid control #endif } MXLCONTROL, *PMXLCONTROL, *CONTROLLIST; typedef struct tagMXLLINE { SLIST List; // MUST BE THE FIRST MEMBER! MIXERLINE Line; // The MixerLine structure for the line CONTROLLIST Controls; // The list of controls associated with line ULONG SourceId; // Source Pin Id this line corresponds to ULONG DestId; // Dest Pin Id this line corresponds to GUID Type; // The type of line this is KSPIN_COMMUNICATION Communication; // KSPIN_COMMUNICATION of the line BOOL bMute; } MXLLINE, *PMXLLINE, *LINELIST; typedef struct tagPEERNODE* PEERLIST; typedef struct tagMXLNODE { SLIST List; // MUST BE THE FIRST MEMBER! MXLNODE_TYPE Type; // Type of node: SOURCE, DEST, or NODE GUID NodeType; // KSNODETYPE of the node KSPIN_COMMUNICATION Communication; // KSPIN_COMMUNICATION of the node ULONG Id; // Pin or node ID PEERLIST Children; // List of Children PEERLIST Parents; // List of Parents } MXLNODE, *PMXLNODE, *NODELIST; typedef struct tagPEERNODE { SLIST List; // MUST BE THE FIRST MEMBER! PMXLNODE pNode; // Pointer to the mixer node } PEERNODE, *PPEERNODE; typedef struct tagMIXEROBJECT { PFILE_OBJECT pfo; PMXLNODE pNodeTable; PKSTOPOLOGY pTopology; CONTROLLIST listMuxControls; DWORD dwControlId; PMIXERDEVICE pMixerDevice; #ifdef DEBUG DWORD dwSig; #endif PWSTR DeviceInterface; } MIXEROBJECT, *PMIXEROBJECT; typedef enum { MIXER_MAPPING_LOGRITHMIC, MIXER_MAPPING_LINEAR, MIXER_MAPPING_EXPONENTIAL } MIXERMAPPING; /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // // M A C R O C I T Y : // // L I S T M A N A G E M E N T M A C R O F U N C T I O N S // // // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // Next in list retrieval macros // #define NextInList( pList, Type ) (( Type* ) ( pList->List.Next ) ) #define kmxlNextNode( pNode ) NextInList( pNode, MXLNODE ) #define kmxlNextPeerNode( pNode ) NextInList( pNode, PEERNODE ) #define kmxlNextControl( pControl ) NextInList( pControl, MXLCONTROL ) #define kmxlNextLine( pLine ) NextInList( pLine, MXLLINE ) // // First in list retrieval macros // #define kmxlFirstInList( NodeList ) ( NodeList ) #define kmxlFirstChildNode( pNode ) (( PEERNODE* ) (pNode)->Children ) #define kmxlFirstParentNode( pNode ) (( PEERNODE* ) (pNode)->Parents ) // // List count macros // #define kmxlParentListLength( pNode ) kmxlListCount( (PSLIST) pNode->Parents ) #define kmxlChildListLength( pNode ) kmxlListCount( (PSLIST) pNode->Children ) #define kmxlListLength( List ) kmxlListCount( (PSLIST) List ) // // Added to a list macros // #define kmxlAddToList( pNodeList, pNode ) \ if( pNodeList ) { \ (pNode)->List.Next = (PSLIST) (pNodeList); \ (pNodeList) = (pNode); \ } else { \ (pNode)->List.Next = NULL; \ (pNodeList) = (pNode); \ } #define kmxlAddToEndOfList( list, node ) \ kmxlAddElemToEndOfList( ((PSLIST*) &(list)), (PSLIST) (node) ) #define kxmlAddLineToEndOfList( list, node ) #define kmxlAddToChildList( NodeList, Node ) \ ASSERT( (Node)->pNode ); \ kmxlAddToList( (NodeList)->Children, (Node) ); #define kmxlAddToParentList( NodeList, Node ) \ ASSERT( (Node)->pNode ); \ kmxlAddToList( (NodeList)->Parents, (Node) ); // // Remove from a list macros // #define RemoveFirstEntry( list, Type ) \ (Type*) (list); \ { \ PSLIST pRFETemp; \ pRFETemp = (PSLIST) (list); \ if( (list) ) { \ (list) = (Type*) (list)->List.Next; \ if( pRFETemp ) { \ ((Type*) pRFETemp)->List.Next = NULL; \ } \ } \ } #define kmxlRemoveFirstNode( pNodeList ) \ RemoveFirstEntry( (pNodeList), MXLNODE ) #define kmxlRemoveFirstControl( pControlList ) \ RemoveFirstEntry( (pControlList), MXLCONTROL ) #define kmxlRemoveFirstLine( pLineList ) \ RemoveFirstEntry( (pLineList), MXLLINE ) #define kmxlRemoveFirstPeerNode( pPeerList ) \ RemoveFirstEntry( (pPeerList), PEERNODE ) #define kmxlRemoveFirstChildNode( pNode ) \ RemoveFirstEntry( (pNode)->Children, PEERNODE ) #define kmxlRemoveFirstParentNode( pNode ) \ RemoveFirstEntry( (pNode)->Parents, PEERNODE ) #ifdef DEBUG #define CONTROL_TAG 'LRTC' //CTRL as seen in memory. #else #define CONTROL_TAG #endif // DEBUG /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // // P R O T O T Y P E S // // // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // // I N I T I A L I Z A T I O N / D E I N I T I A L I Z A T I O N // // // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // kmxlInit // // Retrieves and parses the topology for a given mixer device number. // The pfo is an open file object to an instance of a filter that // will provide the topology. // // NTSTATUS kmxlInit( IN PFILE_OBJECT pfo, // Handle of the topology driver instance IN PMIXERDEVICE pMixerDevice // The device to initialize for ); /////////////////////////////////////////////////////////////////////// // // kmxlDeInit // // Cleans up all memory for all devices. // // NTSTATUS kmxlDeInit( IN PMIXERDEVICE pMixerDevice ); /////////////////////////////////////////////////////////////////////// // // BuildMixerLines // // Build the list of mixer lines and stores them into plistLines. // pcDestinations contains the count of total destinations for the // given topology, pTopology. // // NTSTATUS kmxlBuildLines( IN PMIXERDEVICE pMixer, // The mixer device IN PFILE_OBJECT pfoInstance, // The FILE_OBJECT of a filter instance IN OUT LINELIST* plistLines, // Pointer to the list of all lines IN OUT PULONG pcDestinations, // Pointer to the number of dests IN OUT PKSTOPOLOGY pTopology // Pointer to a topology structure ); /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // // T O P O L O G Y F U N C T I O N S // // // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // QueryTopology // // Queries the topology property on the given instance and stores // it into pTopology. Note that memory is allocated to store the // topology. // // NTSTATUS kmxlQueryTopology( IN PFILE_OBJECT pfoInstance, // The instance to query OUT PKSTOPOLOGY pTopology // The topology structure to fill in ); /////////////////////////////////////////////////////////////////////// // // ParseTopology // // Parses the topology in pTopology and builds a graph of sources and // destinations. ppSources will contain a list of all sources nodes // and ppDests will contain a list of dests. The elements in pNodeTable // will be updated. // // NTSTATUS kmxlParseTopology( IN PMIXEROBJECT pmxobj, OUT NODELIST* ppSources, // Pointer to the sources list to build OUT NODELIST* ppDests // Pointer to the dests list to build ); /////////////////////////////////////////////////////////////////////// // // BuildChildGraph // // For a given node, BuildChildGraph() will build the graph of each // of the node's children. pNodeTable is updated. // // NTSTATUS kmxlBuildChildGraph( IN PMIXEROBJECT pmxobj, IN NODELIST listDests, // The list of destinations IN PMXLNODE pNode, // The node to build the graph for IN ULONG FromNode, // The node's ID IN ULONG FromNodePin // The Pin connection to look for ); /////////////////////////////////////////////////////////////////////// // // BuildNodeTable // // Allocates and fills in the table of nodes for the topology. // // PMXLNODE kmxlBuildNodeTable( IN PKSTOPOLOGY pTopology // The topology structure to build from ); /////////////////////////////////////////////////////////////////////// // // FindTopologyConnection // // Finds the specified connection, if it exists, starting at the // StartIndex index into the connections table. It will return the // index into the connection table of a connection starting from // the given FromNode and FromNodePin. FromNodePin may be PINID_WILDCARD // if a connection on a node is present rather than a specific connection. // // ULONG kmxlFindTopologyConnection( IN PMIXEROBJECT pmxobj, //IN CONST KSTOPOLOGY_CONNECTION* pConnections, // The connection table //IN ULONG cConnections, // The # of connections IN ULONG StartIndex, // Index to start search IN ULONG FromNode, // The Node ID to look for IN ULONG FromNodePin // The Pin ID to look for ); /////////////////////////////////////////////////////////////////////// // // GetProperty // // Retrieves the specified property from an open filter. Flags may // contain values such as KSPROPERTY_TYPE_TOPOLOGY. The output // buffer is allocated to the correct size and returned by this // function. // // NTSTATUS kmxlGetProperty( PFILE_OBJECT pFileObject, // The instance of the filter CONST GUID *pguidPropertySet, // The requested property set ULONG ulPropertyId, // The ID of the specific property ULONG cbInput, // The number of extra input bytes PVOID pInputData, // Pointer to the extra input bytes ULONG Flags, // Additional flags PVOID *ppPropertyOutput // Pointer to a pointer of the output ); /////////////////////////////////////////////////////////////////////// // // kmxlNodeProperty // // NodeProperty() gets or sets the property on an individual node. // The output is not allocated and must be passed in by the caller. // Flags can be KSPROPERTY_TYPE_GET or KSPROPERTY_TYPE_SET. // // NTSTATUS kmxlNodeProperty( IN PFILE_OBJECT pFileObject, // Instance of the filter owning node IN CONST GUID* pguidPropertySet, // The GUID of the property set IN ULONG ulPropertyId, // The specific property in the set IN ULONG ulNodeId, // The virtual node id IN ULONG cbInput, // # of extra input bytes IN PVOID pInputData, // Pointer to the extra input bytes OUT PVOID pPropertyOutput, // Pointer to the output data IN ULONG cbPropertyOutput, // Size of the output data buffer IN ULONG Flags // KSPROPERTY_TYPE_GET or SET ); /////////////////////////////////////////////////////////////////////// // // kmxlGetNodeProperty // // Get the specified property for a node. See kmxlNodeProperty for // details on parameters and returns. // // #define kmxlGetNodeProperty( pfo,pguid,Id,Node,cbIn,pIn,pOut,cbOut ) \ kmxlNodeProperty( pfo,pguid,Id,Node,cbIn,pIn,pOut,cbOut,KSPROPERTY_TYPE_GET ) /////////////////////////////////////////////////////////////////////// // // kmxlSetNodeProperty // // Sets the specified property for a node. See kmxlNodeProperty for // details on parameters and returns. // // #define kmxlSetNodeProperty( pfo,pguid,Id,Node,cbIn,pIn,pOut,cbOut ) \ kmxlNodeProperty( pfo,pguid,Id,Node,cbIn,pIn,pOut,cbOut,KSPROPERTY_TYPE_SET ) /////////////////////////////////////////////////////////////////////// // // kmxlAudioNodeProperty // // Sets or get the audio specific node property. The property set // is always KSPROPSETID_Audio. lChannel specifies which channel to // apply the property to. 0 is left, 1 is right, -1 is master (all). // Flags can be either KSPROPERTY_TYPE_GET or KSPROPERTY_TYPE_SET. // // NTSTATUS kmxlAudioNodeProperty( IN PFILE_OBJECT pfo, // Instance of the filter owning node IN ULONG ulPropertyId, // The audio property to get IN ULONG ulNodeId, // The virtual node id IN LONG lChannel, // The channel number IN PVOID pInData, // Pointer to extra input bytes IN ULONG cbInData, // Number of extra input bytes OUT PVOID pOutData, // Pointer to output buffer IN LONG cbOutData, // Size of the output buffer IN ULONG Flags // KSPROPERTY_TYPE_GET or SET ); /////////////////////////////////////////////////////////////////////// // // kxmlGetAudioNodeProperty // // Gets the specified audio property on a node. See kmxlAudioNodeProperty // for details on parameters and return values. // // #define kmxlGetAudioNodeProperty(pfo,Id,Node,Chan,pIn,cbIn,pOut,cbOut) \ kmxlAudioNodeProperty( pfo,Id,Node,Chan,pIn,cbIn,pOut,cbOut,KSPROPERTY_TYPE_GET ) /////////////////////////////////////////////////////////////////////// // // kxmlSetAudioNodeProperty // // Sets the specified audio property on a node. See kmxlAudioNodeProperty // for details on parameters and return values. // // #define kmxlSetAudioNodeProperty(pfo,Id,Node,Chan,pIn,cbIn,pOut,cbOut) \ kmxlAudioNodeProperty( pfo,Id,Node,Chan,pIn,cbIn,pOut,cbOut,KSPROPERTY_TYPE_SET ) /////////////////////////////////////////////////////////////////////// // // kmxlGetPinName // // Retrieves the name of the pin given by NodeId. // // VOID kmxlGetPinName( IN PFILE_OBJECT pfo, // Instance of the owning filter IN ULONG PinId, // Id of the pin IN PMXLLINE pLine // The line to store the name into ); /////////////////////////////////////////////////////////////////////// // // kmxlGetNodeName // // Retrieves the name of a node (control). // // VOID kmxlGetNodeName( IN PFILE_OBJECT pfo, // Instance of the owning filter IN ULONG NodeId, // The node id IN PMXLCONTROL pControl // The control to store the name ); /////////////////////////////////////////////////////////////////////// // // kmxlGetSuperMixCaps // // NTSTATUS kmxlGetSuperMixCaps( IN PFILE_OBJECT pfo, IN ULONG ulNodeId, OUT PKSAUDIO_MIXCAP_TABLE* paMixCaps ); /////////////////////////////////////////////////////////////////////// // // kmxlQueryPropertyRange // // NTSTATUS kmxlQueryPropertyRange( IN PFILE_OBJECT pfo, IN CONST GUID* pguidPropSet, IN ULONG ulPropertyId, IN ULONG ulNodeId, OUT PKSPROPERTY_DESCRIPTION* ppPropDesc ); /////////////////////////////////////////////////////////////////////// // // kmxlGetControlChannels // // NTSTATUS kmxlGetControlChannels( IN PFILE_OBJECT pfo, IN PMXLCONTROL pControl ); /////////////////////////////////////////////////////////////////////// // // kmxlGetControlRange // // NTSTATUS kmxlGetControlRange( IN PFILE_OBJECT pfo, IN PMXLCONTROL pControl ); /////////////////////////////////////////////////////////////////////// // // kmxlGetNumMuxLines // // DWORD kmxlGetNumMuxLines( IN PKSTOPOLOGY pTopology, IN ULONG NodeId ); /////////////////////////////////////////////////////////////////////// // // kmxlGetMuxLineNames // // VOID kmxlGetMuxLineNames( IN PMIXEROBJECT pmxobj, IN PMXLCONTROL pControl ); /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // // M I X E R L I N E F U N C T I O N S // // // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // kmxlBuildDestinationLines // // Builds up a list of destination lines given a list of the destination // nodes. // // Returns NULL on error. // // LINELIST kmxlBuildDestinationLines( IN PMIXEROBJECT pmxobj, IN NODELIST listDests // The list of destination nodes ); /////////////////////////////////////////////////////////////////////// // // kmxlBuildDestinationControls // // Builds a list of mixer line controls for a given destination line. // // NTSTATUS kmxlBuildDestinationControls( IN PMIXEROBJECT pmxobj, IN PMXLNODE pDest, // The destination to built controls for IN PMXLLINE pLine // The line to add the controls to ); /////////////////////////////////////////////////////////////////////// // // kmxlBuildSourceLines // // Builds a list of mixer source lines for the given topology. // // LINELIST kmxlBuildSourceLines( IN PMIXEROBJECT pmxobj, IN NODELIST listSources, // The list of source nodes IN NODELIST listDests // The list of dest. nodes ); /////////////////////////////////////////////////////////////////////// // // kmxlBuildPath // // Builds the controls for each of the source lines, building new // source lines of splits are detected in the topology. plistLines // may have new lines added if splits are encountered. Destinations // for each of the sources is also determined. // // NTSTATUS kmxlBuildPath( IN PMIXEROBJECT pmxobj, IN PMXLNODE pSource, // The source node for this path IN PMXLNODE pNode, // The current node in the path IN PMXLLINE pLine, // The current line IN OUT LINELIST* plistLines, // The list of lines build so far IN NODELIST listDests // The list of the destinations ); /////////////////////////////////////////////////////////////////////// // // kmxlIsDestinationNode // // Return TRUE if the given node appears in the node list of any // of the destinations in listDests. // // BOOL kmxlIsDestinationNode( IN NODELIST listDests, // The list of destinations IN PMXLNODE pNode // The node to check ); /////////////////////////////////////////////////////////////////////// // // kmxlDuplicateLine // // Duplicates the given line, including all controls on that line. // // NTSTATUS kmxlDuplicateLine( IN PMXLLINE* ppTargetLine, // Pointer to the new line IN PMXLLINE pSourceLine // The line to duplicate ); /////////////////////////////////////////////////////////////////////// // // kmxlDuplicateLineControls // // Duplicate up to nCount controls on the source line and stores them // into the target line. // // NTSTATUS kmxlDuplicateLineControls( IN PMXLLINE pTargetLine, // The line to put the controls into IN PMXLLINE pSourceLine, // The line with the controls to dup IN ULONG nCount // The number of controls to dup ); /////////////////////////////////////////////////////////////////////// // // kmxlFindDestinationForNode // // For a given node, this function finds the destination it is assoicated // with. plistLines needs to be included since new lines will need to // be created if a split is encountered in the topology. // // ULONG kmxlFindDestinationForNode( IN PMIXEROBJECT pmxobj, IN PMXLNODE pNode, // The node to find dest for IN PMXLNODE pParent, // The original parent IN PMXLLINE pLine, // The current line it's on IN OUT LINELIST* plistLines // The list of all lines ); /////////////////////////////////////////////////////////////////////// // // kmxlBuildVirtualMuxLine // // NTSTATUS kmxlBuildVirtualMuxLine( IN PMIXEROBJECT pmxobj, IN PMXLNODE pParent, IN PMXLNODE pMux, IN OUT LINELIST* plistLines ); /////////////////////////////////////////////////////////////////////// // // kmxlAssignLineAndControlIds // // For a specific set of lines, this function assigns the mixer line // line Ids and controls Ids. Only sources or only destinations can // be assigned per call. // // NTSTATUS kmxlAssignLineAndControlIds( IN PMIXEROBJECT pmxobj, IN LINELIST listLines, // The list to assign ids for IN ULONG ListType // LIST_SOURCE or LIST_DESTINATION ); /////////////////////////////////////////////////////////////////////// // // kmxlAssignDestinationsToSources // // For each line, the destination field of the MIXERLINE structure // is filled in and a unique LineId is assigned. // // NTSTATUS kmxlAssignDestinationsToSources( IN LINELIST listSourceLines, // The list of all source lines IN LINELIST listDestLines // The list of all dest lines ); /////////////////////////////////////////////////////////////////////// // // kmxlAssignMuxIds // // NTSTATUS kmxlAssignMuxIds( IN PMIXEROBJECT pmxobj, IN LINELIST listSourceLines ); /////////////////////////////////////////////////////////////////////// // // TranslateNodeToControl // // Translates the node specified by its GUID into 0 or more mixer // line controls. The return value indicates how many controls // the node was really translated into. // // ULONG kmxlTranslateNodeToControl( IN PMIXEROBJECT pmxobj, IN PMXLNODE pNode, // The node to translate into a control OUT PMXLCONTROL* ppControl // The control to fill in ); /////////////////////////////////////////////////////////////////////// // // kmxlSupportsControl // // Queries for property on control to see if it is actually supported // // NTSTATUS kmxlSupportsControl( IN PFILE_OBJECT pfoInstance, // The instance to check for IN ULONG Node, // The node ID on the instance IN ULONG Property // The property to query support ); /////////////////////////////////////////////////////////////////////// // // kmxlSupportsMultiChannelControl // // Queries for property on the second channel of the control to see // independent levels can be set. It is assumed that the first channel // already succeeded in kmxlSupportsControl // // NTSTATUS kmxlSupportsMultiChannelControl( IN PFILE_OBJECT pfoInstance, // The instance to check for IN ULONG Node, // The node id to query IN ULONG Property // The property to check for ); /////////////////////////////////////////////////////////////////////// // // kmxlSupportsTrebleControl // // Querys the node to see if it supports KSPROPERTY_AUDIO_TREBLE. // See kmxlSupportsControl for return value details. // // #define kmxlSupportsTrebleControl( pfo, Node ) \ kmxlSupportsControl( pfo, Node, KSPROPERTY_AUDIO_TREBLE ) /////////////////////////////////////////////////////////////////////// // // kmxlSupportsBassControl // // Querys the node to see if it supports KSPROPERTY_AUDIO_BASS. // See kmxlSupportsControl for return value details. // // #define kmxlSupportsBassControl( pfo, Node ) \ kmxlSupportsControl( pfo, Node, KSPROPERTY_AUDIO_BASS ) /////////////////////////////////////////////////////////////////////// // // kmxlUpdateDestinationConnectionCount // // Counts the number of sources mapping to a single destination and // stores that value in the MIXERLINE.cConnections field for that // destination. // // NTSTATUS kmxlUpdateDestintationConnectionCount( IN LINELIST listSourceLines, // The list of sources IN LINELIST listDestLines // The list of destinations ); /////////////////////////////////////////////////////////////////////// // // kmxlElminiateInvalidLines // // Loops through all the lines and eliminates the ones that are // invalid by the IsValidLine() macro function test. // // NTSTATUS kmxlEliminateInvalidLines( IN LINELIST* listLines // The list of sources ); /////////////////////////////////////////////////////////////////////// // // kmxlAssignComponentIds // // For each source and destination line, it assignes the // MIXERLINE.dwComonentType field for that line. // // VOID kmxlAssignComponentIds( IN PMIXEROBJECT pmxobj, // Instance data IN LINELIST listSourceLines, // The list of source lines IN LINELIST listDestLines // The list of destination lines ); /////////////////////////////////////////////////////////////////////// // // kmxlDetermineDestinationType // // Determines the dwComponentId and Target.dwType fields for the // given line. Determination is made by the MXLLINE.Type field. // // ULONG kmxlDetermineDestinationType( IN PMIXEROBJECT pmxobj, // Instance data IN PMXLLINE pLine // The line to update ); /////////////////////////////////////////////////////////////////////// // // kmxlDetermineSourceType // // Determines the dwComponentId and Target.dwType fields for the // given line. Determination is made by the MXLLINE.Type field. // // ULONG kmxlDetermineSourceType( IN PMIXEROBJECT pmxobj, // Instance data IN PMXLLINE pLine // The line to update ); /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // // U T I L I T Y F U N C T I O N S // // // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // kmxlOpenSysAudio // // Opens the SysAudio device and returns the file object. // // PFILE_OBJECT kmxlOpenSysAudio( ); /////////////////////////////////////////////////////////////////////// // // kmxlCloseSysAudio // // Closes the SysAudio device opened by kmxlOpenSysAudio. // // VOID kmxlCloseSysAudio( IN PFILE_OBJECT pfo // The instance to close ); /////////////////////////////////////////////////////////////////////// // // kmxlFindDestination // // Finds a destination id in the list of all the destinations and returns // a pointer to that node. Returns NULL on failure. // // PMXLNODE kmxlFindDestination( IN NODELIST listDests, // The list of destinations to search IN ULONG Id // The node Id to look for in the list ); /////////////////////////////////////////////////////////////////////// // // kmxlAppendListToList // // Appends listSource onto the front of plistTarget. // // VOID kmxlAppendListToList( IN OUT PSLIST* plistTarget, // The list to append to IN PSLIST listSource // the list to append ); /////////////////////////////////////////////////////////////////////// // // kmxlAppendListToList // // Appends listSource onto the end of plistTarget // // VOID kmxlAppendListToEndOfList( IN OUT PSLIST* plistTarget, // The list to append to IN PSLIST listSource // the list to append ); /////////////////////////////////////////////////////////////////////// // // kmxlListCount // // Returns the number of elements in the list. // // ULONG kmxlListCount( IN PSLIST pList // The list to count the elements of ); /////////////////////////////////////////////////////////////////////// // // kmxlInList // // Return TRUE if pNewNode is in the list. // // BOOL kmxlInList( IN PEERLIST list, // The list to search IN PMXLNODE pNewNode // The new to search for ); /////////////////////////////////////////////////////////////////////// // // kmxlAddElemToEndOfList // // Adds an element to the end of the given list. // // VOID kmxlAddElemToEndOfList( IN OUT PSLIST* list, // The list to add to the end of IN PSLIST elem // The element or list to add ); /////////////////////////////////////////////////////////////////////// // // kmxlInChildList // // Return TRUE if pNewNode is contained in the child list of the list. // // BOOL kmxlInChildList( IN NODELIST list, // The list to search the parent list IN PMXLNODE pNewNode // The node to search for ); /////////////////////////////////////////////////////////////////////// // // kmxlInParentList // // Returns TRUE if pNewNode is contained in the parent list of the list. // // BOOL kmxlInParentList( IN NODELIST list, // The list to search the parent list IN PMXLNODE pNewNode // The node to search for ); /////////////////////////////////////////////////////////////////////// // // kmxlSortByDestination // // Sorts the given list by destination id in increasing order. // // NTSTATUS kmxlSortByDestination( IN LINELIST* list // The pointer to the list to sort ); /////////////////////////////////////////////////////////////////////// // // kmxlVolLinearToLog // // LONG kmxlVolLinearToLog( IN PMXLCONTROL pControl, IN DWORD dwLin, IN MIXERMAPPING Mapping, IN ULONG Channel ); /////////////////////////////////////////////////////////////////////// // // kmxlVolLogToLinear // // DWORD kmxlVolLogToLinear( IN PMXLCONTROL pControl, IN LONG lLog, IN MIXERMAPPING Mapping, IN ULONG Channel ); /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // // M E M O R Y A L L O C A T I O N / D E A L L O C A T I O N // // // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // kmxlAllocMem // // Allocates size bytes and stores that pointer in pp. Returns // STATUS_SUCCESS or another STATUS failure code. // // //NTSTATUS //kmxlAllocMem( // IN PVOID *pp, // Pointer to put the new memory in // IN ULONG size, // The number of bytes to allocate // IN ULONG ultag //); /////////////////////////////////////////////////////////////////////// // // kmxlAllocDeviceInfo // NTSTATUS kmxlAllocDeviceInfo( OUT LPDEVICEINFO *pp, PCWSTR DeviceInterface, DWORD dwFlags, ULONG ultag ); /////////////////////////////////////////////////////////////////////// // // kmxlFreeMem // // // Frees the memory pointed to by p. Does nothing if p is NULL. // // //VOID //kmxlFreeMem( // IN PVOID p // The pointer to the buffer to free //); /////////////////////////////////////////////////////////////////////// // // kmxlFreePeerList // // Loops through a peer list freeing all the peer nodes. // // VOID kmxlFreePeerList( IN PEERLIST list // The PeerList to free ); /////////////////////////////////////////////////////////////////////// // // kmxlAllocateControl // // Allocates and zero fills a new MXLCONTROL structure. // // MXLCONTROL* kmxlAllocateControl( IN ULONG ultag ); VOID kmxlFreeControl( IN PMXLCONTROL pControl ); /////////////////////////////////////////////////////////////////////// // // kmxlAllocateLine // // Allocates and zero filles a new MXLLINE structure. // // MXLLINE* kmxlAllocateLine( IN ULONG ultag ); /////////////////////////////////////////////////////////////////////// // // kmxlAllocateNode // // Allocates and zero filles a new MXLNODE structure. // // MXLNODE* kmxlAllocateNode( IN ULONG ultag ); /////////////////////////////////////////////////////////////////////// // // kmxlAllocatePeerNode // // Allocates and zero fills a new PEERNODE structure. // // PEERNODE* kmxlAllocatePeerNode( IN PMXLNODE pNode OPTIONAL, // The node to associate with the peer IN ULONG ultag ); /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // // P E R S I S T A N C E F U N C T I O N S // // // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// NTSTATUS kmxlOpenInterfaceKey( IN PFILE_OBJECT pfo, IN ULONG Device, OUT HANDLE* phKey ); NTSTATUS kmxlRegQueryValue( IN HANDLE hKey, IN PWCHAR szValueName, IN PVOID pData, IN ULONG cbData, OUT PULONG pResultLength ); /////////////////////////////////////////////////////////////////////// // // kmxlRegCloseKey // // Closes the given key and NULLs the pointer. // // #define kmxlRegCloseKey( hKey ) \ { \ ZwClose( hKey ); \ hKey = NULL; \ } /////////////////////////////////////////////////////////////////////// // // PinCategoryToString // // Translates a PinCategory GUID into a string. // // const char* PinCategoryToString ( IN CONST GUID* NodeType // The node to translate ); /////////////////////////////////////////////////////////////////////// // // NodeTypeToString // // Translates a NodeType GUID to a string. // // const char* NodeTypeToString ( IN CONST GUID* NodeType // The node to translate ); #define ControlTypeToString( dwType ) \ (dwType) == MIXERCONTROL_CONTROLTYPE_BOOLEAN ? "Boolean" : \ (dwType) == MIXERCONTROL_CONTROLTYPE_ONOFF ? "On Off" : \ (dwType) == MIXERCONTROL_CONTROLTYPE_MUTE ? "Mute" : \ (dwType) == MIXERCONTROL_CONTROLTYPE_MONO ? "Mono" : \ (dwType) == MIXERCONTROL_CONTROLTYPE_LOUDNESS ? "Loudness" : \ (dwType) == MIXERCONTROL_CONTROLTYPE_STEREOENH ? "Stereo Enhance" : \ (dwType) == MIXERCONTROL_CONTROLTYPE_VOLUME ? "Volume" : \ (dwType) == MIXERCONTROL_CONTROLTYPE_BASS ? "Bass" : \ (dwType) == MIXERCONTROL_CONTROLTYPE_TREBLE ? "Treble" : \ (dwType) == MIXERCONTROL_CONTROLTYPE_BASS_BOOST ? "Bass Boost" : \ (dwType) == MIXERCONTROL_CONTROLTYPE_PEAKMETER ? "Peakmeter" : \ (dwType) == MIXERCONTROL_CONTROLTYPE_MUX ? "Mux" : \ (dwType) == MIXERCONTROL_CONTROLTYPE_MIXER ? "Mixer" : \ "Unknown ControlType" /////////////////////////////////////////////////////////////////////// // // ComponentTypeToString // // Translates one of the MIXERLINE_COMPONENTTYPE constants to a string. // // #define ComponentTypeToString( dwType ) \ (dwType) == MIXERLINE_COMPONENTTYPE_DST_DIGITAL ? "Digital line" : \ (dwType) == MIXERLINE_COMPONENTTYPE_DST_HEADPHONES ? "Headphones" : \ (dwType) == MIXERLINE_COMPONENTTYPE_DST_LINE ? "Line" : \ (dwType) == MIXERLINE_COMPONENTTYPE_DST_MONITOR ? "Monitor" : \ (dwType) == MIXERLINE_COMPONENTTYPE_DST_SPEAKERS ? "Speakers" : \ (dwType) == MIXERLINE_COMPONENTTYPE_DST_TELEPHONE ? "Telephone" : \ (dwType) == MIXERLINE_COMPONENTTYPE_DST_UNDEFINED ? "Undefined" : \ (dwType) == MIXERLINE_COMPONENTTYPE_DST_VOICEIN ? "Voicein" : \ (dwType) == MIXERLINE_COMPONENTTYPE_DST_WAVEIN ? "Wavein" : \ (dwType) == MIXERLINE_COMPONENTTYPE_SRC_ANALOG ? "Analog line" : \ (dwType) == MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY ? "Auxiliary" : \ (dwType) == MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC ? "Compact disc" : \ (dwType) == MIXERLINE_COMPONENTTYPE_SRC_DIGITAL ? "Digital line" : \ (dwType) == MIXERLINE_COMPONENTTYPE_SRC_LINE ? "Line" : \ (dwType) == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE ? "Microphone" : \ (dwType) == MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER ? "PC Speaker" : \ (dwType) == MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER ? "Synthesizer" : \ (dwType) == MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE ? "Telephone" : \ (dwType) == MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED ? "Undefined" : \ (dwType) == MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT ? "Waveout" : \ "Unknown ComponentType" /////////////////////////////////////////////////////////////////////// // // TargetTypeToString // // Translates one of hte MIXERLINE_TARGETTYPE constants to a string. // // #define TargetTypeToString( dwType ) \ (dwType) == MIXERLINE_TARGETTYPE_AUX ? "Aux" : \ (dwType) == MIXERLINE_TARGETTYPE_MIDIIN ? "MidiIn" : \ (dwType) == MIXERLINE_TARGETTYPE_MIDIOUT ? "MidiOut" : \ (dwType) == MIXERLINE_TARGETTYPE_UNDEFINED ? "Undefined" : \ (dwType) == MIXERLINE_TARGETTYPE_WAVEIN ? "WaveIn" : \ (dwType) == MIXERLINE_TARGETTYPE_WAVEOUT ? "WaveOut" : \ "Unknown TargetType" /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // // D E B U G O N L Y F U N C T I O N S // // // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// #ifdef DEBUG /////////////////////////////////////////////////////////////////////// // // LineFlagsToString // // Converts on of the MIXERLINE_LINEF flags to a string. // // #define LineFlagsToString( fdwFlags ) \ ( fdwFlags & MIXERLINE_LINEF_ACTIVE ) ? "ACTIVE " : \ ( fdwFlags & MIXERLINE_LINEF_DISCONNECTED ) ? "DISCONNECTED " : \ ( fdwFlags & MIXERLINE_LINEF_SOURCE ) ? "SOURCE " : \ "Unknown" /////////////////////////////////////////////////////////////////////// // // DumpChildGraph // // For a given node, it dumps the child of that node onto the debug // monitor. CurrentIndent is the number of spaces to indent before // display. // // VOID DumpChildGraph( IN PMXLNODE pNode, // The node to display the children of IN ULONG CurrentIndent // The number of spaces to ident ); /////////////////////////////////////////////////////////////////////// // // DumpMemList // // Dumps the list of currently allocated memory blocks. // // VOID DumpMemList( ); #endif // DEBUG VOID GetHardwareEventData(LPDEVICEINFO pDeviceInfo); #endif // _MIXER_H_INCLUDED