mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 15:46:13 +00:00
[MMIXER_TEST]
- Commit a simple test application to test the mmixer library - Debug Outputs are appreciated svn path=/trunk/; revision=44546
This commit is contained in:
parent
1caea1d387
commit
35f22b3c5c
3 changed files with 315 additions and 0 deletions
|
@ -139,6 +139,10 @@
|
|||
<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>
|
||||
|
|
12
rostests/tests/mmixer_test/mmixer_test.rbuild
Normal file
12
rostests/tests/mmixer_test/mmixer_test.rbuild
Normal file
|
@ -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>
|
299
rostests/tests/mmixer_test/test.c
Normal file
299
rostests/tests/mmixer_test/test.c
Normal file
|
@ -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;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue