123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- /*
- Copyright 2011 Faculte Polytechnique de Mons (TCTS lab)
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- #include "sekai/OLABuffer.h"
- // Source code take from
- //<https://github.com/numediart/mage-legacy/blob/master/magelib-2.00/libs/olabox-0.01>,
- // this version contains BugFixes
- OLABuffer::OLABuffer(int bufferLen) {
- length = bufferLen; // init the OLA buffer to 0
- rawData = new float[length];
- memset(rawData, 0, length * sizeof(float));
- pos = 0; // 1st position is buffer head
- inputPosition = 0;
- atLoc = 0;
- }
- OLABuffer::~OLABuffer() { delete[] rawData; }
- void OLABuffer::ola(float *frame, int frameLen, float period) {
- int m, k;
- float a = atLoc - ((int)atLoc);
- float b = 1 - a;
- float nextSample = 0;
- for (k = 0; k < frameLen; k++) {
- m = (pos + ((int)atLoc) + k) %
- length; // we cycle through OLA buffer indices
- if (k < frameLen - 1) nextSample = frame[k + 1];
- rawData[m] += frame[k] * a + nextSample * b; // and add the current frame
- // at location and apply
- // fractional delay
- }
- atLoc += period; // buffer location
- inputPosition += period;
- }
- void OLABuffer::ola(double *frame, int frameLen, float period) {
- int m, k;
- float a = atLoc - ((int)atLoc);
- float b = 1 - a;
- float nextSample = 0;
- for (k = 0; k < frameLen; k++) {
- m = (pos + ((int)atLoc) + k) %
- length; // we cycle through OLA buffer indices
- if (k < frameLen - 1) nextSample = frame[k + 1];
- rawData[m] += frame[k] * a + nextSample * b; // and add the current frame
- // at location and apply
- // fractional delay
- }
- atLoc += period; // buffer location
- inputPosition += period;
- }
- bool OLABuffer::isFilled(int size) { return atLoc > size; }
- void OLABuffer::pop(float *buffer, int bufferLen) {
- if (pos + bufferLen < length) {
- // transfer samples to out in one block
- memcpy(buffer, &rawData[pos], bufferLen * sizeof(float));
- memset(&rawData[pos], 0, bufferLen * sizeof(float));
- } else {
- // remaining bit
- int remain = length - pos;
- // transfer/clean from pos to end
- memcpy(buffer, &rawData[pos], remain * sizeof(float));
- memset(&rawData[pos], 0, remain * sizeof(float));
- // transfer/clean from beginning to remaining bit
- memcpy(&buffer[remain], rawData, (bufferLen - remain) * sizeof(float));
- memset(rawData, 0, (bufferLen - remain) * sizeof(float));
- }
- // finally move pos to next
- pos = (pos + bufferLen) % length;
- atLoc -= bufferLen;
- }
- void OLABuffer::reset() {
- pos = 0; // 1st position is buffer head
- atLoc = 0;
- inputPosition = 0;
- memset(rawData, 0, length * sizeof(float));
- }
|