#include "SABuffer.h" #include "fft.h" #include "../nsutil/window.h" #include 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; }