mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-12-29 18:06:05 +00:00
140 lines
3.5 KiB
C++
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;
|
||
|
}
|
||
|
|