Author: janderwald
Date: Thu Jul 9 18:09:27 2009
New Revision: 41830
URL:
http://svn.reactos.org/svn/reactos?rev=41830&view=rev
Log:
- Fix a few bugs in the sample rate conversion code
- Might fix playback for audio samples out of audio adapter supported range
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] Thu Jul 9 18:09:27
2009
@@ -34,6 +34,8 @@
DPRINT("PerformSampleRateConversion OldRate %u NewRate %u BytesPerSample %u
NumChannels %u Irql %u\n", OldRate, NewRate, BytesPerSample, NumChannels,
KeGetCurrentIrql());
+ ASSERT(BytesPerSample == 1 || BytesPerSample == 2 || BytesPerSample == 4);
+
/* first acquire float save context */
Status = KeSaveFloatingPointState(&FloatSave);
@@ -43,9 +45,9 @@
return Status;
}
- NumSamples = BufferLength / BytesPerSample;
-
- FloatIn = ExAllocatePool(NonPagedPool, NumSamples * sizeof(FLOAT));
+ NumSamples = BufferLength / (BytesPerSample * NumChannels);
+
+ FloatIn = ExAllocatePool(NonPagedPool, NumSamples * NumChannels * sizeof(FLOAT));
if (!FloatIn)
{
KeRestoreFloatingPointState(&FloatSave);
@@ -54,7 +56,7 @@
NewSamples = lrintf(((FLOAT)NumSamples * ((FLOAT)NewRate / (FLOAT)OldRate))) + 2;
- FloatOut = ExAllocatePool(NonPagedPool, NewSamples * sizeof(FLOAT));
+ FloatOut = ExAllocatePool(NonPagedPool, NewSamples * NumChannels * sizeof(FLOAT));
if (!FloatOut)
{
ExFreePool(FloatIn);
@@ -62,7 +64,7 @@
return STATUS_INSUFFICIENT_RESOURCES;
}
- ResultOut = ExAllocatePool(NonPagedPool, NewSamples * (BytesPerSample/8));
+ ResultOut = ExAllocatePool(NonPagedPool, NewSamples * NumChannels * BytesPerSample);
if (!FloatOut)
{
ExFreePool(FloatIn);
@@ -83,31 +85,24 @@
}
/* fixme use asm */
- if (BytesPerSample == 8)
- {
- for(Index = 0; Index < NumSamples; Index++)
- FloatIn[Index] = (float)Buffer[Index];
- }
- else if (BytesPerSample == 16)
- {
- PUSHORT Res = (PUSHORT)ResultOut;
- for(Index = 0; Index < NumSamples; Index++)
- FloatIn[Index] = (float)_byteswap_ushort(Res[Index]);
- }
- else
- {
- UNIMPLEMENTED
- KeRestoreFloatingPointState(&FloatSave);
- ExFreePool(FloatIn);
- ExFreePool(FloatOut);
- ExFreePool(ResultOut);
- return STATUS_UNSUCCESSFUL;
+ if (BytesPerSample == 1)
+ {
+ for(Index = 0; Index < NumSamples * NumChannels; Index++)
+ FloatIn[Index] = (float)(Buffer[Index] / (1.0 * 0x80));
+ }
+ else if (BytesPerSample == 2)
+ {
+ src_short_to_float_array((short*)Buffer, FloatIn, NumSamples * NumChannels);
+ }
+ else if (BytesPerSample == 4)
+ {
+ src_int_to_float_array((int*)Buffer, FloatIn, NumSamples * NumChannels);
}
Data.data_in = FloatIn;
Data.data_out = FloatOut;
- Data.input_frames = NumSamples / NumChannels;
- Data.output_frames = NewSamples / NumChannels;
+ Data.input_frames = NumSamples;
+ Data.output_frames = NewSamples;
Data.src_ratio = (double)NewRate / (double)OldRate;
error = src_process(State, &Data);
@@ -121,26 +116,33 @@
return STATUS_UNSUCCESSFUL;
}
- if (BytesPerSample == 8)
- {
+ if (BytesPerSample == 1)
+ {
+ /* FIXME perform over/under clipping */
+
for(Index = 0; Index < Data.output_frames_gen * NumChannels; Index++)
- ResultOut[Index] = lrintf(FloatOut[Index]);
- }
- else if (BytesPerSample == 16)
+ ResultOut[Index] = (lrintf(FloatOut[Index]) >> 24);
+ }
+ else if (BytesPerSample == 2)
{
PUSHORT Res = (PUSHORT)ResultOut;
- for(Index = 0; Index < Data.output_frames_gen * NumChannels; Index++)
- Res[Index] = _byteswap_ushort(lrintf(FloatOut[Index]));
- }
+ src_float_to_short_array(FloatIn, (short*)Res, Data.output_frames_gen *
NumChannels);
+ }
+ else if (BytesPerSample == 4)
+ {
+ PULONG Res = (PULONG)ResultOut;
+
+ src_float_to_int_array(FloatIn, (int*)Res, Data.output_frames_gen *
NumChannels);
+ }
+
*Result = ResultOut;
- *ResultLength = Data.output_frames_gen * (BytesPerSample/8) * NumChannels;
+ *ResultLength = Data.output_frames_gen * BytesPerSample * NumChannels;
ExFreePool(FloatIn);
ExFreePool(FloatOut);
src_delete(State);
KeRestoreFloatingPointState(&FloatSave);
-
return STATUS_SUCCESS;
}
@@ -654,7 +656,7 @@
StreamHeader->DataUsed,
InputFormat->WaveFormatEx.nSamplesPerSec,
OutputFormat->WaveFormatEx.nSamplesPerSec,
-
OutputFormat->WaveFormatEx.wBitsPerSample,
+ OutputFormat->WaveFormatEx.wBitsPerSample
/ 8,
OutputFormat->WaveFormatEx.nChannels,
&BufferOut,
&BufferLength);