Author: janderwald Date: Tue Apr 14 20:43:17 2009 New Revision: 40505
URL: http://svn.reactos.org/svn/reactos?rev=40505&view=rev Log: - Implement Channel de-muxing - WIP, bugs expected
Modified: trunk/reactos/drivers/wdm/audio/filters/kmixer/pin.c
Modified: 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 [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/filters/kmixer/pin.c [iso-8859-1] Tue Apr 14 20:43:17 2009 @@ -9,6 +9,127 @@ #include "kmixer.h"
const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; + +NTSTATUS +PerformChannelConversion( + PUCHAR Buffer, + ULONG BufferLength, + ULONG OldChannels, + ULONG NewChannels, + ULONG BitsPerSample, + PVOID * Result, + PULONG ResultLength) +{ + ULONG Samples; + ULONG NewIndex, OldIndex; + + Samples = BufferLength / (BitsPerSample / 8) / OldChannels; + + if (NewChannels > OldChannels) + { + if (BitsPerSample == 8) + { + PUCHAR BufferOut = ExAllocatePool(NonPagedPool, Samples * NewChannels); + if (!BufferOut) + return STATUS_INSUFFICIENT_RESOURCES; + + for(NewIndex = 0, OldIndex = 0; OldIndex < Samples * OldChannels; NewIndex += NewChannels, OldIndex += OldChannels) + { + ULONG SubIndex = 0; + + RtlMoveMemory(&BufferOut[NewIndex], &Buffer[OldIndex], OldChannels * sizeof(UCHAR)); + + do + { + /* 2 channel stretched to 4 looks like LRLR */ + BufferOut[NewIndex+OldChannels + SubIndex] = Buffer[OldIndex + (SubIndex % OldChannels)]; + }while(SubIndex++ < NewChannels - OldChannels); + } + *Result = BufferOut; + *ResultLength = Samples * NewChannels; + } + else if (BitsPerSample == 16) + { + PUSHORT BufferOut = ExAllocatePool(NonPagedPool, Samples * NewChannels); + if (!BufferOut) + return STATUS_INSUFFICIENT_RESOURCES; + + for(NewIndex = 0, OldIndex = 0; OldIndex < Samples * OldChannels; NewIndex += NewChannels, OldIndex += OldChannels) + { + ULONG SubIndex = 0; + + RtlMoveMemory(&BufferOut[NewIndex], &Buffer[OldIndex], OldChannels * sizeof(USHORT)); + + do + { + BufferOut[NewIndex+OldChannels + SubIndex] = Buffer[OldIndex + (SubIndex % OldChannels)]; + }while(SubIndex++ < NewChannels - OldChannels); + } + *Result = BufferOut; + *ResultLength = Samples * NewChannels; + } + else if (BitsPerSample == 24) + { + PUCHAR BufferOut = ExAllocatePool(NonPagedPool, Samples * NewChannels); + if (!BufferOut) + return STATUS_INSUFFICIENT_RESOURCES; + + for(NewIndex = 0, OldIndex = 0; OldIndex < Samples * OldChannels; NewIndex += NewChannels, OldIndex += OldChannels) + { + ULONG SubIndex = 0; + + RtlMoveMemory(&BufferOut[NewIndex], &Buffer[OldIndex], OldChannels * 3); + + do + { + RtlMoveMemory(&BufferOut[(NewIndex+OldChannels + SubIndex) * 3], &Buffer[(OldIndex + (SubIndex % OldChannels)) * 3], 3); + }while(SubIndex++ < NewChannels - OldChannels); + } + *Result = BufferOut; + *ResultLength = Samples * NewChannels; + } + else if (BitsPerSample == 32) + { + PULONG BufferOut = ExAllocatePool(NonPagedPool, Samples * NewChannels); + if (!BufferOut) + return STATUS_INSUFFICIENT_RESOURCES; + + for(NewIndex = 0, OldIndex = 0; OldIndex < Samples * OldChannels; NewIndex += NewChannels, OldIndex += OldChannels) + { + ULONG SubIndex = 0; + + RtlMoveMemory(&BufferOut[NewIndex], &Buffer[OldIndex], OldChannels * sizeof(ULONG)); + + do + { + BufferOut[NewIndex+OldChannels + SubIndex] = Buffer[OldIndex + (SubIndex % OldChannels)]; + }while(SubIndex++ < NewChannels - OldChannels); + } + *Result = BufferOut; + *ResultLength = Samples * NewChannels; + } + + } + else + { + PUSHORT BufferOut = ExAllocatePool(NonPagedPool, Samples * NewChannels); + if (!BufferOut) + return STATUS_INSUFFICIENT_RESOURCES; + + for(NewIndex = 0, OldIndex = 0; OldIndex < Samples * OldChannels; NewIndex += NewChannels, OldIndex += OldChannels) + { + /* TODO + * mix stream instead of just dumping part of it ;) + */ + RtlMoveMemory(&BufferOut[NewIndex], &Buffer[OldIndex], NewChannels * (BitsPerSample/8)); + } + + *Result = BufferOut; + *ResultLength = Samples * NewChannels; + } + return STATUS_SUCCESS; +} +
NTSTATUS PerformQualityConversion( @@ -359,7 +480,6 @@ InputFormat->WaveFormatEx.nSamplesPerSec, OutputFormat->WaveFormatEx.nSamplesPerSec, InputFormat->WaveFormatEx.wBitsPerSample, OutputFormat->WaveFormatEx.wBitsPerSample);
- if (InputFormat->WaveFormatEx.wBitsPerSample != OutputFormat->WaveFormatEx.wBitsPerSample) { Status = PerformQualityConversion(StreamHeader->Data, @@ -370,7 +490,24 @@ &BufferLength); if (NT_SUCCESS(Status)) { - //DPRINT1("Old BufferSize %u NewBufferSize %u\n", StreamHeader->DataUsed, BufferLength); + ExFreePool(StreamHeader->Data); + StreamHeader->Data = BufferOut; + StreamHeader->DataUsed = BufferLength; + } + } + + if (InputFormat->WaveFormatEx.nChannels != OutputFormat->WaveFormatEx.nChannels) + { + Status = PerformChannelConversion(StreamHeader->Data, + StreamHeader->DataUsed, + InputFormat->WaveFormatEx.nChannels, + OutputFormat->WaveFormatEx.nChannels, + InputFormat->WaveFormatEx.wBitsPerSample, + &BufferOut, + &BufferLength); + + if (NT_SUCCESS(Status)) + { ExFreePool(StreamHeader->Data); StreamHeader->Data = BufferOut; StreamHeader->DataUsed = BufferLength;