winamp/Src/Winamp/SABuffer.cpp

140 lines
3.5 KiB
C++

#include "SABuffer.h"
#include "fft.h"
#include "../nsutil/window.h"
#include <windows.h>
static const float const_1_div_128_ = 1.0f / 128.0f; /* 8 bit multiplier */
static const float const_1_div_32768_ = 1.0f / 32768.f; /* 16 bit multiplier */
static const double const_1_div_2147483648_ = 1.0 / 2147483648.0; /* 32 bit multiplier */
static void Int16_To_Float32(float *dest, void *sourceBuffer, signed int sourceStride, unsigned int count)
{
signed short *src = (signed short*)sourceBuffer;
while (count--)
{
float samp = *src * const_1_div_32768_; /* FIXME: i'm concerned about this being asymetrical with float->int16 -rb */
*dest = samp;
src += sourceStride;
dest++;
}
}
static void Int24_To_Float32(float *dest, void *sourceBuffer, signed int sourceStride, unsigned int count)
{
unsigned char *src = (unsigned char*)sourceBuffer;
while (count--)
{
signed long temp = (((long)src[0]) << 8);
temp = temp | (((long)src[1]) << 16);
temp = temp | (((long)src[2]) << 24);
*dest = (float)((double)temp * const_1_div_2147483648_);
src += sourceStride * 3;
dest++;
}
}
static void Int32_To_Float32(float *dest, void *sourceBuffer, signed int sourceStride, unsigned int count)
{
int32_t *src = (int32_t *)sourceBuffer;
while (count--)
{
*dest = (float)((double)*src * const_1_div_2147483648_);
src += sourceStride;
dest++;
}
}
static void UInt8_To_Float32(float *dest, void *sourceBuffer, signed int sourceStride, unsigned int count)
{
unsigned char *src = (unsigned char*)sourceBuffer;
while (count--)
{
float samp = (*src - 128) * const_1_div_128_;
*dest = samp;
src += sourceStride;
dest++;
}
}
SABuffer::SABuffer()
{
memset(&buffer, 0, sizeof(buffer));
used=0;
init=false;
}
void SABuffer::CopyHalf()
{
memcpy(buffer[0], buffer[0]+SABUFFER_WINDOW_INCREMENT, (512-SABUFFER_WINDOW_INCREMENT)*sizeof(float));
memcpy(buffer[1], buffer[1]+SABUFFER_WINDOW_INCREMENT, (512-SABUFFER_WINDOW_INCREMENT)*sizeof(float));
used-=SABUFFER_WINDOW_INCREMENT;
}
void SABuffer::Clear()
{
used=0;
}
void SABuffer::WindowToFFTBuffer(float *wavetrum)
{
for (int i=0;i<512;i++)
{
wavetrum[i] = (buffer[0][i] + buffer[1][i]);
//*wavetrum++=0;
}
nsutil_window_Multiply_F32_IP(wavetrum, window, 512);
}
unsigned int SABuffer::AddToBuffer(char *samples, int numChannels, int bps, int ts, unsigned int numSamples)
{
if (!init) {
nsutil_window_FillHann_F32_IP(window, 512); // TODO this could be hardcoded
init=true;
}
unsigned int toCopy = min((unsigned int)(512-used), numSamples);
switch (bps)
{
case 8:
UInt8_To_Float32(buffer[0]+used, samples, numChannels, toCopy);
if (numChannels > 1)
UInt8_To_Float32(buffer[1]+used, samples+1, numChannels, toCopy);
else
UInt8_To_Float32(buffer[1]+used, samples, numChannels, toCopy);
break;
case 16:
Int16_To_Float32(buffer[0]+used, samples, numChannels, toCopy);
if (numChannels > 1)
Int16_To_Float32(buffer[1]+used, samples+2, numChannels, toCopy);
else
Int16_To_Float32(buffer[1]+used, samples, numChannels, toCopy);
break;
case 24:
Int24_To_Float32(buffer[0]+used, samples, numChannels, toCopy);
if (numChannels > 1)
Int24_To_Float32(buffer[1]+used, samples+3, numChannels, toCopy);
else
Int24_To_Float32(buffer[1]+used, samples, numChannels, toCopy);
break;
case 32:
Int32_To_Float32(buffer[0]+used, samples, numChannels, toCopy);
if (numChannels > 1)
Int32_To_Float32(buffer[1]+used, samples+4, numChannels, toCopy);
else
Int32_To_Float32(buffer[1]+used, samples, numChannels, toCopy);
break;
}
used+=toCopy;
return toCopy;
}