[MMIXER_TEST]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Sat, 12 Dec 2009 13:40:54 +0000 (13:40 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Sat, 12 Dec 2009 13:40:54 +0000 (13:40 +0000)
- Commit a simple test application to test the mmixer library
- Debug Outputs are appreciated

svn path=/trunk/; revision=44546

rostests/tests/directory.rbuild
rostests/tests/mmixer_test/mmixer_test.rbuild [new file with mode: 0644]
rostests/tests/mmixer_test/test.c [new file with mode: 0644]

index d93671b..1659a6c 100644 (file)
        <directory name="mktime">
                <xi:include href="mktime/mktime.rbuild" />
        </directory>
+       <directory name="mmixer_test">
+               <xi:include href="mmixer_test/mmixer_test.rbuild" />
+       </directory>
+
        <directory name="moztest">
                <xi:include href="moztest/moztest.rbuild" />
        </directory>
diff --git a/rostests/tests/mmixer_test/mmixer_test.rbuild b/rostests/tests/mmixer_test/mmixer_test.rbuild
new file mode 100644 (file)
index 0000000..63248a6
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
+<module name="mmixer_test" type="win32cui" baseaddress="${BASEADDRESS_CONTROL}" installbase="system32" installname="mmixer_test.exe">
+       <include base="ReactOS">include/reactos/libs/sound</include>
+       <include base="mmixer"></include>
+       <library>advapi32</library>
+       <library>setupapi</library>
+       <library>kernel32</library>
+       <library>winmm</library>
+       <library>mmixer</library>
+       <file>test.c</file>
+</module>
\ No newline at end of file
diff --git a/rostests/tests/mmixer_test/test.c b/rostests/tests/mmixer_test/test.c
new file mode 100644 (file)
index 0000000..18b345e
--- /dev/null
@@ -0,0 +1,299 @@
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <setupapi.h>
+#include <ksmedia.h>
+#include <mmsystem.h>
+#include <mmreg.h>
+#include "mmixer.h"
+
+MIXER_CONTEXT MixerContext;
+GUID CategoryGuid = {STATIC_KSCATEGORY_AUDIO};
+
+PVOID Alloc(ULONG NumBytes)
+{
+    //printf("Alloc: %lu\n", NumBytes);
+    return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, NumBytes);
+}
+
+MIXER_STATUS
+Close(HANDLE hDevice)
+{
+    //printf("Close: Handle %p\n", hDevice);
+    if (CloseHandle(hDevice))
+        return MM_STATUS_SUCCESS;
+    else
+        return MM_STATUS_UNSUCCESSFUL;
+}
+
+VOID
+Free(PVOID Block)
+{
+    //printf("Free: %p\n", Block);
+    HeapFree(GetProcessHeap(), 0, Block);
+}
+
+VOID
+Copy(PVOID Src, PVOID Dst, ULONG NumBytes)
+{
+    //printf("Copy: Src %p Dst %p NumBytes %lu\n", Src, Dst, NumBytes);
+    CopyMemory(Src, Dst, NumBytes);
+}
+
+MIXER_STATUS
+Open(
+    IN LPWSTR DevicePath,
+    OUT PHANDLE hDevice)
+{
+     DevicePath[1] = L'\\';
+    *hDevice = CreateFileW(DevicePath,
+                           GENERIC_READ | GENERIC_WRITE,
+                           0,
+                           NULL,
+                           OPEN_EXISTING,
+                           FILE_FLAG_OVERLAPPED,
+                           NULL);
+    if (*hDevice == INVALID_HANDLE_VALUE)
+    {
+        //wprintf(L" Failed to open %s Error %lu\n", DevicePath, GetLastError());
+        return MM_STATUS_UNSUCCESSFUL;
+    }
+    wprintf(L"Open: %s hDevice %p\n", DevicePath, *hDevice);
+
+    return MM_STATUS_SUCCESS;
+}
+
+MIXER_STATUS
+Control(
+    IN HANDLE hMixer,
+    IN ULONG dwIoControlCode,
+    IN PVOID lpInBuffer,
+    IN ULONG nInBufferSize,
+    OUT PVOID lpOutBuffer,
+    ULONG nOutBufferSize,
+    PULONG lpBytesReturned)
+{
+    OVERLAPPED Overlapped;
+    BOOLEAN IoResult;
+    DWORD Transferred = 0;
+
+    //printf("hMixer %p dwIoControlCode %lx lpInBuffer %p nInBufferSize %lu lpOutBuffer %p nOutBufferSize %lu lpBytesReturned %p\n",
+    //        hMixer, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned);
+
+    /* Overlapped I/O is done here - this is used for waiting for completion */
+    ZeroMemory(&Overlapped, sizeof(OVERLAPPED));
+    Overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+    if ( ! Overlapped.hEvent )
+        return MM_STATUS_NO_MEMORY;
+
+    /* Talk to the device */
+    IoResult = DeviceIoControl(hMixer,
+                               dwIoControlCode,
+                               lpInBuffer,
+                               nInBufferSize,
+                               lpOutBuffer,
+                               nOutBufferSize,
+                               &Transferred,
+                               &Overlapped);
+
+    /* If failure occurs, make sure it's not just due to the overlapped I/O */
+    if ( ! IoResult )
+    {
+        if ( GetLastError() != ERROR_IO_PENDING )
+        {
+            CloseHandle(Overlapped.hEvent);
+
+            //printf("Control: Failed with %lu Transferred %lu\n", GetLastError(), Transferred);
+
+            if (GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+            {
+                if ( lpBytesReturned )
+                    *lpBytesReturned = Transferred;
+                return MM_STATUS_MORE_ENTRIES;
+            }
+
+            return MM_STATUS_UNSUCCESSFUL;
+        }
+    }
+
+    /* Wait for the I/O to complete */
+    IoResult = GetOverlappedResult(hMixer,
+                                   &Overlapped,
+                                   &Transferred,
+                                   TRUE);
+
+    /* Don't need this any more */
+    CloseHandle(Overlapped.hEvent);
+
+    if ( ! IoResult )
+        return MM_STATUS_UNSUCCESSFUL;
+
+    //printf("Transferred %lu bytes in Sync overlapped I/O\n", Transferred);
+
+    if ( lpBytesReturned )
+        *lpBytesReturned = Transferred;
+
+    return MM_STATUS_SUCCESS;
+}
+
+MIXER_STATUS
+Enum(
+    IN  PVOID EnumContext,
+    IN  ULONG DeviceIndex,
+    OUT LPWSTR * DeviceName,
+    OUT PHANDLE OutHandle)
+{
+    SP_DEVICE_INTERFACE_DATA InterfaceData;
+    SP_DEVINFO_DATA DeviceData;
+    PSP_DEVICE_INTERFACE_DETAIL_DATA_W DetailData;
+    BOOL Result;
+    DWORD Length;
+
+    //printf("Enum EnumContext %p DeviceIndex %lu OutHandle %p\n", EnumContext, DeviceIndex, OutHandle);
+
+    InterfaceData.cbSize = sizeof(InterfaceData);
+    InterfaceData.Reserved = 0;
+
+    Result = SetupDiEnumDeviceInterfaces(EnumContext,
+                                NULL,
+                                &CategoryGuid,
+                                DeviceIndex,
+                                &InterfaceData);
+
+    if (!Result)
+    {
+        if (GetLastError() == ERROR_NO_MORE_ITEMS)
+        {
+            printf("LastDevice\n");
+            return MM_STATUS_NO_MORE_DEVICES;
+        }
+        printf("SetupDiEnumDeviceInterfaces failed with %lu\n", GetLastError());
+        return MM_STATUS_UNSUCCESSFUL;
+    }
+
+    Length = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + MAX_PATH * sizeof(WCHAR);
+    DetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)HeapAlloc(GetProcessHeap(),
+                                                             0,
+                                                             Length);
+    DetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
+    DeviceData.cbSize = sizeof(DeviceData);
+    DeviceData.Reserved = 0;
+
+    Result = SetupDiGetDeviceInterfaceDetailW(EnumContext,
+                                    &InterfaceData,
+                                    DetailData,
+                                    Length,
+                                    NULL,
+                                    &DeviceData);
+
+    if (!Result)
+    {
+        printf("SetupDiGetDeviceInterfaceDetailW failed with %lu\n", GetLastError());
+        return MM_STATUS_UNSUCCESSFUL;
+    }
+
+    // copy path
+    *DeviceName = (LPWSTR)&DetailData->DevicePath[0];
+    return Open(DetailData->DevicePath, OutHandle);
+}
+
+
+int main(int argc, char**argv)
+{
+    MIXER_STATUS Status;
+    HDEVINFO DeviceHandle;
+    MIXERCAPSW MixCaps1, MixCaps2;
+    ULONG Index, SubIndex;
+    HANDLE hMixer2;
+    HMIXER hMixer1;
+    MIXERLINEW MixerLine1, MixerLine2;
+    MIXERLINECONTROLS Controls1, Controls2;
+
+    ZeroMemory(&MixerContext, sizeof(MIXER_CONTEXT));
+
+    DeviceHandle = SetupDiGetClassDevs(&CategoryGuid,
+                                       NULL,
+                                       NULL,
+                                       DIGCF_DEVICEINTERFACE|DIGCF_PRESENT);
+    if (DeviceHandle == INVALID_HANDLE_VALUE)
+    {
+        printf("SetupDiGetClassDevs failed with %lx\n", GetLastError());
+        return 0;
+    }
+
+    printf("DeviceHandle %p\n", DeviceHandle);
+
+    MixerContext.SizeOfStruct = sizeof(MIXER_CONTEXT);
+    MixerContext.Alloc = Alloc;
+    MixerContext.Close = Close;
+    MixerContext.Control = Control;
+    MixerContext.Copy = Copy;
+    MixerContext.Free = Free;
+    MixerContext.Open = Open;
+
+    Status = MMixerInitialize(&MixerContext, Enum, (PVOID)DeviceHandle);
+
+    printf("Status %x\n", Status);
+    printf("NumberOfMixers %lu mixerGetNumDevs %u\n", MMixerGetCount(&MixerContext), mixerGetNumDevs());
+
+    for(Index = 0; Index < MMixerGetCount(&MixerContext); Index++)
+    {
+        mixerGetDevCapsW(Index, &MixCaps1, sizeof(MIXERCAPSW));
+        wprintf(L"WINM: cDestination %u fdwSupport %lx szPname %s vDriverVersion %u wMid %x wPid %x\n", MixCaps1.cDestinations, MixCaps1.fdwSupport, MixCaps1.szPname, MixCaps1.vDriverVersion, MixCaps1.wMid, MixCaps1.wPid);
+        MMixerGetCapabilities(&MixerContext, Index, &MixCaps2);
+        wprintf(L"MMIX: cDestination %u fdwSupport %lx szPname %s vDriverVersion %u wMid %x wPid %x\n", MixCaps2.cDestinations, MixCaps2.fdwSupport, MixCaps2.szPname, MixCaps2.vDriverVersion, MixCaps2.wMid, MixCaps2.wPid);
+
+        mixerOpen(&hMixer1, Index, 0, 0, MIXER_OBJECTF_HMIXER);
+        MMixerOpen(&MixerContext, Index, NULL, NULL, &hMixer2);
+
+        ZeroMemory(&MixerLine1, sizeof(MIXERLINEW));
+        ZeroMemory(&MixerLine2, sizeof(MIXERLINEW));
+        MixerLine1.cbStruct = sizeof(MIXERLINEW);
+        MixerLine2.cbStruct = sizeof(MIXERLINEW);
+        mixerGetLineInfoW((HMIXEROBJ)hMixer1, &MixerLine1, MIXER_GETLINEINFOF_DESTINATION);
+        MMixerGetLineInfo(&MixerContext, hMixer2, MIXER_GETLINEINFOF_DESTINATION, &MixerLine2);
+
+        wprintf(L"WINM: dwDestination %lx dwSource %lx dwLineID %lx dwUser %lx dwComponentType %lx cChannels %lx cConnections %lx cControls %lx szShortName %s szName %s\n\n",
+                MixerLine1.dwDestination, MixerLine1.dwSource, MixerLine1.dwLineID, MixerLine1.dwUser, MixerLine1.dwComponentType, MixerLine1.cChannels, MixerLine1.cConnections, MixerLine1.cControls, MixerLine1.szShortName, MixerLine1.szName);
+
+        wprintf(L"MMIX: dwDestination %lx dwSource %lx dwLineID %lx dwUser %lx dwComponentType %lx cChannels %lx cConnections %lx cControls %lx szShortName %s szName %s\n\n",
+                MixerLine2.dwDestination, MixerLine2.dwSource, MixerLine2.dwLineID, MixerLine2.dwUser, MixerLine2.dwComponentType, MixerLine2.cChannels, MixerLine2.cConnections, MixerLine2.cControls, MixerLine2.szShortName, MixerLine2.szName);
+
+        Controls1.cbStruct = sizeof(MIXERLINECONTROLS);
+        Controls2.cbStruct = sizeof(MIXERLINECONTROLS);
+
+        Controls1.cbmxctrl = sizeof(MIXERCONTROL);
+        Controls2.cbmxctrl = sizeof(MIXERCONTROL);
+
+        Controls1.cControls = MixerLine1.cControls;
+        Controls2.cControls = MixerLine2.cControls;
+
+        Controls1.dwLineID = MixerLine1.dwLineID;
+        Controls2.dwLineID = MixerLine2.dwLineID;
+
+
+
+        Controls1.pamxctrl = (LPMIXERCONTROL)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MIXERCONTROL) * Controls1.cControls);
+        Controls2.pamxctrl = (LPMIXERCONTROL)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MIXERCONTROL) * Controls2.cControls);
+
+        for(SubIndex = 0; SubIndex < Controls1.cControls; SubIndex++)
+            Controls1.pamxctrl[SubIndex].cbStruct = sizeof(MIXERCONTROL);
+
+        for(SubIndex = 0; SubIndex < Controls2.cControls; SubIndex++)
+            Controls2.pamxctrl[SubIndex].cbStruct = sizeof(MIXERCONTROL);
+
+        mixerGetLineControls((HMIXEROBJ)hMixer1, &Controls1, MIXER_GETLINECONTROLSF_ALL);
+
+        wprintf(L"----------------------------------------\n");
+        for(SubIndex = 0; SubIndex < Controls1.cControls; SubIndex++)
+        {
+            wprintf(L"WINM: Index %d dwControlID %lx dwControlType %lx fdwControl %lx cMultipleItems %lx szName %s szShortName %s \n", SubIndex, Controls1.pamxctrl[SubIndex].dwControlID, Controls1.pamxctrl[SubIndex].dwControlType, Controls1.pamxctrl[SubIndex].fdwControl, Controls1.pamxctrl[SubIndex].cMultipleItems, Controls1.pamxctrl[SubIndex].szName, Controls1.pamxctrl[SubIndex].szShortName);
+        }
+        wprintf(L"----------------------------------------\n");
+
+
+        wprintf(L"=======================\n");
+    }
+    return 0;
+}