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/kmixer/pin.c?rev=40505&r1=40504&r2=40505&view=diff
==============================================================================
--- 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;

Reply via email to