diff options
Diffstat (limited to 'Src/Winamp/SABuffer.cpp')
-rw-r--r-- | Src/Winamp/SABuffer.cpp | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/Src/Winamp/SABuffer.cpp b/Src/Winamp/SABuffer.cpp new file mode 100644 index 00000000..dfe47c6c --- /dev/null +++ b/Src/Winamp/SABuffer.cpp @@ -0,0 +1,139 @@ +#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; +} + |