- Fix a few bugs in the sample rate conversion code

- Might fix playback for audio samples out of audio adapter supported range

svn path=/trunk/; revision=41830
This commit is contained in:
Johannes Anderwald 2009-07-09 14:09:27 +00:00
parent 7b83de4325
commit c70e3fd433

View file

@ -34,6 +34,8 @@ PerformSampleRateConversion(
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 @@ PerformSampleRateConversion(
return Status;
}
NumSamples = BufferLength / BytesPerSample;
NumSamples = BufferLength / (BytesPerSample * NumChannels);
FloatIn = ExAllocatePool(NonPagedPool, NumSamples * sizeof(FLOAT));
FloatIn = ExAllocatePool(NonPagedPool, NumSamples * NumChannels * sizeof(FLOAT));
if (!FloatIn)
{
KeRestoreFloatingPointState(&FloatSave);
@ -54,7 +56,7 @@ PerformSampleRateConversion(
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 @@ PerformSampleRateConversion(
return STATUS_INSUFFICIENT_RESOURCES;
}
ResultOut = ExAllocatePool(NonPagedPool, NewSamples * (BytesPerSample/8));
ResultOut = ExAllocatePool(NonPagedPool, NewSamples * NumChannels * BytesPerSample);
if (!FloatOut)
{
ExFreePool(FloatIn);
@ -83,31 +85,24 @@ PerformSampleRateConversion(
}
/* fixme use asm */
if (BytesPerSample == 8)
if (BytesPerSample == 1)
{
for(Index = 0; Index < NumSamples; Index++)
FloatIn[Index] = (float)Buffer[Index];
for(Index = 0; Index < NumSamples * NumChannels; Index++)
FloatIn[Index] = (float)(Buffer[Index] / (1.0 * 0x80));
}
else if (BytesPerSample == 16)
else if (BytesPerSample == 2)
{
PUSHORT Res = (PUSHORT)ResultOut;
for(Index = 0; Index < NumSamples; Index++)
FloatIn[Index] = (float)_byteswap_ushort(Res[Index]);
src_short_to_float_array((short*)Buffer, FloatIn, NumSamples * NumChannels);
}
else
else if (BytesPerSample == 4)
{
UNIMPLEMENTED
KeRestoreFloatingPointState(&FloatSave);
ExFreePool(FloatIn);
ExFreePool(FloatOut);
ExFreePool(ResultOut);
return STATUS_UNSUCCESSFUL;
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 @@ PerformSampleRateConversion(
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]);
ResultOut[Index] = (lrintf(FloatOut[Index]) >> 24);
}
else if (BytesPerSample == 16)
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 @@ Pin_fnFastWrite(
StreamHeader->DataUsed,
InputFormat->WaveFormatEx.nSamplesPerSec,
OutputFormat->WaveFormatEx.nSamplesPerSec,
OutputFormat->WaveFormatEx.wBitsPerSample,
OutputFormat->WaveFormatEx.wBitsPerSample / 8,
OutputFormat->WaveFormatEx.nChannels,
&BufferOut,
&BufferLength);