OLABuffer.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /*
  2. Copyright 2011 Faculte Polytechnique de Mons (TCTS lab)
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include "sekai/OLABuffer.h"
  15. // Source code take from
  16. //<https://github.com/numediart/mage-legacy/blob/master/magelib-2.00/libs/olabox-0.01>,
  17. // this version contains BugFixes
  18. OLABuffer::OLABuffer(int bufferLen) {
  19. length = bufferLen; // init the OLA buffer to 0
  20. rawData = new float[length];
  21. memset(rawData, 0, length * sizeof(float));
  22. pos = 0; // 1st position is buffer head
  23. inputPosition = 0;
  24. atLoc = 0;
  25. }
  26. OLABuffer::~OLABuffer() { delete[] rawData; }
  27. void OLABuffer::ola(float *frame, int frameLen, float period) {
  28. int m, k;
  29. float a = atLoc - ((int)atLoc);
  30. float b = 1 - a;
  31. float nextSample = 0;
  32. for (k = 0; k < frameLen; k++) {
  33. m = (pos + ((int)atLoc) + k) %
  34. length; // we cycle through OLA buffer indices
  35. if (k < frameLen - 1) nextSample = frame[k + 1];
  36. rawData[m] += frame[k] * a + nextSample * b; // and add the current frame
  37. // at location and apply
  38. // fractional delay
  39. }
  40. atLoc += period; // buffer location
  41. inputPosition += period;
  42. }
  43. void OLABuffer::ola(double *frame, int frameLen, float period) {
  44. int m, k;
  45. float a = atLoc - ((int)atLoc);
  46. float b = 1 - a;
  47. float nextSample = 0;
  48. for (k = 0; k < frameLen; k++) {
  49. m = (pos + ((int)atLoc) + k) %
  50. length; // we cycle through OLA buffer indices
  51. if (k < frameLen - 1) nextSample = frame[k + 1];
  52. rawData[m] += frame[k] * a + nextSample * b; // and add the current frame
  53. // at location and apply
  54. // fractional delay
  55. }
  56. atLoc += period; // buffer location
  57. inputPosition += period;
  58. }
  59. bool OLABuffer::isFilled(int size) { return atLoc > size; }
  60. void OLABuffer::pop(float *buffer, int bufferLen) {
  61. if (pos + bufferLen < length) {
  62. // transfer samples to out in one block
  63. memcpy(buffer, &rawData[pos], bufferLen * sizeof(float));
  64. memset(&rawData[pos], 0, bufferLen * sizeof(float));
  65. } else {
  66. // remaining bit
  67. int remain = length - pos;
  68. // transfer/clean from pos to end
  69. memcpy(buffer, &rawData[pos], remain * sizeof(float));
  70. memset(&rawData[pos], 0, remain * sizeof(float));
  71. // transfer/clean from beginning to remaining bit
  72. memcpy(&buffer[remain], rawData, (bufferLen - remain) * sizeof(float));
  73. memset(rawData, 0, (bufferLen - remain) * sizeof(float));
  74. }
  75. // finally move pos to next
  76. pos = (pos + bufferLen) % length;
  77. atLoc -= bufferLen;
  78. }
  79. void OLABuffer::reset() {
  80. pos = 0; // 1st position is buffer head
  81. atLoc = 0;
  82. inputPosition = 0;
  83. memset(rawData, 0, length * sizeof(float));
  84. }