Author: janderwald Date: Thu Mar 5 00:13:10 2009 New Revision: 39877
URL: http://svn.reactos.org/svn/reactos?rev=39877&view=rev Log: - Start implementing kmixer
Added: trunk/reactos/drivers/wdm/audio/filters/directory.rbuild (with props) trunk/reactos/drivers/wdm/audio/filters/kmixer/filter.c (with props) trunk/reactos/drivers/wdm/audio/filters/kmixer/kmixer.c (with props) trunk/reactos/drivers/wdm/audio/filters/kmixer/kmixer.h (with props) trunk/reactos/drivers/wdm/audio/filters/kmixer/kmixer.rbuild (with props) trunk/reactos/drivers/wdm/audio/filters/kmixer/pin.c (with props) Modified: trunk/reactos/drivers/wdm/audio/directory.rbuild
Modified: trunk/reactos/drivers/wdm/audio/directory.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/directory... ============================================================================== --- trunk/reactos/drivers/wdm/audio/directory.rbuild [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/directory.rbuild [iso-8859-1] Thu Mar 5 00:13:10 2009 @@ -10,6 +10,9 @@ <directory name="drm"> <xi:include href="drm/directory.rbuild" /> </directory> + <directory name="filters"> + <xi:include href="filters/directory.rbuild" /> + </directory> <directory name="legacy"> <xi:include href="legacy/directory.rbuild" /> </directory>
Added: trunk/reactos/drivers/wdm/audio/filters/directory.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/filters/d... ============================================================================== --- trunk/reactos/drivers/wdm/audio/filters/directory.rbuild (added) +++ trunk/reactos/drivers/wdm/audio/filters/directory.rbuild [iso-8859-1] Thu Mar 5 00:13:10 2009 @@ -1,0 +1,7 @@ +<?xml version="1.0"?> +<!DOCTYPE group SYSTEM "../../../../tools/rbuild/project.dtd"> +<group xmlns:xi="http://www.w3.org/2001/XInclude"> + <directory name="kmixer"> + <xi:include href="kmixer/kmixer.rbuild" /> + </directory> +</group>
Propchange: trunk/reactos/drivers/wdm/audio/filters/directory.rbuild ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/drivers/wdm/audio/filters/kmixer/filter.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/filters/k... ============================================================================== --- trunk/reactos/drivers/wdm/audio/filters/kmixer/filter.c (added) +++ trunk/reactos/drivers/wdm/audio/filters/kmixer/filter.c [iso-8859-1] Thu Mar 5 00:13:10 2009 @@ -1,0 +1,254 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/wdm/audio/filters/kmixer/filter.c + * PURPOSE: Filter File Context Header header + * PROGRAMMER: Johannes Anderwald + */ + +#include "kmixer.h" + +NTSTATUS +NTAPI +Dispatch_fnDeviceIoControl( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + + IoStack = IoGetCurrentIrpStackLocation(Irp); + + DPRINT1("Dispatch_fnDeviceIoControl Unhandeled %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode); + DbgBreakPoint(); + + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +Dispatch_fnRead( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + DPRINT1("Dispatch_fnRead called DeviceObject %p Irp %p\n", DeviceObject); + + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +Dispatch_fnWrite( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + DPRINT1("Dispatch_fnWrite called DeviceObject %p Irp %p\n", DeviceObject); + + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +Dispatch_fnFlush( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + DPRINT1("Dispatch_fnFlush called DeviceObject %p Irp %p\n", DeviceObject); + //FIXME + // cleanup resources + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +Dispatch_fnClose( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + DPRINT1("Dispatch_fnClose called DeviceObject %p Irp %p\n", DeviceObject); + + //FIXME + // cleanup resources + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +Dispatch_fnQuerySecurity( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + DPRINT1("Dispatch_fnQuerySecurity called DeviceObject %p Irp %p\n", DeviceObject); + + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +Dispatch_fnSetSecurity( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + + DPRINT1("Dispatch_fnSetSecurity called DeviceObject %p Irp %p\n", DeviceObject); + + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; +} + +BOOLEAN +NTAPI +Dispatch_fnFastDeviceIoControl( + PFILE_OBJECT FileObject, + BOOLEAN Wait, + PVOID InputBuffer, + ULONG InputBufferLength, + PVOID OutputBuffer, + ULONG OutputBufferLength, + ULONG IoControlCode, + PIO_STATUS_BLOCK IoStatus, + PDEVICE_OBJECT DeviceObject) +{ + DPRINT1("Dispatch_fnFastDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject); + + + return FALSE; +} + + +BOOLEAN +NTAPI +Dispatch_fnFastRead( + PFILE_OBJECT FileObject, + PLARGE_INTEGER FileOffset, + ULONG Length, + BOOLEAN Wait, + ULONG LockKey, + PVOID Buffer, + PIO_STATUS_BLOCK IoStatus, + PDEVICE_OBJECT DeviceObject) +{ + DPRINT1("Dispatch_fnFastRead called DeviceObject %p Irp %p\n", DeviceObject); + + return FALSE; + +} + +BOOLEAN +NTAPI +Dispatch_fnFastWrite( + PFILE_OBJECT FileObject, + PLARGE_INTEGER FileOffset, + ULONG Length, + BOOLEAN Wait, + ULONG LockKey, + PVOID Buffer, + PIO_STATUS_BLOCK IoStatus, + PDEVICE_OBJECT DeviceObject) +{ + DPRINT1("Dispatch_fnFastWrite called DeviceObject %p Irp %p\n", DeviceObject); + + return FALSE; +} + +static KSDISPATCH_TABLE DispatchTable = +{ + Dispatch_fnDeviceIoControl, + Dispatch_fnRead, + Dispatch_fnWrite, + Dispatch_fnFlush, + Dispatch_fnClose, + Dispatch_fnQuerySecurity, + Dispatch_fnSetSecurity, + Dispatch_fnFastDeviceIoControl, + Dispatch_fnFastRead, + Dispatch_fnFastWrite, +}; + +NTSTATUS +NTAPI +DispatchCreateKMix( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + NTSTATUS Status; + KSOBJECT_HEADER ObjectHeader; + PIO_STACK_LOCATION IoStatus; + LPWSTR Buffer; + + static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}"; + + IoStatus = IoGetCurrentIrpStackLocation(Irp); + Buffer = IoStatus->FileObject->FileName.Buffer; + + DPRINT1("DispatchCreateKMix entered\n"); + + if (Buffer) + { + /* is the request for a new pin */ + if (!wcsncmp(KS_NAME_PIN, Buffer, wcslen(KS_NAME_PIN))) + { + UNIMPLEMENTED + Status = STATUS_UNSUCCESSFUL; + + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + } + + /* allocate object header */ + Status = KsAllocateObjectHeader(&ObjectHeader, 0, NULL, Irp, &DispatchTable); + + DPRINT1("KsAllocateObjectHeader result %x\n", Status); + /* complete the irp */ + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; +} + +NTSTATUS +NTAPI +KMixAllocateDeviceHeader( + IN PKMIXER_DEVICE_EXT DeviceExtension) +{ + NTSTATUS Status; + PKSOBJECT_CREATE_ITEM CreateItem; + + /* allocate create item */ + CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM)); + if (!CreateItem) + return STATUS_INSUFFICIENT_RESOURCES; + + /* initialize create item struct */ + RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM)); + CreateItem->Create = DispatchCreateKMix; + RtlInitUnicodeString(&CreateItem->ObjectClass, L"KMixer"); + + Status = KsAllocateDeviceHeader(&DeviceExtension->KsDeviceHeader, + 1, + CreateItem); + return Status; +} +
Propchange: trunk/reactos/drivers/wdm/audio/filters/kmixer/filter.c ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/drivers/wdm/audio/filters/kmixer/kmixer.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/filters/k... ============================================================================== --- trunk/reactos/drivers/wdm/audio/filters/kmixer/kmixer.c (added) +++ trunk/reactos/drivers/wdm/audio/filters/kmixer/kmixer.c [iso-8859-1] Thu Mar 5 00:13:10 2009 @@ -1,0 +1,112 @@ +/* + * PROJECT: ReactOS Kernel Streaming Mixer + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/wdm/audio/filters/kmixer/kmixer.c + * PURPOSE: main entry point + * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org) + */ + +#include "kmixer.h" + +NTSTATUS +NTAPI +KMix_Pnp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IrpStack; + + IrpStack = IoGetCurrentIrpStackLocation(Irp); + + DPRINT("KMix_Pnp called for func %x\n", IrpStack->MinorFunction); + + if (IrpStack->MinorFunction == IRP_MN_QUERY_PNP_DEVICE_STATE) + { + Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE; + } + + return KsDefaultDispatchPnp(DeviceObject, Irp); +} + +VOID +NTAPI +KMix_Unload(IN PDRIVER_OBJECT DriverObject) +{ + DPRINT1("SysAudio_Unload called\n"); +} + +NTSTATUS +NTAPI +KMix_InstallDevice( + IN PDRIVER_OBJECT DriverObject) +{ + NTSTATUS Status; + UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\Device\kmixer"); + PDEVICE_OBJECT DeviceObject; + PKMIXER_DEVICE_EXT DeviceExtension; + + DPRINT1("KMix_InstallDevice called\n"); + + /* create the device */ + Status = IoCreateDevice(DriverObject, + sizeof(KMIXER_DEVICE_EXT), + &DeviceName, + FILE_DEVICE_KS, + 0, + FALSE, + &DeviceObject); + + /* check for success */ + if (!NT_SUCCESS(Status)) + { + DPRINT("Failed to create \Device\kmixer !\n"); + return Status; + } + + DeviceExtension = (PKMIXER_DEVICE_EXT)DeviceObject->DeviceExtension; + /* initialize device extension */ + RtlZeroMemory(DeviceExtension, sizeof(KMIXER_DEVICE_EXT)); + + + Status = KMixAllocateDeviceHeader(DeviceExtension); + if (!NT_SUCCESS(Status)) + { + DPRINT1("KMixAllocateDeviceHeader failed with %x\n", Status); + goto cleanup; + } + + /* set io flags */ + DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE; + /* clear initializing flag */ + DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING; + + DPRINT("KMix_InstallDevice result %x\n", Status); + return STATUS_SUCCESS; + +cleanup: + + IoDeleteDevice(DeviceObject); + return Status; +} + + +NTSTATUS +NTAPI +DriverEntry( + PDRIVER_OBJECT DriverObject, + PUNICODE_STRING RegistryPathName) +{ + DPRINT1("KMixer.sys loaded\n"); + + KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CREATE); + KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CLOSE); + KsSetMajorFunctionHandler(DriverObject, IRP_MJ_WRITE); + KsSetMajorFunctionHandler(DriverObject, IRP_MJ_DEVICE_CONTROL); + + DriverObject->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower; + DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = KsDefaultForwardIrp; + DriverObject->MajorFunction[IRP_MJ_PNP] = KMix_Pnp; + DriverObject->DriverUnload = KMix_Unload; + + return KMix_InstallDevice(DriverObject); +}
Propchange: trunk/reactos/drivers/wdm/audio/filters/kmixer/kmixer.c ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/drivers/wdm/audio/filters/kmixer/kmixer.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/filters/k... ============================================================================== --- trunk/reactos/drivers/wdm/audio/filters/kmixer/kmixer.h (added) +++ trunk/reactos/drivers/wdm/audio/filters/kmixer/kmixer.h [iso-8859-1] Thu Mar 5 00:13:10 2009 @@ -1,0 +1,27 @@ +#ifndef KMIXER_H__ +#define KMIXER_H__ + +#include <ntddk.h> +#include <portcls.h> +#include <ks.h> +#include <ksmedia.h> +#define YDEBUG +#include <debug.h> + +#include <samplerate.h> +#include <float_cast.h> + +typedef struct +{ + KSDEVICE_HEADER KsDeviceHeader; + + +}KMIXER_DEVICE_EXT, *PKMIXER_DEVICE_EXT; + +NTSTATUS +NTAPI +KMixAllocateDeviceHeader( + IN PKMIXER_DEVICE_EXT DeviceExtension); + + +#endif
Propchange: trunk/reactos/drivers/wdm/audio/filters/kmixer/kmixer.h ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/drivers/wdm/audio/filters/kmixer/kmixer.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/filters/k... ============================================================================== --- trunk/reactos/drivers/wdm/audio/filters/kmixer/kmixer.rbuild (added) +++ trunk/reactos/drivers/wdm/audio/filters/kmixer/kmixer.rbuild [iso-8859-1] Thu Mar 5 00:13:10 2009 @@ -1,0 +1,15 @@ +<?xml version="1.0"?> +<!DOCTYPE module SYSTEM "../../../../../tools/rbuild/project.dtd"> +<module name="kmixer" type="kernelmodedriver" installbase="system32/drivers" installname="kmixer.sys"> + <include base="kmixer">.</include> + <include base="libsamplerate">.</include> + <library>ntoskrnl</library> + <library>ks</library> + <library>rtl</library> + <library>hal</library> + <library>libcntpr</library> + <library>libsamplerate</library> + <file>kmixer.c</file> + <file>filter.c</file> + <file>pin.c</file> +</module>
Propchange: trunk/reactos/drivers/wdm/audio/filters/kmixer/kmixer.rbuild ------------------------------------------------------------------------------ svn:eol-style = native
Added: trunk/reactos/drivers/wdm/audio/filters/kmixer/pin.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/filters/k... ============================================================================== --- trunk/reactos/drivers/wdm/audio/filters/kmixer/pin.c (added) +++ trunk/reactos/drivers/wdm/audio/filters/kmixer/pin.c [iso-8859-1] Thu Mar 5 00:13:10 2009 @@ -1,0 +1,185 @@ +/* + * PROJECT: ReactOS Kernel Streaming Mixer + * LICENSE: GPL - See COPYING in the top level directory + * FILE: drivers/wdm/audio/filters/kmixer/kmixer.c + * PURPOSE: Pin functions + * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org) + */ + +#include "kmixer.h" + + + +NTSTATUS +PerformSampleRateConversion( + PUCHAR Buffer, + ULONG BufferLength, + ULONG OldRate, + ULONG NewRate, + ULONG BytesPerSample, + ULONG NumChannels, + PVOID * Result, + PULONG ResultLength) +{ + KFLOATING_SAVE FloatSave; + NTSTATUS Status; + ULONG Index; + SRC_STATE * State; + SRC_DATA Data; + PUCHAR ResultOut; + int error; + PFLOAT FloatIn, FloatOut; + ULONG NumSamples; + ULONG NewSamples; + + /* first acquire float save context */ + Status = KeSaveFloatingPointState(&FloatSave); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("KeSaveFloatingPointState failed with %x\n", Status); + return Status; + } + + NumSamples = BufferLength / BytesPerSample; + + FloatIn = ExAllocatePool(NonPagedPool, NumSamples * sizeof(FLOAT)); + if (!FloatIn) + { + KeRestoreFloatingPointState(&FloatSave); + return STATUS_INSUFFICIENT_RESOURCES; + } + + NewSamples = lrintf(((FLOAT)NumSamples * ((FLOAT)OldRate / (FLOAT)NewRate))) + 1; + + FloatOut = ExAllocatePool(NonPagedPool, NewSamples * sizeof(FLOAT)); + if (!FloatOut) + { + ExFreePool(FloatIn); + KeRestoreFloatingPointState(&FloatSave); + return STATUS_INSUFFICIENT_RESOURCES; + } + + ResultOut = ExAllocatePool(NonPagedPool, NewRate * BytesPerSample * NumChannels); + if (!FloatOut) + { + ExFreePool(FloatIn); + ExFreePool(FloatOut); + KeRestoreFloatingPointState(&FloatSave); + return STATUS_INSUFFICIENT_RESOURCES; + } + + State = src_new(SRC_LINEAR, NumChannels, &error); + if (!State) + { + DPRINT1("KeSaveFloatingPointState failed with %x\n", Status); + KeRestoreFloatingPointState(&FloatSave); + ExFreePool(FloatIn); + ExFreePool(FloatOut); + ExFreePool(ResultOut); + return STATUS_UNSUCCESSFUL; + } + + /* fixme use asm */ + if (BytesPerSample == 1) + { + for(Index = 0; Index < NumSamples; Index++) + FloatIn[Index] = (float)Buffer[Index]; + } + else if (BytesPerSample == 2) + { + PUSHORT Res = (PUSHORT)ResultOut; + for(Index = 0; Index < NumSamples; Index++) + FloatIn[Index] = (float)Res[Index]; + } + else + { + UNIMPLEMENTED + KeRestoreFloatingPointState(&FloatSave); + ExFreePool(FloatIn); + ExFreePool(FloatOut); + ExFreePool(ResultOut); + return STATUS_UNSUCCESSFUL; + } + + Data.data_in = FloatIn; + Data.data_out = FloatOut; + Data.input_frames = NumSamples; + Data.output_frames = NewSamples; + Data.src_ratio = (double)NewRate / (double)OldRate; + + error = src_process(State, &Data); + if (error) + { + DPRINT1("src_process failed with %x\n", error); + KeRestoreFloatingPointState(&FloatSave); + ExFreePool(FloatIn); + ExFreePool(FloatOut); + ExFreePool(ResultOut); + return STATUS_UNSUCCESSFUL; + } + + if (BytesPerSample == 1) + { + for(Index = 0; Index < Data.output_frames_gen; Index++) + ResultOut[Index] = lrintf(FloatOut[Index]); + } + else if (BytesPerSample == 2) + { + PUSHORT Res = (PUSHORT)ResultOut; + for(Index = 0; Index < Data.output_frames_gen; Index++) + Res[Index] = lrintf(FloatOut[Index]); + } + + *Result = ResultOut; + *ResultLength = NewRate * BytesPerSample * NumChannels; + ExFreePool(FloatIn); + ExFreePool(FloatOut); + KeRestoreFloatingPointState(&FloatSave); + return STATUS_SUCCESS; +} + + +void * calloc(size_t Elements, size_t ElementSize) +{ + PVOID Block = ExAllocatePool(NonPagedPool, Elements * ElementSize); + if (Block) + RtlZeroMemory(Block, Elements * ElementSize); + + return Block; +} + +void free(PVOID Block) +{ + ExFreePool(Block); +} + +void *memset( + void* dest, + int c, + size_t count) +{ + RtlFillMemory(dest, count, c); + return dest; +} + +void * memcpy( + void* dest, + const void* src, + size_t count) +{ + RtlCopyMemory(dest, src, count); + return dest; +} + +void *memmove( + void* dest, + const void* src, + size_t count) +{ + RtlMoveMemory(dest, src, count); + return dest; +} + + +
Propchange: trunk/reactos/drivers/wdm/audio/filters/kmixer/pin.c ------------------------------------------------------------------------------ svn:eol-style = native