aboutsummaryrefslogtreecommitdiff
path: root/Src/Winamp/SABuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Winamp/SABuffer.cpp')
-rw-r--r--Src/Winamp/SABuffer.cpp139
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;
+}
+