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/…
==============================================================================
--- 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;