else
NodeIndex = CurConnection->ToNode;
+ if (NodeIndex > NodeTypes->Count)
+ {
+ // reached end of pin connection
+ return MM_STATUS_SUCCESS;
+ }
+
/* get target node type of current connection */
NodeType = MMixerGetNodeType(NodeTypes, NodeIndex);
Status = MMixerGetNodeIndexes(MixerContext, NodeConnections, NodeIndex, TRUE, TRUE, &NodeConnectionCount, &NodeConnection);
}
- if (Status != MM_STATUS_SUCCESS)
+ if (Status == MM_STATUS_SUCCESS)
{
for(Index = 0; Index < NodeConnectionCount; Index++)
{
LPWSTR PinName;
GUID NodeType;
ULONG BytesReturned, ControlCount, Index;
+ LPGUID Node;
PULONG Nodes;
if (!bTargetPin)
{
if (Nodes[Index])
{
- // found a node
- ControlCount++;
+ // get node type
+ Node = MMixerGetNodeType(NodeTypes, Index);
+
+ if (MMixerGetControlTypeFromTopologyNode(Node))
+ {
+ // found a node which can be resolved to a type
+ ControlCount++;
+ }
}
}
{
if (Nodes[Index])
{
- /* store the node index for retrieving / setting details */
- SrcLine->NodeIds[ControlCount] = Index;
+ // get node type
+ Node = MMixerGetNodeType(NodeTypes, Index);
- Status = MMixerAddMixerControl(MixerContext, MixerInfo, hDevice, NodeTypes, Index, SrcLine, &SrcLine->LineControls[ControlCount]);
- if (Status == MM_STATUS_SUCCESS)
+ if (MMixerGetControlTypeFromTopologyNode(Node))
{
- /* increment control count on success */
- ControlCount++;
+ /* store the node index for retrieving / setting details */
+ SrcLine->NodeIds[ControlCount] = Index;
+
+ Status = MMixerAddMixerControl(MixerContext, MixerInfo, hDevice, NodeTypes, Index, SrcLine, &SrcLine->LineControls[ControlCount]);
+ if (Status == MM_STATUS_SUCCESS)
+ {
+ /* increment control count on success */
+ ControlCount++;
+ }
}
}
}
MMixerCreateDestinationLine(
IN PMIXER_CONTEXT MixerContext,
IN LPMIXER_INFO MixerInfo,
- IN ULONG bInputMixer)
+ IN ULONG bInputMixer,
+ IN LPWSTR LineName)
{
LPMIXERLINE_EXT DestinationLine;
DestinationLine->Line.dwUser = 0;
DestinationLine->Line.dwComponentType = (bInputMixer == 0 ? MIXERLINE_COMPONENTTYPE_DST_SPEAKERS : MIXERLINE_COMPONENTTYPE_DST_WAVEIN);
DestinationLine->Line.cChannels = 2; //FIXME
- wcscpy(DestinationLine->Line.szShortName, L"Summe"); //FIXME
- wcscpy(DestinationLine->Line.szName, L"Summe"); //FIXME
+
+ if (LineName)
+ {
+ wcscpy(DestinationLine->Line.szShortName, LineName);
+ wcscpy(DestinationLine->Line.szName, LineName);
+ }
+ else
+ {
+ /* FIXME no name was found for pin */
+ wcscpy(DestinationLine->Line.szShortName, L"Summe");
+ wcscpy(DestinationLine->Line.szName, L"Summe");
+ }
+
DestinationLine->Line.Target.dwType = (bInputMixer == 0 ? MIXERLINE_TARGETTYPE_WAVEOUT : MIXERLINE_TARGETTYPE_WAVEIN);
DestinationLine->Line.Target.dwDeviceID = !bInputMixer;
DestinationLine->Line.Target.wMid = MixerInfo->MixCaps.wMid;
MIXER_STATUS
MMixerHandlePhysicalConnection(
IN PMIXER_CONTEXT MixerContext,
+ IN PMIXER_LIST MixerList,
IN OUT LPMIXER_INFO MixerInfo,
IN ULONG bInput,
IN PKSPIN_PHYSICALCONNECTION OutConnection)
PULONG PinsRef = NULL, PinConnectionIndex = NULL, PinsSrcRef;
ULONG PinsRefCount, Index, PinConnectionIndexCount;
MIXER_STATUS Status;
- HANDLE hDevice = NULL;
PKSMULTIPLE_ITEM NodeTypes = NULL;
PKSMULTIPLE_ITEM NodeConnections = NULL;
PULONG MixerControls;
ULONG MixerControlsCount;
+ LPMIXER_DATA MixerData;
// open the connected filter
- Status = MixerContext->Open(OutConnection->SymbolicLinkName, &hDevice);
- if (Status != MM_STATUS_SUCCESS)
- {
- DPRINT("OpenDevice failed with %x\n", Status);
- return Status;
- }
+ OutConnection->SymbolicLinkName[1] = L'\\';
+ MixerData = MMixerGetDataByDeviceName(MixerList, OutConnection->SymbolicLinkName);
+ ASSERT(MixerData);
// get connected filter pin count
- PinsRefCount = MMixerGetFilterPinCount(MixerContext, hDevice);
+ PinsRefCount = MMixerGetFilterPinCount(MixerContext, MixerData->hDevice);
ASSERT(PinsRefCount);
PinsRef = (PULONG)MixerContext->Alloc(sizeof(ULONG) * PinsRefCount);
if (!PinsRef)
{
// no memory
- MixerContext->Close(hDevice);
return MM_STATUS_UNSUCCESSFUL;
}
// get topology node types
- Status = MMixerGetFilterTopologyProperty(MixerContext, hDevice, KSPROPERTY_TOPOLOGY_NODES, &NodeTypes);
+ Status = MMixerGetFilterTopologyProperty(MixerContext, MixerData->hDevice, KSPROPERTY_TOPOLOGY_NODES, &NodeTypes);
if (Status != MM_STATUS_SUCCESS)
{
- MixerContext->Close(hDevice);
MixerContext->Free(PinsRef);
return Status;
}
// get topology connections
- Status = MMixerGetFilterTopologyProperty(MixerContext, hDevice, KSPROPERTY_TOPOLOGY_CONNECTIONS, &NodeConnections);
+ Status = MMixerGetFilterTopologyProperty(MixerContext, MixerData->hDevice, KSPROPERTY_TOPOLOGY_CONNECTIONS, &NodeConnections);
if (Status != MM_STATUS_SUCCESS)
{
- MixerContext->Close(hDevice);
MixerContext->Free(PinsRef);
MixerContext->Free(NodeTypes);
return Status;
Status = MMixerGetNodeIndexes(MixerContext, NodeConnections, OutConnection->Pin, FALSE, !bInput, &PinConnectionIndexCount, &PinConnectionIndex);
if (Status != MM_STATUS_SUCCESS)
{
- MixerContext->Close(hDevice);
MixerContext->Free(PinsRef);
MixerContext->Free(NodeTypes);
MixerContext->Free(NodeConnections);
Status = MMixerGetTargetPinsByNodeConnectionIndex(MixerContext, NodeConnections, NodeTypes, FALSE, PinConnectionIndex[0], PinsRef);
if (Status != MM_STATUS_SUCCESS)
{
- MixerContext->Close(hDevice);
MixerContext->Free(PinsRef);
MixerContext->Free(NodeTypes);
MixerContext->Free(NodeConnections);
if (!PinsSrcRef)
{
/* no memory */
- MixerContext->Close(hDevice);
MixerContext->Free(PinsRef);
MixerContext->Free(NodeTypes);
MixerContext->Free(NodeConnections);
if (Status != MM_STATUS_SUCCESS)
{
// failed */
- MixerContext->Close(hDevice);
MixerContext->Free(PinsRef);
MixerContext->Free(NodeTypes);
MixerContext->Free(NodeConnections);
}
PinsSrcRef[OutConnection->Pin] = TRUE;
- Status = MMixerAddMixerSourceLines(MixerContext, MixerInfo, hDevice, NodeConnections, NodeTypes, PinsRefCount, OutConnection->Pin, Index, PinsSrcRef);
+ Status = MMixerAddMixerSourceLines(MixerContext, MixerInfo, MixerData->hDevice, NodeConnections, NodeTypes, PinsRefCount, OutConnection->Pin, Index, PinsSrcRef);
MixerContext->Free(MixerControls);
MixerContext->Free(PinsSrcRef);
MMixerInitializeFilter(
IN PMIXER_CONTEXT MixerContext,
IN PMIXER_LIST MixerList,
- IN HANDLE hMixer,
- IN LPWSTR DeviceName,
+ IN LPMIXER_DATA MixerData,
IN PKSMULTIPLE_ITEM NodeTypes,
IN PKSMULTIPLE_ITEM NodeConnections,
IN ULONG PinCount,
ULONG Index;
ULONG * Pins;
ULONG bUsed;
+ ULONG BytesReturned;
+ KSP_PIN Pin;
+ LPWSTR Buffer = NULL;
// allocate a mixer info struct
MixerInfo = (LPMIXER_INFO) MixerContext->Alloc(sizeof(MIXER_INFO));
MixerInfo->MixCaps.vDriverVersion = 1; //FIXME
MixerInfo->MixCaps.fdwSupport = 0;
MixerInfo->MixCaps.cDestinations = 1;
- MixerInfo->hMixer = hMixer;
+ MixerInfo->hMixer = MixerData->hDevice;
+
+ // get mixer name
+ MMixerGetDeviceName(MixerContext, MixerInfo, MixerData->hDeviceInterfaceKey);
// initialize line list
InitializeListHead(&MixerInfo->LineList);
- /* FIXME find mixer name */
-
- Status = MMixerCreateDestinationLine(MixerContext, MixerInfo, bInputMixer);
- if (Status != MM_STATUS_SUCCESS)
- {
- // failed to create destination line
- MixerContext->Free(MixerInfo);
- return Status;
- }
-
-
// now allocate an array which will receive the indices of the pin
// which has a ADC / DAC nodetype in its path
Pins = (PULONG)MixerContext->Alloc(PinCount * sizeof(ULONG));
return MM_STATUS_NO_MEMORY;
}
+ // now get the target pins of the ADC / DAC node
+ Status = MMixerGetTargetPins(MixerContext, NodeTypes, NodeConnections, NodeIndex, !bInputMixer, Pins, PinCount);
+
+ for(Index = 0; Index < PinCount; Index++)
+ {
+ if (Pins[Index])
+ {
+ /* retrieve pin name */
+ Pin.PinId = Index;
+ Pin.Reserved = 0;
+ Pin.Property.Flags = KSPROPERTY_TYPE_GET;
+ Pin.Property.Set = KSPROPSETID_Pin;
+ Pin.Property.Id = KSPROPERTY_PIN_NAME;
+
+ /* try get pin name size */
+ Status = MixerContext->Control(MixerData->hDevice, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), NULL, 0, &BytesReturned);
+
+ if (Status == MM_STATUS_MORE_ENTRIES)
+ {
+ Buffer = (LPWSTR)MixerContext->Alloc(BytesReturned);
+ if (Buffer)
+ {
+ /* try get pin name */
+ Status = MixerContext->Control(MixerData->hDevice, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)Buffer, BytesReturned, &BytesReturned);
+ if (Status != MM_STATUS_SUCCESS)
+ {
+ MixerContext->Free((PVOID)Buffer);
+ Buffer = NULL;
+ }
+ else
+ {
+ // found name, done
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ Status = MMixerCreateDestinationLine(MixerContext, MixerInfo, bInputMixer, Buffer);
+
+ if (Buffer)
+ {
+ // free name
+ MixerContext->Free(Buffer);
+ }
+
+ if (Status != MM_STATUS_SUCCESS)
+ {
+ // failed to create destination line
+ MixerContext->Free(MixerInfo);
+ MixerContext->Free(Pins);
+
+ return Status;
+ }
+
+ RtlZeroMemory(Pins, sizeof(ULONG) * PinCount);
// now get the target pins of the ADC / DAC node
Status = MMixerGetTargetPins(MixerContext, NodeTypes, NodeConnections, NodeIndex, bInputMixer, Pins, PinCount);
if (Pins[Index])
{
// check if the pin has a physical connection
- Status = MMixerGetPhysicalConnection(MixerContext, hMixer, Index, &OutConnection);
+ Status = MMixerGetPhysicalConnection(MixerContext, MixerData->hDevice, Index, &OutConnection);
if (Status == MM_STATUS_SUCCESS)
{
// the pin has a physical connection
- Status = MMixerHandlePhysicalConnection(MixerContext, MixerInfo, bInputMixer, OutConnection);
+ Status = MMixerHandlePhysicalConnection(MixerContext, MixerList, MixerInfo, bInputMixer, OutConnection);
DPRINT("MMixerHandlePhysicalConnection status %u\n", Status);
MixerContext->Free(OutConnection);
bUsed = TRUE;
}
+ else
+ {
+ // filter exposes the topology on the same filter
+ MMixerAddMixerSourceLine(MixerContext, MixerInfo, MixerData->hDevice, NodeConnections, NodeTypes, Index, FALSE, FALSE);
+ bUsed = TRUE;
+ }
}
}
MixerContext->Free(Pins);
if (bUsed)
{
// store mixer info in list
- InsertTailList(&MixerList->MixerList, &MixerInfo->Entry);
+ if (!bInputMixer && MixerList->MixerListCount == 1)
+ {
+ //FIXME preferred device should be inserted at front
+ //windows always inserts output mixer in front
+ InsertHeadList(&MixerList->MixerList, &MixerInfo->Entry);
+ }
+ else
+ {
+ InsertTailList(&MixerList->MixerList, &MixerInfo->Entry);
+ }
MixerList->MixerListCount++;
DPRINT("New MixerCount %lu\n", MixerList->MixerListCount);
}
else
{
- // TODO:
- // filter exposes its topology on the same filter
+ // failed to create a mixer topology
MMixerFreeMixerInfo(MixerContext, MixerInfo);
}
MMixerSetupFilter(
IN PMIXER_CONTEXT MixerContext,
IN PMIXER_LIST MixerList,
- IN HANDLE hMixer,
- IN PULONG DeviceCount,
- IN LPWSTR DeviceName)
+ IN LPMIXER_DATA MixerData,
+ IN PULONG DeviceCount)
{
PKSMULTIPLE_ITEM NodeTypes, NodeConnections;
MIXER_STATUS Status;
ULONG NodeIndex;
// get number of pins
- PinCount = MMixerGetFilterPinCount(MixerContext, hMixer);
+ PinCount = MMixerGetFilterPinCount(MixerContext, MixerData->hDevice);
ASSERT(PinCount);
DPRINT("NumOfPins: %lu\n", PinCount);
// get filter node types
- Status = MMixerGetFilterTopologyProperty(MixerContext, hMixer, KSPROPERTY_TOPOLOGY_NODES, &NodeTypes);
+ Status = MMixerGetFilterTopologyProperty(MixerContext, MixerData->hDevice, KSPROPERTY_TOPOLOGY_NODES, &NodeTypes);
if (Status != MM_STATUS_SUCCESS)
{
// failed
}
// get filter node connections
- Status = MMixerGetFilterTopologyProperty(MixerContext, hMixer, KSPROPERTY_TOPOLOGY_CONNECTIONS, &NodeConnections);
+ Status = MMixerGetFilterTopologyProperty(MixerContext, MixerData->hDevice, KSPROPERTY_TOPOLOGY_CONNECTIONS, &NodeConnections);
if (Status != MM_STATUS_SUCCESS)
{
// failed
if (NodeIndex != MAXULONG)
{
// it has
-
- Status = MMixerInitializeFilter(MixerContext, MixerList, hMixer, DeviceName, NodeTypes, NodeConnections, PinCount, NodeIndex, FALSE);
+ Status = MMixerInitializeFilter(MixerContext, MixerList, MixerData, NodeTypes, NodeConnections, PinCount, NodeIndex, FALSE);
DPRINT("MMixerInitializeFilter Status %u\n", Status);
// check for success
if (Status == MM_STATUS_SUCCESS)
if (NodeIndex != MAXULONG)
{
// it has
- Status = MMixerInitializeFilter(MixerContext, MixerList, hMixer, DeviceName, NodeTypes, NodeConnections, PinCount, NodeIndex, TRUE);
+ Status = MMixerInitializeFilter(MixerContext, MixerList, MixerData, NodeTypes, NodeConnections, PinCount, NodeIndex, TRUE);
DPRINT("MMixerInitializeFilter Status %u\n", Status);
// check for success
if (Status == MM_STATUS_SUCCESS)