Unified · Split
| @@ -18,6 +18,10 @@ · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | #endif | 19 | #endif |
| 20 | 20 | ||
| 21 | #if LEAF_DEBUG | ||
| 22 | #include "../../TestPlugin/JuceLibraryCode/JuceHeader.h" | ||
| 23 | #endif | ||
| 24 | |||
| 21 | //=========================================================================== | 25 | //=========================================================================== |
| 22 | /* Envelope Follower */ | 26 | /* Envelope Follower */ |
| 23 | //=========================================================================== | 27 | //=========================================================================== |
| @@ -52,8 +56,8 @@ float tEnvelopeFollower_tick(tEnvelopeFollower* const ef, float x) · 28 unmodified lines | |||
| 52 | if (x < 0.0f ) x = -x; /* Absolute value. */ | 56 | if (x < 0.0f ) x = -x; /* Absolute value. */ |
| 53 | 57 | ||
| 54 | if (isnan(x)) return 0.0f; | 58 | if (isnan(x)) return 0.0f; |
| 55 | if ((x >= e->y) && (x > e->a_thresh)) e->y = x; /* If we hit a peak, ride the peak to the top. */ | 59 | if ((x >= e->y) && (x > e->a_thresh)) e->y = x; /* If we hit a peak, ride the peak to the top. */ |
| 56 | else e->y = e->y * e->d_coeff; /* Else, exponential decay of output. */ | 60 | else e->y = e->y * e->d_coeff; /* Else, exponential decay of output. */ |
| 57 | 61 | ||
| 58 | //ef->y = envelope_pow[(uint16_t)(ef->y * (float)UINT16_MAX)] * ef->d_coeff; //not quite the right behavior - too much loss of precision? | 62 | //ef->y = envelope_pow[(uint16_t)(ef->y * (float)UINT16_MAX)] * ef->d_coeff; //not quite the right behavior - too much loss of precision? |
| 59 | //ef->y = powf(ef->y, 1.000009f) * ef->d_coeff; // too expensive | 63 | //ef->y = powf(ef->y, 1.000009f) * ef->d_coeff; // too expensive |
| @@ -961,7 +965,7 @@ void tZeroCrossingInfo_init (tZeroCrossingInfo* const zc, LEAF* const leaf) · 901 unmodified lines | |||
| 961 | void tZeroCrossingInfo_initToPool (tZeroCrossingInfo* const zc, tMempool* const mp) | 965 | void tZeroCrossingInfo_initToPool (tZeroCrossingInfo* const zc, tMempool* const mp) |
| 962 | { | 966 | { |
| 963 | _tMempool* m = *mp; | 967 | _tMempool* m = *mp; |
| 964 | _tZeroCrossingInfo* z = *zc = (_tZeroCrossingInfo*) mpool_alloc(sizeof(_tZeroCrossingInfo), m); | 968 | _tZeroCrossingInfo* z = *zc = (_tZeroCrossingInfo*) mpool_calloc(sizeof(_tZeroCrossingInfo), m); |
| 965 | z->mempool = m; | 969 | z->mempool = m; |
| 966 | 970 | ||
| 967 | z->_leading_edge = INT_MIN; | 971 | z->_leading_edge = INT_MIN; |
| @@ -1050,7 +1054,9 @@ void tZeroCrossingCollector_initToPool (tZeroCrossingCollector* const zc, · 82 unmodified lines | |||
| 1050 | z->_info = (tZeroCrossingInfo*) mpool_calloc(sizeof(tZeroCrossingInfo) * z->_size, m); | 1054 | z->_info = (tZeroCrossingInfo*) mpool_calloc(sizeof(tZeroCrossingInfo) * z->_size, m); |
| 1051 | 1055 | ||
| 1052 | for (unsigned i = 0; i < z->_size; i++) | 1056 | for (unsigned i = 0; i < z->_size; i++) |
| 1053 | tZeroCrossingInfo_initToPool(&z->_info[i], mp); | 1057 | { |
| 1058 | tZeroCrossingInfo_initToPool(&z->_info[i], mp); | ||
| 1059 | } | ||
| 1054 | 1060 | ||
| 1055 | z->_pos = 0; | 1061 | z->_pos = 0; |
| 1056 | 1062 | ||
| @@ -1068,8 +1074,9 @@ void tZeroCrossingCollector_free (tZeroCrossingCollector* const zc) · 11 unmodified lines | |||
| 1068 | _tZeroCrossingCollector* z = *zc; | 1074 | _tZeroCrossingCollector* z = *zc; |
| 1069 | 1075 | ||
| 1070 | for (unsigned i = 0; i < z->_size; i++) | 1076 | for (unsigned i = 0; i < z->_size; i++) |
| 1071 | 1077 | { | |
| 1072 | tZeroCrossingInfo_free(&z->_info[i]); | 1078 | tZeroCrossingInfo_free(&z->_info[i]); |
| 1079 | } | ||
| 1073 | 1080 | ||
| 1074 | mpool_free((char*)z->_info, z->mempool); | 1081 | mpool_free((char*)z->_info, z->mempool); |
| 1075 | mpool_free((char*)z, z->mempool); | 1082 | mpool_free((char*)z, z->mempool); |
| @@ -1198,7 +1205,7 @@ static inline void update_state(tZeroCrossingCollector* const zc, float s) · 122 unmodified lines | |||
| 1198 | { | 1205 | { |
| 1199 | --z->_pos; | 1206 | --z->_pos; |
| 1200 | z->_pos &= z->_mask; | 1207 | z->_pos &= z->_mask; |
| 1201 | tZeroCrossingInfo crossing = z->_info[z->_pos]; | 1208 | tZeroCrossingInfo crossing = z->_info[z->_pos & z->_mask]; |
| 1202 | crossing->_before_crossing = z->_prev; | 1209 | crossing->_before_crossing = z->_prev; |
| 1203 | crossing->_after_crossing = s; | 1210 | crossing->_after_crossing = s; |
| 1204 | crossing->_peak = s; | 1211 | crossing->_peak = s; |
| @@ -1210,7 +1217,7 @@ static inline void update_state(tZeroCrossingCollector* const zc, float s) · 5 unmodified lines | |||
| 1210 | } | 1217 | } |
| 1211 | else | 1218 | else |
| 1212 | { | 1219 | { |
| 1213 | tZeroCrossingInfo_updatePeak(&z->_info[z->_pos], s, z->_frame); | 1220 | tZeroCrossingInfo_updatePeak(&z->_info[z->_pos & z->_mask], s, z->_frame); |
| 1214 | } | 1221 | } |
| 1215 | if (s > z->_peak_update) | 1222 | if (s > z->_peak_update) |
| 1216 | { | 1223 | { |
| @@ -1220,14 +1227,14 @@ static inline void update_state(tZeroCrossingCollector* const zc, float s) · 3 unmodified lines | |||
| 1220 | else if (z->_state && (s < z->_hysteresis)) | 1227 | else if (z->_state && (s < z->_hysteresis)) |
| 1221 | { | 1228 | { |
| 1222 | z->_state = 0; | 1229 | z->_state = 0; |
| 1223 | z->_info[z->_pos]->_trailing_edge = z->_frame; | 1230 | z->_info[z->_pos & z->_mask]->_trailing_edge = z->_frame; |
| 1224 | if (z->_peak == 0.0f) | 1231 | if (z->_peak == 0.0f) |
| 1225 | z->_peak = z->_peak_update; | 1232 | z->_peak = z->_peak_update; |
| 1226 | } | 1233 | } |
| 1227 | 1234 | ||
| 1228 | if (z->_frame > z->_window_size * 2) | 1235 | if (z->_frame > z->_window_size * 2) |
| 1229 | reset(zc); | 1236 | reset(zc); |
| 1230 | 1237 | ||
| 1231 | z->_prev = s; | 1238 | z->_prev = s; |
| 1232 | } | 1239 | } |
| 1233 | 1240 | ||
| @@ -1235,7 +1242,7 @@ static inline void shift(tZeroCrossingCollector* const zc, int n) · 1 unmodified line | |||
| 1235 | { | 1242 | { |
| 1236 | _tZeroCrossingCollector* z = *zc; | 1243 | _tZeroCrossingCollector* z = *zc; |
| 1237 | 1244 | ||
| 1238 | tZeroCrossingInfo crossing = z->_info[z->_pos]; | 1245 | tZeroCrossingInfo crossing = z->_info[z->_pos & z->_mask]; |
| 1239 | 1246 | ||
| 1240 | crossing->_leading_edge -= n; | 1247 | crossing->_leading_edge -= n; |
| 1241 | if (!z->_state) | 1248 | if (!z->_state) |
| @@ -80,14 +80,15 @@ void tOversampler_init (tOversampler* const osr, int ratio, int extraQuality, LE · 79 unmodified lines | |||
| 80 | void tOversampler_initToPool (tOversampler* const osr, int ratio, int extraQuality, tMempool* const mp) | 80 | void tOversampler_initToPool (tOversampler* const osr, int ratio, int extraQuality, tMempool* const mp) |
| 81 | { | 81 | { |
| 82 | _tMempool* m = *mp; | 82 | _tMempool* m = *mp; |
| 83 | _tOversampler* os = *osr = (_tOversampler*) mpool_alloc(sizeof(_tOversampler), m); | ||
| 84 | os->mempool = m; | ||
| 85 | |||
| 86 | uint8_t offset = 0; | 83 | uint8_t offset = 0; |
| 87 | if (extraQuality) offset = 6; | 84 | if (extraQuality) offset = 6; |
| 88 | if (ratio == 2 || ratio == 4 || | 85 | if (ratio == 2 || ratio == 4 || |
| 89 | ratio == 8 || ratio == 16 || | 86 | ratio == 8 || ratio == 16 || |
| 90 | ratio == 32 || ratio == 64) { | 87 | ratio == 32 || ratio == 64) { |
| 88 | |||
| 89 | _tOversampler* os = *osr = (_tOversampler*) mpool_alloc(sizeof(_tOversampler), m); | ||
| 90 | os->mempool = m; | ||
| 91 | |||
| 91 | os->ratio = ratio; | 92 | os->ratio = ratio; |
| 92 | int idx = (int)(log2f(os->ratio))-1+offset; | 93 | int idx = (int)(log2f(os->ratio))-1+offset; |
| 93 | os->numTaps = __leaf_tablesize_firNumTaps[idx]; | 94 | os->numTaps = __leaf_tablesize_firNumTaps[idx]; |
| @@ -904,9 +904,8 @@ void tRosenbergGlottalPulse_initToPool (tRosenbergGlottalPulse* const gp, tMempo · 903 unmodified lines | |||
| 904 | g->pulseLength = 0.0f; | 904 | g->pulseLength = 0.0f; |
| 905 | g->freq = 0.0f; | 905 | g->freq = 0.0f; |
| 906 | g->inc = 0.0f; | 906 | g->inc = 0.0f; |
| 907 | |||
| 908 | |||
| 909 | } | 907 | } |
| 908 | |||
| 910 | void tRosenbergGlottalPulse_free (tRosenbergGlottalPulse* const gp) | 909 | void tRosenbergGlottalPulse_free (tRosenbergGlottalPulse* const gp) |
| 911 | { | 910 | { |
| 912 | _tRosenbergGlottalPulse* g = *gp; | 911 | _tRosenbergGlottalPulse* g = *gp; |
| @@ -977,6 +976,7 @@ void tRosenbergGlottalPulse_setFreq (tRosenbergGlottalPulse* const g · 64 unmodified lines | |||
| 977 | 976 | ||
| 978 | g->freq = freq; | 977 | g->freq = freq; |
| 979 | g->inc = freq * leaf->invSampleRate; | 978 | g->inc = freq * leaf->invSampleRate; |
| 979 | g->inc -= (int) g->inc; | ||
| 980 | } | 980 | } |
| 981 | 981 | ||
| 982 | void tRosenbergGlottalPulse_setOpenLength (tRosenbergGlottalPulse* const gp, float openLength) | 982 | void tRosenbergGlottalPulse_setOpenLength (tRosenbergGlottalPulse* const gp, float openLength) |
| @@ -1066,7 +1066,7 @@ void tSOLAD_ioSamples(tSOLAD* const wp, float* in, float* out, int blocksize) · 83 unmodified lines | |||
| 1066 | { | 1066 | { |
| 1067 | float sample = tHighpass_tick(&w->hp, in[0]); | 1067 | float sample = tHighpass_tick(&w->hp, in[0]); |
| 1068 | w->delaybuf[0] = sample; | 1068 | w->delaybuf[0] = sample; |
| 1069 | w->delaybuf[w->loopSize] = sample; // copy one sample for interpolation | 1069 | w->delaybuf[w->loopSize-1] = sample; // copy one sample for interpolation |
| 1070 | n--; | 1070 | n--; |
| 1071 | i++; | 1071 | i++; |
| 1072 | in++; | 1072 | in++; |
| @@ -746,8 +746,6 @@ void tADSRT_setRelease(tADSRT* const adsrenv, float release) · 745 unmodified lines | |||
| 746 | void tADSRT_setLeakFactor(tADSRT* const adsrenv, float leakFactor) | 746 | void tADSRT_setLeakFactor(tADSRT* const adsrenv, float leakFactor) |
| 747 | { | 747 | { |
| 748 | _tADSRT* adsr = *adsrenv; | 748 | _tADSRT* adsr = *adsrenv; |
| 749 | |||
| 750 | |||
| 751 | adsr->leakFactor = leakFactor; | 749 | adsr->leakFactor = leakFactor; |
| 752 | } | 750 | } |
| 753 | 751 | ||
| @@ -48,6 +48,12 @@ · 47 unmodified lines | |||
| 48 | 48 | ||
| 49 | #endif | 49 | #endif |
| 50 | 50 | ||
| 51 | #include <stdlib.h> | ||
| 52 | |||
| 53 | #if LEAF_DEBUG | ||
| 54 | #include "../../TestPlugin/JuceLibraryCode/JuceHeader.h" | ||
| 55 | #endif | ||
| 56 | |||
| 51 | /** | 57 | /** |
| 52 | * private function | 58 | * private function |
| 53 | */ | 59 | */ |
| @@ -89,6 +95,23 @@ void leaf_pool_init(LEAF* const leaf, char* memory, size_t size) · 35 unmodified lines | |||
| 89 | */ | 95 | */ |
| 90 | char* mpool_alloc(size_t asize, _tMempool* pool) | 96 | char* mpool_alloc(size_t asize, _tMempool* pool) |
| 91 | { | 97 | { |
| 98 | #if LEAF_DEBUG | ||
| 99 | DBG("malloc " + String(asize)); | ||
| 100 | #endif | ||
| 101 | #if LEAF_USE_DYNAMIC_ALLOCATION | ||
| 102 | char* temp = (char*) malloc(asize); | ||
| 103 | if (temp == NULL) | ||
| 104 | { | ||
| 105 | // allocation failed, exit from the program | ||
| 106 | fprintf(stderr, "Out of memory.\n"); | ||
| 107 | exit(1); | ||
| 108 | } | ||
| 109 | if (pool->leaf->clearOnAllocation > 0) | ||
| 110 | { | ||
| 111 | memset(temp, 0, asize); | ||
| 112 | } | ||
| 113 | return temp; | ||
| 114 | #else | ||
| 92 | // If the head is NULL, the mempool is full | 115 | // If the head is NULL, the mempool is full |
| 93 | if (pool->head == NULL) | 116 | if (pool->head == NULL) |
| 94 | { | 117 | { |
| @@ -169,6 +192,7 @@ char* mpool_alloc(size_t asize, _tMempool* pool) · 74 unmodified lines | |||
| 169 | 192 | ||
| 170 | // Return the pool of the allocated node; | 193 | // Return the pool of the allocated node; |
| 171 | return node_to_alloc->pool; | 194 | return node_to_alloc->pool; |
| 195 | #endif | ||
| 172 | } | 196 | } |
| 173 | 197 | ||
| 174 | 198 | ||
| @@ -177,6 +201,20 @@ char* mpool_alloc(size_t asize, _tMempool* pool) · 2 unmodified lines | |||
| 177 | */ | 201 | */ |
| 178 | char* mpool_calloc(size_t asize, _tMempool* pool) | 202 | char* mpool_calloc(size_t asize, _tMempool* pool) |
| 179 | { | 203 | { |
| 204 | #if LEAF_DEBUG | ||
| 205 | DBG("calloc " + String(asize)); | ||
| 206 | #endif | ||
| 207 | #if LEAF_USE_DYNAMIC_ALLOCATION | ||
| 208 | char* ret = (char*) malloc(asize); | ||
| 209 | if (ret == NULL) | ||
| 210 | { | ||
| 211 | // allocation failed, exit from the program | ||
| 212 | fprintf(stderr, "Out of memory.\n"); | ||
| 213 | exit(1); | ||
| 214 | } | ||
| 215 | memset(ret, 0, asize); | ||
| 216 | return ret; | ||
| 217 | #else | ||
| 180 | // If the head is NULL, the mempool is full | 218 | // If the head is NULL, the mempool is full |
| 181 | if (pool->head == NULL) | 219 | if (pool->head == NULL) |
| 182 | { | 220 | { |
| @@ -252,26 +290,29 @@ char* mpool_calloc(size_t asize, _tMempool* pool) · 69 unmodified lines | |||
| 252 | for (int i = 0; i < node_to_alloc->size; i++) node_to_alloc->pool[i] = 0; | 290 | for (int i = 0; i < node_to_alloc->size; i++) node_to_alloc->pool[i] = 0; |
| 253 | // Return the pool of the allocated node; | 291 | // Return the pool of the allocated node; |
| 254 | return node_to_alloc->pool; | 292 | return node_to_alloc->pool; |
| 293 | #endif | ||
| 255 | } | 294 | } |
| 256 | 295 | ||
| 257 | char* leaf_alloc(LEAF* const leaf, size_t size) | 296 | char* leaf_alloc(LEAF* const leaf, size_t size) |
| 258 | { | 297 | { |
| 259 | //printf("alloc %i\n", size); | 298 | //printf("alloc %i\n", size); |
| 260 | char* block = mpool_alloc(size, &leaf->_internal_mempool); | 299 | return mpool_alloc(size, &leaf->_internal_mempool); |
| 261 | |||
| 262 | return block; | ||
| 263 | } | 300 | } |
| 264 | 301 | ||
| 265 | char* leaf_calloc(LEAF* const leaf, size_t size) | 302 | char* leaf_calloc(LEAF* const leaf, size_t size) |
| 266 | { | 303 | { |
| 267 | //printf("alloc %i\n", size); | 304 | //printf("alloc %i\n", size); |
| 268 | char* block = mpool_calloc(size, &leaf->_internal_mempool); | 305 | return mpool_calloc(size, &leaf->_internal_mempool); |
| 269 | |||
| 270 | return block; | ||
| 271 | } | 306 | } |
| 272 | 307 | ||
| 273 | void mpool_free(char* ptr, _tMempool* pool) | 308 | void mpool_free(char* ptr, _tMempool* pool) |
| 274 | { | 309 | { |
| 310 | #if LEAF_DEBUG | ||
| 311 | DBG("free"); | ||
| 312 | #endif | ||
| 313 | #if LEAF_USE_DYNAMIC_ALLOCATION | ||
| 314 | free(ptr); | ||
| 315 | #else | ||
| 275 | //if (ptr < pool->mpool || ptr >= pool->mpool + pool->msize) | 316 | //if (ptr < pool->mpool || ptr >= pool->mpool + pool->msize) |
| 276 | // Get the node at the freed space | 317 | // Get the node at the freed space |
| 277 | mpool_node_t* freed_node = (mpool_node_t*) (ptr - pool->leaf->header_size); | 318 | mpool_node_t* freed_node = (mpool_node_t*) (ptr - pool->leaf->header_size); |
| @@ -336,6 +377,7 @@ void mpool_free(char* ptr, _tMempool* pool) · 58 unmodified lines | |||
| 336 | // Format the freed pool | 377 | // Format the freed pool |
| 337 | // char* freed_pool = (char*)freed_node->pool; | 378 | // char* freed_pool = (char*)freed_node->pool; |
| 338 | // for (int i = 0; i < freed_node->size; i++) freed_pool[i] = 0; | 379 | // for (int i = 0; i < freed_node->size; i++) freed_pool[i] = 0; |
| 380 | #endif | ||
| 339 | } | 381 | } |
| 340 | 382 | ||
| 341 | void leaf_free(LEAF* const leaf, char* ptr) | 383 | void leaf_free(LEAF* const leaf, char* ptr) |
| @@ -633,11 +633,11 @@ void tSimplePoly_initToPool (tSimplePoly* const polyh, int maxNumV · 632 unmodified lines | |||
| 633 | } | 633 | } |
| 634 | poly->stealing_on = 1; | 634 | poly->stealing_on = 1; |
| 635 | poly->recover_stolen = 1; | 635 | poly->recover_stolen = 1; |
| 636 | poly->voices = (int**) mpool_alloc(sizeof(int*) * poly->maxNumVoices, m); | 636 | poly->voices = (int**) mpool_calloc(sizeof(int*) * poly->maxNumVoices, m); |
| 637 | 637 | ||
| 638 | for (int i = 0; i < poly->maxNumVoices; ++i) | 638 | for (int i = 0; i < poly->maxNumVoices; ++i) |
| 639 | { | 639 | { |
| 640 | poly->voices[i] = (int*) mpool_alloc(sizeof(int) * 3, m); | 640 | poly->voices[i] = (int*) mpool_calloc(sizeof(int) * 3, m); |
| 641 | poly->voices[i][0] = -1; | 641 | poly->voices[i][0] = -1; |
| 642 | } | 642 | } |
| 643 | tStack_initToPool(&poly->stack, mp); | 643 | tStack_initToPool(&poly->stack, mp); |
| @@ -58,6 +58,9 @@ · 57 unmodified lines | |||
| 58 | 58 | ||
| 59 | #define LEAF_USE_CMSIS 0 | 59 | #define LEAF_USE_CMSIS 0 |
| 60 | 60 | ||
| 61 | //! Use stdlib malloc() and free() internally instead of LEAF's normal mempool behavior for when you want to avoid being limited to and managing mempool a fixed mempool size. Usage of all object remains essentially the same. | ||
| 62 | #define LEAF_USE_DYNAMIC_ALLOCATION 0 | ||
| 63 | |||
| 61 | //============================================================================== | 64 | //============================================================================== |
| 62 | 65 | ||
| 63 | #endif // LEAF_CONFIG_H_INCLUDED | 66 | #endif // LEAF_CONFIG_H_INCLUDED |
| @@ -27,9 +27,9 @@ · 26 unmodified lines | |||
| 27 | 27 | ||
| 28 | #define LEAF_DEBUG 0 | 28 | #define LEAF_DEBUG 0 |
| 29 | 29 | ||
| 30 | #if LEAF_DEBUG | 30 | //#if LEAF_DEBUG |
| 31 | #include "../LEAF_JUCEPlugin/JuceLibraryCode/JuceHeader.h" | 31 | //#include "../TestPlugin/JuceLibraryCode/JuceHeader.h" |
| 32 | #endif | 32 | //#endif |
| 33 | 33 | ||
| 34 | #if _WIN32 || _WIN64 | 34 | #if _WIN32 || _WIN64 |
| 35 | 35 | ||