You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

83 lines
2.6KB

  1. #include "ColoredNoise.h"
  2. #include "FFTCrossFader.h"
  3. #include <assert.h>
  4. NoiseMessage* FFTCrossFader::step(float* out)
  5. {
  6. NoiseMessage* usedMessage = nullptr;
  7. if (dataFrames[0] && !dataFrames[1]) {
  8. // just one frame - play it;
  9. *out = dataFrames[0]->dataBuffer->get(curPlayOffset[0]);
  10. advance(0);
  11. } else if (dataFrames[0] && dataFrames[1]) {
  12. // curPlayOffset1 is the index into buffer 1, but also the crossfade index
  13. assert(curPlayOffset[1] < crossfadeSamples);
  14. float buffer0Value = dataFrames[0]->dataBuffer->get(curPlayOffset[0]) *
  15. (crossfadeSamples - (curPlayOffset[1]+1));
  16. float buffer1Value = dataFrames[1]->dataBuffer->get(curPlayOffset[1]) * curPlayOffset[1];
  17. // TODO: do we need to pre-divide
  18. *out = (buffer1Value + buffer0Value) / (crossfadeSamples-1);
  19. if (makeupGain) {
  20. float gain = std::sqrt(2.0f) - 1;
  21. float offset = float(curPlayOffset[1]);
  22. float crossM1 = float(crossfadeSamples - 1);
  23. const float halfFade = crossM1 / 2.f;
  24. // printf(" halfFade = %f offset=%f, crossm1=%f initgain=%f\n", halfFade, offset, crossM1, gain);
  25. if (offset < halfFade) {
  26. gain *= offset / crossM1;
  27. gain *= 2.f;
  28. // printf(" low case, off/cross=%f\n", offset / crossM1);
  29. } else {
  30. gain *= (crossM1 - offset) / crossM1;
  31. gain *= 2;
  32. // printf(" high case, c-off/cross=%f\n", (crossM1 - offset) / crossM1);
  33. }
  34. gain += 1;
  35. *out *= gain;
  36. }
  37. advance(0);
  38. advance(1);
  39. if (curPlayOffset[1] == crossfadeSamples) {
  40. // finished fade, can get rid of 0
  41. usedMessage = dataFrames[0];
  42. dataFrames[0] = dataFrames[1];
  43. curPlayOffset[0] = curPlayOffset[1];
  44. dataFrames[1] = nullptr;
  45. curPlayOffset[1] = 0;
  46. }
  47. } else {
  48. *out = 0;
  49. }
  50. return usedMessage;;
  51. }
  52. void FFTCrossFader::advance(int index)
  53. {
  54. ++curPlayOffset[index];
  55. if (curPlayOffset[index] >= dataFrames[index]->dataBuffer->size()) {
  56. curPlayOffset[index] = 0;
  57. }
  58. }
  59. NoiseMessage * FFTCrossFader::acceptData(NoiseMessage* msg)
  60. {
  61. NoiseMessage* returnedBuffer = nullptr;
  62. if (dataFrames[0] == nullptr) {
  63. dataFrames[0] = msg;
  64. curPlayOffset[0] = 0;
  65. }
  66. else if (dataFrames[1] == nullptr) {
  67. dataFrames[1] = msg;
  68. curPlayOffset[1] = 0;
  69. } else {
  70. // we are full, just ignore this one.
  71. returnedBuffer = msg;
  72. }
  73. return returnedBuffer;
  74. }