SABuffer.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #include "SABuffer.h"
  2. #include "fft.h"
  3. #include "../nsutil/window.h"
  4. #include <windows.h>
  5. static const float const_1_div_128_ = 1.0f / 128.0f; /* 8 bit multiplier */
  6. static const float const_1_div_32768_ = 1.0f / 32768.f; /* 16 bit multiplier */
  7. static const double const_1_div_2147483648_ = 1.0 / 2147483648.0; /* 32 bit multiplier */
  8. static void Int16_To_Float32(float *dest, void *sourceBuffer, signed int sourceStride, unsigned int count)
  9. {
  10. signed short *src = (signed short*)sourceBuffer;
  11. while (count--)
  12. {
  13. float samp = *src * const_1_div_32768_; /* FIXME: i'm concerned about this being asymetrical with float->int16 -rb */
  14. *dest = samp;
  15. src += sourceStride;
  16. dest++;
  17. }
  18. }
  19. static void Int24_To_Float32(float *dest, void *sourceBuffer, signed int sourceStride, unsigned int count)
  20. {
  21. unsigned char *src = (unsigned char*)sourceBuffer;
  22. while (count--)
  23. {
  24. signed long temp = (((long)src[0]) << 8);
  25. temp = temp | (((long)src[1]) << 16);
  26. temp = temp | (((long)src[2]) << 24);
  27. *dest = (float)((double)temp * const_1_div_2147483648_);
  28. src += sourceStride * 3;
  29. dest++;
  30. }
  31. }
  32. static void Int32_To_Float32(float *dest, void *sourceBuffer, signed int sourceStride, unsigned int count)
  33. {
  34. int32_t *src = (int32_t *)sourceBuffer;
  35. while (count--)
  36. {
  37. *dest = (float)((double)*src * const_1_div_2147483648_);
  38. src += sourceStride;
  39. dest++;
  40. }
  41. }
  42. static void UInt8_To_Float32(float *dest, void *sourceBuffer, signed int sourceStride, unsigned int count)
  43. {
  44. unsigned char *src = (unsigned char*)sourceBuffer;
  45. while (count--)
  46. {
  47. float samp = (*src - 128) * const_1_div_128_;
  48. *dest = samp;
  49. src += sourceStride;
  50. dest++;
  51. }
  52. }
  53. SABuffer::SABuffer()
  54. {
  55. memset(&buffer, 0, sizeof(buffer));
  56. used=0;
  57. init=false;
  58. }
  59. void SABuffer::CopyHalf()
  60. {
  61. memcpy(buffer[0], buffer[0]+SABUFFER_WINDOW_INCREMENT, (512-SABUFFER_WINDOW_INCREMENT)*sizeof(float));
  62. memcpy(buffer[1], buffer[1]+SABUFFER_WINDOW_INCREMENT, (512-SABUFFER_WINDOW_INCREMENT)*sizeof(float));
  63. used-=SABUFFER_WINDOW_INCREMENT;
  64. }
  65. void SABuffer::Clear()
  66. {
  67. used=0;
  68. }
  69. void SABuffer::WindowToFFTBuffer(float *wavetrum)
  70. {
  71. for (int i=0;i<512;i++)
  72. {
  73. wavetrum[i] = (buffer[0][i] + buffer[1][i]);
  74. //*wavetrum++=0;
  75. }
  76. nsutil_window_Multiply_F32_IP(wavetrum, window, 512);
  77. }
  78. unsigned int SABuffer::AddToBuffer(char *samples, int numChannels, int bps, int ts, unsigned int numSamples)
  79. {
  80. if (!init) {
  81. nsutil_window_FillHann_F32_IP(window, 512); // TODO this could be hardcoded
  82. init=true;
  83. }
  84. unsigned int toCopy = min((unsigned int)(512-used), numSamples);
  85. switch (bps)
  86. {
  87. case 8:
  88. UInt8_To_Float32(buffer[0]+used, samples, numChannels, toCopy);
  89. if (numChannels > 1)
  90. UInt8_To_Float32(buffer[1]+used, samples+1, numChannels, toCopy);
  91. else
  92. UInt8_To_Float32(buffer[1]+used, samples, numChannels, toCopy);
  93. break;
  94. case 16:
  95. Int16_To_Float32(buffer[0]+used, samples, numChannels, toCopy);
  96. if (numChannels > 1)
  97. Int16_To_Float32(buffer[1]+used, samples+2, numChannels, toCopy);
  98. else
  99. Int16_To_Float32(buffer[1]+used, samples, numChannels, toCopy);
  100. break;
  101. case 24:
  102. Int24_To_Float32(buffer[0]+used, samples, numChannels, toCopy);
  103. if (numChannels > 1)
  104. Int24_To_Float32(buffer[1]+used, samples+3, numChannels, toCopy);
  105. else
  106. Int24_To_Float32(buffer[1]+used, samples, numChannels, toCopy);
  107. break;
  108. case 32:
  109. Int32_To_Float32(buffer[0]+used, samples, numChannels, toCopy);
  110. if (numChannels > 1)
  111. Int32_To_Float32(buffer[1]+used, samples+4, numChannels, toCopy);
  112. else
  113. Int32_To_Float32(buffer[1]+used, samples, numChannels, toCopy);
  114. break;
  115. }
  116. used+=toCopy;
  117. return toCopy;
  118. }