From: Johannes Anderwald Date: Sat, 12 Dec 2009 13:40:54 +0000 (+0000) Subject: [MMIXER_TEST] X-Git-Tag: backups/aicom-network-stable@46924~322 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=35f22b3c5c21d693e64f7302ea3c555e880acb42 [MMIXER_TEST] - Commit a simple test application to test the mmixer library - Debug Outputs are appreciated svn path=/trunk/; revision=44546 --- diff --git a/rostests/tests/directory.rbuild b/rostests/tests/directory.rbuild index d93671b3e5d..1659a6cafeb 100644 --- a/rostests/tests/directory.rbuild +++ b/rostests/tests/directory.rbuild @@ -139,6 +139,10 @@ + + + + diff --git a/rostests/tests/mmixer_test/mmixer_test.rbuild b/rostests/tests/mmixer_test/mmixer_test.rbuild new file mode 100644 index 00000000000..63248a6eba6 --- /dev/null +++ b/rostests/tests/mmixer_test/mmixer_test.rbuild @@ -0,0 +1,12 @@ + + + + include/reactos/libs/sound + + advapi32 + setupapi + kernel32 + winmm + mmixer + test.c + \ 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 index 00000000000..18b345eb494 --- /dev/null +++ b/rostests/tests/mmixer_test/test.c @@ -0,0 +1,299 @@ +#include +#include +#include +#include +#include +#include +#include +#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; +}