[AUDIO-BRINGUP]
[reactos.git] / lib / drivers / sound / mmixer / mixer.c
index b4b7dcf..f88ac68 100644 (file)
@@ -89,7 +89,7 @@ MMixerOpen(
     if (Status != MM_STATUS_SUCCESS)
     {
         /* invalid context passed */
-               DPRINT1("invalid context\n");
+        DPRINT1("invalid context\n");
         return Status;
     }
 
@@ -98,7 +98,7 @@ MMixerOpen(
     if (!MixerInfo)
     {
         /* invalid mixer id */
-               DPRINT1("invalid mixer id %lu\n", MixerId);
+        DPRINT1("invalid mixer id %lu\n", MixerId);
         return MM_STATUS_INVALID_PARAMETER;
     }
 
@@ -115,13 +115,15 @@ MMixerOpen(
 MIXER_STATUS
 MMixerGetLineInfo(
     IN PMIXER_CONTEXT MixerContext,
-    IN  HANDLE MixerHandle,
-    IN  ULONG Flags,
+    IN HANDLE MixerHandle,
+    IN ULONG MixerId,
+    IN ULONG Flags,
     OUT LPMIXERLINEW MixerLine)
 {
     MIXER_STATUS Status;
     LPMIXER_INFO MixerInfo;
     LPMIXERLINE_EXT MixerLineSrc;
+    ULONG DestinationLineID;
 
     /* verify mixer context */
     Status = MMixerVerifyContext(MixerContext);
@@ -131,25 +133,55 @@ MMixerGetLineInfo(
         /* invalid context passed */
         return Status;
     }
+    if ((Flags & (MIXER_OBJECTF_MIXER | MIXER_OBJECTF_HMIXER)) == MIXER_OBJECTF_MIXER)
+    {
+        /* caller passed mixer id */
+        MixerHandle = (HANDLE)MMixerGetMixerInfoByIndex(MixerContext, MixerId);
+
+        if (!MixerHandle)
+        {
+            /* invalid parameter */
+            return MM_STATUS_INVALID_PARAMETER;
+        }
+    }
+
+    if (MixerLine->cbStruct != sizeof(MIXERLINEW))
+       {
+               DPRINT1("MixerLine Expected %lu but got %lu\n", sizeof(MIXERLINEW), MixerLine->cbStruct);
+               return MM_STATUS_INVALID_PARAMETER;
+       }
+
 
     /* clear hmixer from flags */
     Flags &=~MIXER_OBJECTF_HMIXER;
 
+    DPRINT1("MMixerGetLineInfo MixerId %lu Flags %lu\n", MixerId, Flags);
+
     if (Flags == MIXER_GETLINEINFOF_DESTINATION)
     {
         /* cast to mixer info */
         MixerInfo = (LPMIXER_INFO)MixerHandle;
 
-        if (MixerLine->dwDestination != 0)
+        /* calculate destination line id */
+        DestinationLineID = (MixerLine->dwDestination + DESTINATION_LINE);
+
+        /* get destination line */
+        MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
+
+        if (MixerLineSrc == NULL)
         {
-            /* destination line member must be zero */
-            return MM_STATUS_INVALID_PARAMETER;
+            DPRINT1("MixerCaps Name %S DestinationLineCount %lu dwDestination %lu not found\n", MixerInfo->MixCaps.szPname, MixerInfo->MixCaps.cDestinations, MixerLine->dwDestination);
+            return MM_STATUS_UNSUCCESSFUL;
         }
-
-        MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, DESTINATION_LINE);
-        ASSERT(MixerLineSrc);
+        /* copy mixer line */
         MixerContext->Copy(MixerLine, &MixerLineSrc->Line, sizeof(MIXERLINEW));
 
+        /* make sure it is null terminated */
+        MixerLine->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
+        MixerLine->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
+        MixerLine->Target.szPname[MAXPNAMELEN-1] = L'\0';
+
+        /* done */
         return MM_STATUS_SUCCESS;
     }
     else if (Flags == MIXER_GETLINEINFOF_SOURCE)
@@ -157,41 +189,71 @@ MMixerGetLineInfo(
         /* cast to mixer info */
         MixerInfo = (LPMIXER_INFO)MixerHandle;
 
+        /* calculate destination line id */
+        DestinationLineID = (MixerLine->dwDestination + DESTINATION_LINE);
 
-        MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, DESTINATION_LINE);
-        ASSERT(MixerLineSrc);
+        /* get destination line */
+        MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
 
-        if (MixerLine->dwSource >= MixerLineSrc->Line.cConnections)
+        if (MixerLineSrc == NULL)
         {
-            DPRINT("dwSource %u > Destinations %u\n", MixerLine->dwSource, MixerLineSrc->Line.cConnections);
-
-            /* invalid parameter */
-            return MM_STATUS_INVALID_PARAMETER;
+            DPRINT1("MixerCaps Name %S DestinationLineCount %lu dwDestination %lu not found\n", MixerInfo->MixCaps.szPname, MixerInfo->MixCaps.cDestinations, MixerLine->dwDestination);
+            return MM_STATUS_UNSUCCESSFUL;
         }
 
-        MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, MixerLine->dwSource * 0x10000);
-        if (MixerLineSrc)
+        /* check if dwSource is out of bounds */
+        if (MixerLine->dwSource >= MixerLineSrc->Line.cConnections)
         {
-            DPRINT("Line %u Name %S\n", MixerLineSrc->Line.dwSource, MixerLineSrc->Line.szName);
-            MixerContext->Copy(MixerLine, &MixerLineSrc->Line, sizeof(MIXERLINEW));
-            return MM_STATUS_SUCCESS;
+            DPRINT1("MixerCaps Name %S MixerLineName %S Connections %lu dwSource %lu not found\n", MixerInfo->MixCaps.szPname, MixerLineSrc->Line.szName, MixerLineSrc->Line.cConnections, MixerLine->dwSource);
+            return MM_STATUS_UNSUCCESSFUL;
         }
-        return MM_STATUS_UNSUCCESSFUL;
+
+        /* calculate destination line id */
+        DestinationLineID = (MixerLine->dwSource * DESTINATION_LINE) + MixerLine->dwDestination;
+
+        /* get target destination line id */
+        MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
+
+        /* sanity check */
+        ASSERT(MixerLineSrc);
+
+        DPRINT("Line %u Name %S\n", MixerLineSrc->Line.dwSource, MixerLineSrc->Line.szName);
+
+        /* copy mixer line */
+        MixerContext->Copy(MixerLine, &MixerLineSrc->Line, sizeof(MIXERLINEW));
+
+        /* make sure it is null terminated */
+        MixerLine->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
+        MixerLine->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
+        MixerLine->Target.szPname[MAXPNAMELEN-1] = L'\0';
+
+        /* done */
+        return MM_STATUS_SUCCESS;
     }
     else if (Flags == MIXER_GETLINEINFOF_LINEID)
     {
         /* cast to mixer info */
         MixerInfo = (LPMIXER_INFO)MixerHandle;
 
+        /* try to find line */
         MixerLineSrc = MMixerGetSourceMixerLineByLineId(MixerInfo, MixerLine->dwLineID);
         if (!MixerLineSrc)
         {
             /* invalid parameter */
+            DPRINT1("MixerName %S Line not found %lu\n", MixerInfo->MixCaps.szPname, MixerLine->dwLineID);
             return MM_STATUS_INVALID_PARAMETER;
         }
 
-        /* copy cached data */
+        DPRINT("Line %u Name %S\n", MixerLineSrc->Line.dwSource, MixerLineSrc->Line.szName);
+
+        /* copy mixer line*/
         MixerContext->Copy(MixerLine, &MixerLineSrc->Line, sizeof(MIXERLINEW));
+
+        /* make sure it is null terminated */
+        MixerLine->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
+        MixerLine->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
+        MixerLine->Target.szPname[MAXPNAMELEN-1] = L'\0';
+
         return MM_STATUS_SUCCESS;
     }
     else if (Flags == MIXER_GETLINEINFOF_COMPONENTTYPE)
@@ -199,6 +261,7 @@ MMixerGetLineInfo(
         /* cast to mixer info */
         MixerInfo = (LPMIXER_INFO)MixerHandle;
 
+        /* find mixer line by component type */
         MixerLineSrc = MMixerGetSourceMixerLineByComponentType(MixerInfo, MixerLine->dwComponentType);
         if (!MixerLineSrc)
         {
@@ -206,12 +269,25 @@ MMixerGetLineInfo(
             return MM_STATUS_UNSUCCESSFUL;
         }
 
-        ASSERT(MixerLineSrc);
-
-        /* copy cached data */
+        /* copy mixer line */
         MixerContext->Copy(MixerLine, &MixerLineSrc->Line, sizeof(MIXERLINEW));
+
+        /* make sure it is null terminated */
+        MixerLine->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
+        MixerLine->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
+        MixerLine->Target.szPname[MAXPNAMELEN-1] = L'\0';
+
+        /* done */
         return MM_STATUS_SUCCESS;
     }
+    else if (Flags == MIXER_GETLINEINFOF_TARGETTYPE)
+    {
+        DPRINT1("MIXER_GETLINEINFOF_TARGETTYPE handling is unimplemented\n");
+    }
+    else
+    {
+        DPRINT1("Unknown Flags %lx handling is unimplemented\n", Flags);
+    }
 
     return MM_STATUS_NOT_IMPLEMENTED;
 }
@@ -220,6 +296,7 @@ MIXER_STATUS
 MMixerGetLineControls(
     IN PMIXER_CONTEXT MixerContext,
     IN HANDLE MixerHandle,
+    IN ULONG MixerId,
     IN ULONG Flags,
     OUT LPMIXERLINECONTROLSW MixerLineControls)
 {
@@ -238,6 +315,18 @@ MMixerGetLineControls(
         return Status;
     }
 
+    if ((Flags & (MIXER_OBJECTF_MIXER | MIXER_OBJECTF_HMIXER)) == MIXER_OBJECTF_MIXER)
+    {
+        /* caller passed mixer id */
+        MixerHandle = (HANDLE)MMixerGetMixerInfoByIndex(MixerContext, MixerId);
+
+        if (!MixerHandle)
+        {
+            /* invalid parameter */
+            return MM_STATUS_INVALID_PARAMETER;
+        }
+    }
+
     Flags &= ~MIXER_OBJECTF_HMIXER;
 
     if (Flags == MIXER_GETLINECONTROLSF_ALL)
@@ -312,6 +401,7 @@ MIXER_STATUS
 MMixerSetControlDetails(
     IN PMIXER_CONTEXT MixerContext,
     IN HANDLE MixerHandle,
+    IN ULONG MixerId,
     IN ULONG Flags,
     OUT LPMIXERCONTROLDETAILS MixerControlDetails)
 {
@@ -330,6 +420,18 @@ MMixerSetControlDetails(
         return Status;
     }
 
+    if ((Flags & (MIXER_OBJECTF_MIXER | MIXER_OBJECTF_HMIXER)) == MIXER_OBJECTF_MIXER)
+    {
+        /* caller passed mixer id */
+        MixerHandle = (HANDLE)MMixerGetMixerInfoByIndex(MixerContext, MixerId);
+
+        if (!MixerHandle)
+        {
+            /* invalid parameter */
+            return MM_STATUS_INVALID_PARAMETER;
+        }
+    }
+
     /* get mixer info */
     MixerInfo = (LPMIXER_INFO)MixerHandle;
 
@@ -362,6 +464,7 @@ MIXER_STATUS
 MMixerGetControlDetails(
     IN PMIXER_CONTEXT MixerContext,
     IN HANDLE MixerHandle,
+    IN ULONG MixerId,
     IN ULONG Flags,
     OUT LPMIXERCONTROLDETAILS MixerControlDetails)
 {
@@ -380,6 +483,18 @@ MMixerGetControlDetails(
         return Status;
     }
 
+    if ((Flags & (MIXER_OBJECTF_MIXER | MIXER_OBJECTF_HMIXER)) == MIXER_OBJECTF_MIXER)
+    {
+        /* caller passed mixer id */
+        MixerHandle = (HANDLE)MMixerGetMixerInfoByIndex(MixerContext, MixerId);
+
+        if (!MixerHandle)
+        {
+            /* invalid parameter */
+            return MM_STATUS_INVALID_PARAMETER;
+        }
+    }
+
     /* get mixer info */
     MixerInfo = (LPMIXER_INFO)MixerHandle;
 
@@ -408,6 +523,66 @@ MMixerGetControlDetails(
     return Status;
 }
 
+VOID
+MMixerPrintMixers(
+    IN PMIXER_CONTEXT MixerContext,
+    IN PMIXER_LIST MixerList)
+{
+    ULONG Index, SubIndex, DestinationLineID;
+    LPMIXER_INFO MixerInfo;
+    LPMIXERLINE_EXT DstMixerLine;
+
+    DPRINT1("MixerList %p\n", MixerList);
+    DPRINT1("MidiInCount %lu\n", MixerList->MidiInListCount);
+    DPRINT1("MidiOutCount %lu\n", MixerList->MidiOutListCount);
+    DPRINT1("WaveInCount %lu\n", MixerList->WaveInListCount);
+    DPRINT1("WaveOutCount %lu\n", MixerList->WaveOutListCount);
+    DPRINT1("MixerCount %p\n", MixerList->MixerListCount);
+
+
+    for(Index = 0; Index < MixerList->MixerListCount; Index++)
+    {
+        /* get mixer info */
+        MixerInfo = MMixerGetMixerInfoByIndex(MixerContext, Index);
+
+        ASSERT(MixerInfo);
+        DPRINT1("\n");
+        DPRINT1("Name :%S\n", MixerInfo->MixCaps.szPname);
+        DPRINT1("cDestinations: %lu\n", MixerInfo->MixCaps.cDestinations);
+        DPRINT1("fdwSupport %lu\n", MixerInfo->MixCaps.fdwSupport);
+        DPRINT1("vDriverVersion %lx\n", MixerInfo->MixCaps.vDriverVersion);
+        DPRINT1("wMid %lx\n", MixerInfo->MixCaps.wMid);
+        DPRINT1("wPid %lx\n", MixerInfo->MixCaps.wPid);
+
+        for(SubIndex = 0; SubIndex < MixerInfo->MixCaps.cDestinations; SubIndex++)
+        {
+            /* calculate destination line id */
+            DestinationLineID = (SubIndex + DESTINATION_LINE);
+
+            /* get destination line */
+            DstMixerLine = MMixerGetSourceMixerLineByLineId(MixerInfo, DestinationLineID);
+            DPRINT1("\n");
+            DPRINT1("cChannels %lu\n", DstMixerLine->Line.cChannels);
+            DPRINT1("cConnections %lu\n", DstMixerLine->Line.cConnections);
+            DPRINT1("cControls %lu\n", DstMixerLine->Line.cControls);
+            DPRINT1("dwComponentType %lx\n", DstMixerLine->Line.dwComponentType);
+            DPRINT1("dwDestination %lu\n", DstMixerLine->Line.dwDestination);
+            DPRINT1("dwLineID %lx\n", DstMixerLine->Line.dwLineID);
+            DPRINT1("dwSource %lx\n", DstMixerLine->Line.dwSource);
+            DPRINT1("dwUser %lu\n", DstMixerLine->Line.dwUser);
+            DPRINT1("fdwLine %lu\n", DstMixerLine->Line.fdwLine);
+            DPRINT1("szName %S\n", DstMixerLine->Line.szName);
+            DPRINT1("szShortName %S\n", DstMixerLine->Line.szShortName);
+            DPRINT1("Target.dwDeviceId %lu\n", DstMixerLine->Line.Target.dwDeviceID);
+            DPRINT1("Target.dwType %lu\n", DstMixerLine->Line.Target.dwType);
+            DPRINT1("Target.szName %S\n", DstMixerLine->Line.Target.szPname);
+            DPRINT1("Target.vDriverVersion %lx\n", DstMixerLine->Line.Target.vDriverVersion);
+            DPRINT1("Target.wMid %lx\n", DstMixerLine->Line.Target.wMid );
+            DPRINT1("Target.wPid %lx\n", DstMixerLine->Line.Target.wPid);
+        }
+    }
+}
+
 MIXER_STATUS
 MMixerInitialize(
     IN PMIXER_CONTEXT MixerContext,
@@ -509,6 +684,8 @@ MMixerInitialize(
         Entry = Entry->Flink;
     }
 
+    MMixerPrintMixers(MixerContext, MixerList);
+
     /* done */
     return MM_STATUS_SUCCESS;
 }