Showing the changes to Spectacle/genlib/Odelay.cpp (1 of 32 files). Show all
Unified · Split
| @@ -0,0 +1,145 @@ | |||
| 1 | /* RTcmix - Copyright (C) 2004 The RTcmix Development Team | ||
| 2 | See ``AUTHORS'' for a list of contributors. See ``LICENSE'' for | ||
| 3 | the license to this software and for a DISCLAIMER OF ALL WARRANTIES. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include "Odelay.h" | ||
| 7 | #include <stdlib.h> | ||
| 8 | #include <string.h> | ||
| 9 | #include <assert.h> | ||
| 10 | #include <stdio.h> | ||
| 11 | |||
| 12 | Odelay::Odelay(long defaultLength) : _dline(NULL), _len(0) | ||
| 13 | { | ||
| 14 | if (defaultLength > 0) { | ||
| 15 | _outpoint = 0; | ||
| 16 | resize(defaultLength); | ||
| 17 | clear(); | ||
| 18 | _inpoint = _len - 1; | ||
| 19 | } | ||
| 20 | else { | ||
| 21 | printf("****program error: Odelay defaultLength not > 0\n"); | ||
| 22 | assert(defaultLength > 0); // doesn't print anything in Max/MSP or console | ||
| 23 | } | ||
| 24 | } | ||
| 25 | |||
| 26 | Odelay::~Odelay() | ||
| 27 | { | ||
| 28 | free(_dline); | ||
| 29 | } | ||
| 30 | |||
| 31 | void Odelay::clear() | ||
| 32 | { | ||
| 33 | for (long i = 0; i < _len; i++) | ||
| 34 | _dline[i] = 0.0; | ||
| 35 | _lastout = 0.0; | ||
| 36 | } | ||
| 37 | |||
| 38 | void Odelay::fill(double val) | ||
| 39 | { | ||
| 40 | for (long i = 0; i < _len; i++) | ||
| 41 | _dline[i] = val; | ||
| 42 | _lastout = val; | ||
| 43 | } | ||
| 44 | |||
| 45 | void Odelay::putsamp(float samp) | ||
| 46 | { | ||
| 47 | _dline[_inpoint++] = samp; | ||
| 48 | if (_inpoint == _len) | ||
| 49 | _inpoint = 0; | ||
| 50 | } | ||
| 51 | |||
| 52 | float Odelay::getsamp(double lagsamps) | ||
| 53 | { | ||
| 54 | _outpoint = _inpoint - (long) lagsamps; | ||
| 55 | #ifdef AUTOEXPAND | ||
| 56 | if (lagsamps >= (double) _len) | ||
| 57 | resize((long)(lagsamps + 0.5)); | ||
| 58 | #endif | ||
| 59 | if (_len > 0) { | ||
| 60 | while (_outpoint < 0) | ||
| 61 | _outpoint += _len; | ||
| 62 | } | ||
| 63 | return _lastout = _dline[_outpoint++]; | ||
| 64 | } | ||
| 65 | |||
| 66 | // Set output pointer <_outpoint>. | ||
| 67 | |||
| 68 | void Odelay::setdelay(double lagsamps) | ||
| 69 | { | ||
| 70 | _outpoint = _inpoint - (long) lagsamps; | ||
| 71 | #ifdef AUTOEXPAND | ||
| 72 | if (lagsamps >= (double) _len) | ||
| 73 | resize((long)(lagsamps + 0.5)); | ||
| 74 | #endif | ||
| 75 | if (_len > 0) { | ||
| 76 | while (_outpoint < 0) | ||
| 77 | _outpoint += _len; | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | float Odelay::next(float input) | ||
| 82 | { | ||
| 83 | _dline[_inpoint++] = input; | ||
| 84 | if (_inpoint == _len) | ||
| 85 | _inpoint = 0; | ||
| 86 | _lastout = _dline[_outpoint++]; | ||
| 87 | if (_outpoint == _len) | ||
| 88 | _outpoint = 0; | ||
| 89 | return _lastout; | ||
| 90 | } | ||
| 91 | |||
| 92 | static float *newFloats(float *oldptr, long oldlen, long *newlen) | ||
| 93 | { | ||
| 94 | float *ptr = NULL; | ||
| 95 | if (oldptr == NULL) { | ||
| 96 | ptr = (float *) malloc(*newlen * sizeof(float)); | ||
| 97 | } | ||
| 98 | else { | ||
| 99 | float *newptr = (float *) realloc(oldptr, *newlen * sizeof(float)); | ||
| 100 | if (newptr) { | ||
| 101 | ptr = newptr; | ||
| 102 | // Zero out new portion. | ||
| 103 | for (long n = oldlen; n < *newlen; ++n) | ||
| 104 | ptr[n] = 0.0f; | ||
| 105 | } | ||
| 106 | else { | ||
| 107 | *newlen = oldlen; // notify caller that realloc failed | ||
| 108 | ptr = oldptr; | ||
| 109 | } | ||
| 110 | } | ||
| 111 | return ptr; | ||
| 112 | } | ||
| 113 | |||
| 114 | int Odelay::resize(long thisLength) | ||
| 115 | { | ||
| 116 | const long oldlen = _len; | ||
| 117 | |||
| 118 | if (thisLength == oldlen) | ||
| 119 | return oldlen; | ||
| 120 | |||
| 121 | // For Max/MSP we rely on object to manage maxdeltime and don't take advantage | ||
| 122 | // of Doug's code to automatically resize delay lines. | ||
| 123 | #ifdef AUTOEXPAND | ||
| 124 | // Make a guess at how big the new array should be. | ||
| 125 | long newlen = (thisLength < _len * 2) ? _len * 2 : _len + thisLength; | ||
| 126 | #else | ||
| 127 | long newlen = thisLength; | ||
| 128 | #endif | ||
| 129 | _dline = ::newFloats(_dline, _len, &newlen); | ||
| 130 | if (_outpoint < 0 && newlen > 0) { | ||
| 131 | while (_outpoint < 0) | ||
| 132 | _outpoint += oldlen; | ||
| 133 | long shift = newlen - oldlen; | ||
| 134 | memcpy(&_dline[_outpoint + shift], | ||
| 135 | &_dline[_outpoint], | ||
| 136 | sizeof(float) * (oldlen - _outpoint)); | ||
| 137 | _outpoint += shift; | ||
| 138 | } | ||
| 139 | return _len = newlen; | ||
| 140 | } | ||
| 141 | |||
| 142 | float Odelay::delay() const | ||
| 143 | { | ||
| 144 | return (float) (_len > 0) ? abs((_outpoint - _inpoint) % _len) : 0; | ||
| 145 | } | ||