Unified · Split
| @@ -12,9 +12,11 @@ · 11 unmodified lines | ||
| 12 | 12 | |
| 13 | 13 | void exampleInit() |
| 14 | 14 | { |
| 15 | − LEAF_init(44100, 64, mempool, 1000, &exampleRandom); | |
| 15 | + LEAF leaf; | |
| 16 | 16 | |
| 17 | − tCycle_init(&cycle); | |
| 17 | + LEAF_init(&leaf, 44100, 128, mempool, 1000, &exampleRandom); | |
| 18 | + | |
| 19 | + tCycle_init(&cycle, &leaf); | |
| 18 | 20 | tCycle_setFreq(&cycle, 220); |
| 19 | 21 | } |
| 20 | 22 | |
| @@ -8,7 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | ============================================================================== |
| 9 | 9 | */ |
| 10 | 10 | |
| 11 | −#include "../LEAF/leaf.h" | |
| 11 | +#include "../leaf/leaf.h" | |
| 12 | 12 | |
| 13 | 13 | char mempool[1000]; |
| 14 | 14 | tCycle cycle; |
| @@ -15,7 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | jucerFormatVersion="1"> |
| 16 | 16 | <MAINGROUP id="F7Bywq" name="LEAF"> |
| 17 | 17 | <GROUP id="{F7096CF4-1A84-4CC8-A236-06FAE894451E}" name="Examples"> |
| 18 | − <FILE id="hMMOsl" name="basic-oscillators.c" compile="0" resource="0" | |
| 18 | + <FILE id="hMMOsl" name="basic-oscillators.c" compile="1" resource="0" | |
| 19 | 19 | file="../Examples/basic-oscillators.c"/> |
| 20 | 20 | <FILE id="mVSe2h" name="basic-oscillators.h" compile="0" resource="0" |
| 21 | 21 | file="../Examples/basic-oscillators.h"/> |
| @@ -963,9 +963,9 @@ extern "C" { · 962 unmodified lines | ||
| 963 | 963 | //============================================================================== |
| 964 | 964 | |
| 965 | 965 | /*! |
| 966 | − @defgroup tdualpitchdetector tPitchDetector | |
| 966 | + @defgroup tdualpitchdetector tDualPitchDetector | |
| 967 | 967 | @ingroup analysis |
| 968 | − @brief Combined pitch detection algorithm using boht Joel de Guzman's Q Audio DSP Library and Katya Vetters algorithms | |
| 968 | + @brief Combined pitch detection algorithm using both Joel de Guzman's Q Audio DSP Library and Katya Vetters algorithms | |
| 969 | 969 | @{ |
| 970 | 970 | |
| 971 | 971 | @fn void tDualPitchDetector_init (tDualPitchDetector* const detector, float lowestFreq, float highestFreq, float* inBuffer, int bufSize, LEAF* const leaf) |
| @@ -777,11 +777,17 @@ extern "C" { · 776 unmodified lines | ||
| 777 | 777 | @brief Initialize a tButterworth to the default mempool of a LEAF instance. |
| 778 | 778 | @param filter A pointer to the tButterworth to initialize. |
| 779 | 779 | @param leaf A pointer to the leaf instance. |
| 780 | + @param order Order of the filter. | |
| 781 | + @param lowCutoff Lower cutoff frequency. | |
| 782 | + @param upperCutoff Upper cutoff frequency. | |
| 780 | 783 | |
| 781 | 784 | @fn void tButterworth_initToPool (tButterworth* const, int N, float f1, float f2, tMempool* const) |
| 782 | 785 | @brief Initialize a tButterworth to a specified mempool. |
| 783 | 786 | @param filter A pointer to the tButterworth to initialize. |
| 784 | 787 | @param mempool A pointer to the tMempool to use. |
| 788 | + @param order Order of the filter. | |
| 789 | + @param lowCutoff Lower cutoff frequency. | |
| 790 | + @param upperCutoff Upper cutoff frequency. | |
| 785 | 791 | |
| 786 | 792 | @fn void tButterworth_free (tButterworth* const) |
| 787 | 793 | @brief Free a tButterworth from its mempool. |
| @@ -808,15 +814,13 @@ extern "C" { · 20 unmodified lines | ||
| 808 | 814 | #define NUM_SVF_BW 16 |
| 809 | 815 | typedef struct _tButterworth |
| 810 | 816 | { |
| 811 | − | |
| 812 | 817 | tMempool mempool; |
| 813 | 818 | |
| 814 | 819 | float gain; |
| 820 | + int order; | |
| 821 | + int numSVF; | |
| 815 | 822 | |
| 816 | − int N; | |
| 817 | − | |
| 818 | − tSVF low[NUM_SVF_BW]; | |
| 819 | − tSVF high[NUM_SVF_BW]; | |
| 823 | + tSVF* svf; | |
| 820 | 824 | |
| 821 | 825 | float f1,f2; |
| 822 | 826 | } _tButterworth; |
| @@ -31,20 +31,20 @@ extern "C" { · 30 unmodified lines | ||
| 31 | 31 | /*! |
| 32 | 32 | @defgroup ttable tTable |
| 33 | 33 | @ingroup oscillators |
| 34 | − @brief General wavetable oscillator. | |
| 34 | + @brief Simple aliasing wavetable oscillator. | |
| 35 | 35 | @{ |
| 36 | 36 | |
| 37 | 37 | @fn void tTable_init (tTable* const osc, float* table, int size, LEAF* const leaf) |
| 38 | 38 | @brief Initialize a tTable to the default mempool of a LEAF instance. |
| 39 | 39 | @param osc A pointer to the tTable to initialize. |
| 40 | − @param table A pointer to the wave table data. | |
| 41 | − @param size The number of samples in the wave table. | |
| 40 | + @param table A pointer to the wavetable data. | |
| 41 | + @param size The number of samples in the wavetable. | |
| 42 | 42 | @param leaf A pointer to the leaf instance. |
| 43 | 43 | |
| 44 | 44 | @fn void tTable_initToPool (tTable* const osc, float* table, int size, tMempool* const mempool) |
| 45 | 45 | @brief Initialize a tTable to a specified mempool. |
| 46 | 46 | @param osc A pointer to the tTable to initialize. |
| 47 | − @param table A pointer to the wave table data. | |
| 47 | + @param table A pointer to the wavetable data. | |
| 48 | 48 | @param size The number of samples in the wave table. |
| 49 | 49 | @param mempool A pointer to the tMempool to use. |
| 50 | 50 | |
| @@ -66,7 +66,6 @@ extern "C" { · 15 unmodified lines | ||
| 66 | 66 | |
| 67 | 67 | typedef struct _tTable |
| 68 | 68 | { |
| 69 | − | |
| 70 | 69 | tMempool mempool; |
| 71 | 70 | |
| 72 | 71 | float* waveTable; |
| @@ -86,6 +85,70 @@ extern "C" { · 13 unmodified lines | ||
| 86 | 85 | |
| 87 | 86 | //============================================================================== |
| 88 | 87 | |
| 88 | + /*! | |
| 89 | + @defgroup twavetable tWavetable | |
| 90 | + @ingroup oscillators | |
| 91 | + @brief Anti-aliased wavetable oscillator. | |
| 92 | + @{ | |
| 93 | + | |
| 94 | + @fn void tWavetable_init (tTable* const osc, float* table, int size, LEAF* const leaf) | |
| 95 | + @brief Initialize a tWavetable to the default mempool of a LEAF instance. | |
| 96 | + @param osc A pointer to the tWavetable to initialize. | |
| 97 | + @param table A pointer to the wavetable data. | |
| 98 | + @param size The number of samples in the wavetable. | |
| 99 | + @param leaf A pointer to the leaf instance. | |
| 100 | + | |
| 101 | + @fn void tWavetable_initToPool (tTable* const osc, float* table, int size, tMempool* const mempool) | |
| 102 | + @brief Initialize a tWavetable to a specified mempool. | |
| 103 | + @param osc A pointer to the tWavetable to initialize. | |
| 104 | + @param table A pointer to the wavetable data. | |
| 105 | + @param size The number of samples in the wave table. | |
| 106 | + @param mempool A pointer to the tMempool to use. | |
| 107 | + | |
| 108 | + @fn void tWavetable_free (tTable* const osc) | |
| 109 | + @brief Free a tWavetable from its mempool. | |
| 110 | + @param osc A pointer to the tWavetable to free. | |
| 111 | + | |
| 112 | + @fn float tWavetable_tick (tTable* const osc) | |
| 113 | + @brief Tick a tWavetable oscillator. | |
| 114 | + @param osc A pointer to the relevant tWavetable. | |
| 115 | + @return The ticked sample as a float from -1 to 1. | |
| 116 | + | |
| 117 | + @fn void tWavetable_setFreq (tTable* const osc, float freq) | |
| 118 | + @brief Set the frequency of a tWavetable oscillator. | |
| 119 | + @param osc A pointer to the relevant tWavetable. | |
| 120 | + @param freq The frequency to set the oscillator to. | |
| 121 | + | |
| 122 | + @} */ | |
| 123 | + | |
| 124 | + typedef struct _tWavetable | |
| 125 | + { | |
| 126 | + tMempool mempool; | |
| 127 | + | |
| 128 | + float** tables; | |
| 129 | + int size; | |
| 130 | + int numTables; | |
| 131 | + float baseFreq, invBaseFreq; | |
| 132 | + float inc, freq; | |
| 133 | + float phase; | |
| 134 | + | |
| 135 | + int oct; | |
| 136 | + float w; | |
| 137 | + | |
| 138 | + tButterworth bl; | |
| 139 | + } _tWavetable; | |
| 140 | + | |
| 141 | + typedef _tWavetable* tWavetable; | |
| 142 | + | |
| 143 | + void tWavetable_init(tWavetable* const osc, float* table, int size, LEAF* const leaf); | |
| 144 | + void tWavetable_initToPool(tWavetable* const osc, float* table, int size, tMempool* const mempool); | |
| 145 | + void tWavetable_free(tWavetable* const osc); | |
| 146 | + | |
| 147 | + float tWavetable_tick(tWavetable* const osc); | |
| 148 | + void tWavetable_setFreq(tWavetable* const osc, float freq); | |
| 149 | + | |
| 150 | + //============================================================================== | |
| 151 | + | |
| 89 | 152 | /*! |
| 90 | 153 | @defgroup tcycle tCycle |
| 91 | 154 | @ingroup oscillators |
| @@ -828,7 +828,6 @@ void tSVF_initToPool (tSVF* const svff, SVFType type, float freq, float Q · 827 unmodified lines | ||
| 828 | 828 | svf->cL = 0.0f; |
| 829 | 829 | } |
| 830 | 830 | |
| 831 | − | |
| 832 | 831 | else if (type == SVFTypePeak) |
| 833 | 832 | { |
| 834 | 833 | svf->cH = 1.0f; |
| @@ -974,12 +973,12 @@ void tEfficientSVF_setQ(tEfficientSVF* const svff, float Q) · 139 unmodified lines | ||
| 974 | 973 | #endif // LEAF_INCLUDE_FILTERTAN_TABLE |
| 975 | 974 | |
| 976 | 975 | /* Highpass */ |
| 977 | −void tHighpass_init(tHighpass* const ft, float freq, LEAF* const leaf) | |
| 976 | +void tHighpass_init(tHighpass* const ft, float freq, LEAF* const leaf) | |
| 978 | 977 | { |
| 979 | 978 | tHighpass_initToPool(ft, freq, &leaf->mempool); |
| 980 | 979 | } |
| 981 | 980 | |
| 982 | −void tHighpass_initToPool (tHighpass* const ft, float freq, tMempool* const mp) | |
| 981 | +void tHighpass_initToPool (tHighpass* const ft, float freq, tMempool* const mp) | |
| 983 | 982 | { |
| 984 | 983 | _tMempool* m = *mp; |
| 985 | 984 | _tHighpass* f = *ft = (_tHighpass*) mpool_calloc(sizeof(_tHighpass), m); |
| @@ -994,14 +993,14 @@ void tHighpass_initToPool (tHighpass* const ft, float freq, tMempool* cons · 8 unmodified lines | ||
| 994 | 993 | f->frequency = freq; |
| 995 | 994 | } |
| 996 | 995 | |
| 997 | −void tHighpass_free (tHighpass* const ft) | |
| 996 | +void tHighpass_free (tHighpass* const ft) | |
| 998 | 997 | { |
| 999 | 998 | _tHighpass* f = *ft; |
| 1000 | 999 | |
| 1001 | 1000 | mpool_free((char*)f, f->mempool); |
| 1002 | 1001 | } |
| 1003 | 1002 | |
| 1004 | −void tHighpass_setFreq(tHighpass* const ft, float freq) | |
| 1003 | +void tHighpass_setFreq(tHighpass* const ft, float freq) | |
| 1005 | 1004 | { |
| 1006 | 1005 | _tHighpass* f = *ft; |
| 1007 | 1006 | LEAF* leaf = f->mempool->leaf; |
| @@ -1011,14 +1010,14 @@ void tHighpass_setFreq(tHighpass* const ft, float freq) · 3 unmodified lines | ||
| 1011 | 1010 | |
| 1012 | 1011 | } |
| 1013 | 1012 | |
| 1014 | −float tHighpass_getFreq(tHighpass* const ft) | |
| 1013 | +float tHighpass_getFreq(tHighpass* const ft) | |
| 1015 | 1014 | { |
| 1016 | 1015 | _tHighpass* f = *ft; |
| 1017 | 1016 | return f->frequency; |
| 1018 | 1017 | } |
| 1019 | 1018 | |
| 1020 | 1019 | // From JOS DC Blocker |
| 1021 | −float tHighpass_tick(tHighpass* const ft, float x) | |
| 1020 | +float tHighpass_tick(tHighpass* const ft, float x) | |
| 1022 | 1021 | { |
| 1023 | 1022 | _tHighpass* f = *ft; |
| 1024 | 1023 | f->ys = x - f->xs + f->R * f->ys; |
| @@ -1034,12 +1033,12 @@ void tHighpassSampleRateChanged(tHighpass* const ft) · 9 unmodified lines | ||
| 1034 | 1033 | f->R = (1.0f-((f->frequency * 2.0f * 3.14f) * leaf->invSampleRate)); |
| 1035 | 1034 | } |
| 1036 | 1035 | |
| 1037 | −void tButterworth_init(tButterworth* const ft, int N, float f1, float f2, LEAF* const leaf) | |
| 1036 | +void tButterworth_init(tButterworth* const ft, int order, float f1, float f2, LEAF* const leaf) | |
| 1038 | 1037 | { |
| 1039 | − tButterworth_initToPool(ft, N, f1, f2, &leaf->mempool); | |
| 1038 | + tButterworth_initToPool(ft, order, f1, f2, &leaf->mempool); | |
| 1040 | 1039 | } |
| 1041 | 1040 | |
| 1042 | −void tButterworth_initToPool (tButterworth* const ft, int N, float f1, float f2, tMempool* const mp) | |
| 1041 | +void tButterworth_initToPool (tButterworth* const ft, int order, float f1, float f2, tMempool* const mp) | |
| 1043 | 1042 | { |
| 1044 | 1043 | _tMempool* m = *mp; |
| 1045 | 1044 | _tButterworth* f = *ft = (_tButterworth*) mpool_alloc(sizeof(_tButterworth), m); |
| @@ -1049,14 +1048,19 @@ void tButterworth_initToPool (tButterworth* const ft, int N, float f1, fl · 3 unmodified lines | ||
| 1049 | 1048 | f->f2 = f2; |
| 1050 | 1049 | f->gain = 1.0f; |
| 1051 | 1050 | |
| 1052 | − f->N = N; | |
| 1051 | + f->numSVF = f->order = order; | |
| 1052 | + if (f1 >= 0.0f && f2 >= 0.0f) f->numSVF *= 2; | |
| 1053 | 1053 | |
| 1054 | − if (f->N > NUM_SVF_BW) f->N = NUM_SVF_BW; | |
| 1054 | + f->svf = (tSVF*) mpool_alloc(sizeof(tSVF) * f->numSVF, m); | |
| 1055 | 1055 | |
| 1056 | − for(int i = 0; i < N/2; ++i) | |
| 1056 | + int o = 0; | |
| 1057 | + if (f1 >= 0.0f) o = f->order; | |
| 1058 | + for(int i = 0; i < f->order; ++i) | |
| 1057 | 1059 | { |
| 1058 | − tSVF_initToPool(&f->low[i], SVFTypeHighpass, f1, 0.5f/cosf((1.0f+2.0f*i)*PI/(2*N)), mp); | |
| 1059 | − tSVF_initToPool(&f->high[i], SVFTypeLowpass, f2, 0.5f/cosf((1.0f+2.0f*i)*PI/(2*N)), mp); | |
| 1060 | + if (f1 >= 0.0f) | |
| 1061 | + tSVF_initToPool(&f->svf[i], SVFTypeHighpass, f1, 0.5f/cosf((1.0f+2.0f*i)*PI/(2*f->order)), mp); | |
| 1062 | + if (f2 >= 0.0f) | |
| 1063 | + tSVF_initToPool(&f->svf[i+o], SVFTypeLowpass, f2, 0.5f/cosf((1.0f+2.0f*i)*PI/(2*f->order)), mp); | |
| 1060 | 1064 | } |
| 1061 | 1065 | } |
| 1062 | 1066 | |
| @@ -1064,11 +1068,8 @@ void tButterworth_free (tButterworth* const ft) · 1 unmodified line | ||
| 1064 | 1068 | { |
| 1065 | 1069 | _tButterworth* f = *ft; |
| 1066 | 1070 | |
| 1067 | − for(int i = 0; i < f->N/2; ++i) | |
| 1068 | − { | |
| 1069 | − tSVF_free(&f->low[i]); | |
| 1070 | − tSVF_free(&f->high[i]); | |
| 1071 | − } | |
| 1071 | + for(int i = 0; i < f->numSVF; ++i) | |
| 1072 | + tSVF_free(&f->svf[i]); | |
| 1072 | 1073 | |
| 1073 | 1074 | mpool_free((char*)f, f->mempool); |
| 1074 | 1075 | } |
| @@ -1077,11 +1078,9 @@ float tButterworth_tick(tButterworth* const ft, float samp) · 2 unmodified lines | ||
| 1077 | 1078 | { |
| 1078 | 1079 | _tButterworth* f = *ft; |
| 1079 | 1080 | |
| 1080 | − for(int i = 0; i < ((f->N)/2); ++i) | |
| 1081 | − { | |
| 1082 | − samp = tSVF_tick(&f->low[i],samp); | |
| 1083 | − samp = tSVF_tick(&f->high[i],samp); | |
| 1084 | − } | |
| 1081 | + for(int i = 0; i < f->numSVF; ++i) | |
| 1082 | + samp = tSVF_tick(&f->svf[i], samp); | |
| 1083 | + | |
| 1085 | 1084 | return samp; |
| 1086 | 1085 | } |
| 1087 | 1086 | |
| @@ -1089,29 +1088,36 @@ void tButterworth_setF1(tButterworth* const ft, float f1) · 1 unmodified line | ||
| 1089 | 1088 | { |
| 1090 | 1089 | _tButterworth* f = *ft; |
| 1091 | 1090 | |
| 1091 | + if (f->f1 < 0.0f || f1 < 0.0f) return; | |
| 1092 | + | |
| 1092 | 1093 | f->f1 = f1; |
| 1093 | − for(int i = 0; i < ((f->N)/2); ++i) tSVF_setFreq(&f->low[i], f1); | |
| 1094 | + for (int i = 0; i < f->order; ++i) tSVF_setFreq(&f->svf[i], f1); | |
| 1094 | 1095 | } |
| 1095 | 1096 | |
| 1096 | 1097 | void tButterworth_setF2(tButterworth* const ft, float f2) |
| 1097 | 1098 | { |
| 1098 | 1099 | _tButterworth* f = *ft; |
| 1099 | 1100 | |
| 1101 | + if (f->f2 < 0.0f || f2 < 0.0f) return; | |
| 1102 | + | |
| 1103 | + int o = 0; | |
| 1104 | + if (f->f1 >= 0.0f) o = f->order; | |
| 1100 | 1105 | f->f2 = f2; |
| 1101 | − for(int i = 0; i < ((f->N)/2); ++i) tSVF_setFreq(&f->high[i], f2); | |
| 1106 | + for (int i = 0; i < f->order; ++i) tSVF_setFreq(&f->svf[i+o], f2); | |
| 1102 | 1107 | } |
| 1103 | 1108 | |
| 1104 | 1109 | void tButterworth_setFreqs(tButterworth* const ft, float f1, float f2) |
| 1105 | 1110 | { |
| 1106 | − _tButterworth* f = *ft; | |
| 1107 | − | |
| 1108 | − f->f1 = f1; | |
| 1109 | − f->f2 = f2; | |
| 1110 | − for(int i = 0; i < ((f->N)/2); ++i) | |
| 1111 | − { | |
| 1112 | − tSVF_setFreq(&f->low[i], f1); | |
| 1113 | − tSVF_setFreq(&f->high[i], f2); | |
| 1114 | − } | |
| 1111 | +// _tButterworth* f = *ft; | |
| 1112 | + tButterworth_setF1(ft, f1); | |
| 1113 | + tButterworth_setF1(ft, f2); | |
| 1114 | +// f->f1 = f1; | |
| 1115 | +// f->f2 = f2; | |
| 1116 | +// for(int i = 0; i < ((f->N)/2); ++i) | |
| 1117 | +// { | |
| 1118 | +// tSVF_setFreq(&f->low[i], f1); | |
| 1119 | +// tSVF_setFreq(&f->high[i], f2); | |
| 1120 | +// } | |
| 1115 | 1121 | } |
| 1116 | 1122 | |
| 1117 | 1123 | void tFIR_init(tFIR* const firf, float* coeffs, int numTaps, LEAF* const leaf) |
| @@ -86,6 +86,123 @@ void tTableSampleRateChanged(tTable* const cy) · 85 unmodified lines | ||
| 86 | 86 | c->inc = c->freq * leaf->invSampleRate; |
| 87 | 87 | } |
| 88 | 88 | |
| 89 | +void tWavetable_init(tWavetable* const cy, float* table, int size, LEAF* const leaf) | |
| 90 | +{ | |
| 91 | + tWavetable_initToPool(cy, table, size, &leaf->mempool); | |
| 92 | +} | |
| 93 | + | |
| 94 | +void tWavetable_initToPool(tWavetable* const cy, float* table, int size, tMempool* const mp) | |
| 95 | +{ | |
| 96 | + _tMempool* m = *mp; | |
| 97 | + _tWavetable* c = *cy = (_tWavetable*)mpool_alloc(sizeof(_tTable), m); | |
| 98 | + c->mempool = m; | |
| 99 | + | |
| 100 | + // Determine base frequency | |
| 101 | + c->baseFreq = m->leaf->sampleRate / (float) size; | |
| 102 | + c->invBaseFreq = 1.0f / c->baseFreq; | |
| 103 | + | |
| 104 | + // Determine how many tables we need | |
| 105 | + c->numTables = 1; | |
| 106 | + float f = c->baseFreq; | |
| 107 | + while (f < 20000.f) | |
| 108 | + { | |
| 109 | + c->numTables++; | |
| 110 | + f *= 2.0f; // pass this multiplier in to set spacing of tables? | |
| 111 | + } | |
| 112 | + | |
| 113 | + c->size = size; | |
| 114 | + | |
| 115 | + // Allocate memory for the tables | |
| 116 | + c->tables = (float**) mpool_alloc(sizeof(float*) * c->numTables, m); | |
| 117 | + for (int t = 0; t < c->numTables; ++t) | |
| 118 | + { | |
| 119 | + c->tables[t] = (float*) mpool_alloc(sizeof(float) * c->size, m); | |
| 120 | + } | |
| 121 | + | |
| 122 | + // Copy table | |
| 123 | + for (int i = 0; i < c->size; ++i) | |
| 124 | + { | |
| 125 | + c->tables[0][i] = table[i]; | |
| 126 | + } | |
| 127 | + | |
| 128 | + // Make bandlimited copies at | |
| 129 | + f = m->leaf->sampleRate * 0.25f; //start at half nyquist | |
| 130 | + for (int t = 1; t < c->numTables; ++t) | |
| 131 | + { | |
| 132 | + tButterworth_initToPool(&c->bl, 4, -1.0f, f, mp); | |
| 133 | + for (int i = 0; i < c->size; ++i) | |
| 134 | + { | |
| 135 | + c->tables[t][i] = tButterworth_tick(&c->bl, table[i]); | |
| 136 | + } | |
| 137 | + tButterworth_free(&c->bl); | |
| 138 | + f *= 0.5f; //half the cutoff for next pass | |
| 139 | + } | |
| 140 | + | |
| 141 | + c->inc = 0.0f; | |
| 142 | + c->phase = 0.0f; | |
| 143 | + | |
| 144 | + tWavetable_setFreq(cy, 220); | |
| 145 | +} | |
| 146 | + | |
| 147 | +void tWavetable_free(tWavetable* const cy) | |
| 148 | +{ | |
| 149 | + _tWavetable* c = *cy; | |
| 150 | + | |
| 151 | + for (int t = 0; t < c->numTables; ++t) | |
| 152 | + { | |
| 153 | + mpool_free((char*)c->tables[t], c->mempool); | |
| 154 | + } | |
| 155 | + mpool_free((char*)c->tables, c->mempool); | |
| 156 | + | |
| 157 | + mpool_free((char*)c, c->mempool); | |
| 158 | +} | |
| 159 | + | |
| 160 | +float tWavetable_tick(tWavetable* const cy) | |
| 161 | +{ | |
| 162 | + _tWavetable* c = *cy; | |
| 163 | + | |
| 164 | + float temp; | |
| 165 | + int idx; | |
| 166 | + float fracPart; | |
| 167 | + float samp0; | |
| 168 | + float samp1; | |
| 169 | + | |
| 170 | + // Phasor increment | |
| 171 | + c->phase += c->inc; | |
| 172 | + while (c->phase >= 1.0f) c->phase -= 1.0f; | |
| 173 | + while (c->phase < 0.0f) c->phase += 1.0f; | |
| 174 | + | |
| 175 | + // Wavetable synthesis | |
| 176 | + temp = c->size * c->phase; | |
| 177 | + idx = (int)temp; | |
| 178 | + fracPart = temp - (float)idx; | |
| 179 | + samp0 = c->tables[c->oct+1][idx] + | |
| 180 | + (c->tables[c->oct][idx] - c->tables[c->oct+1][idx]) * c->w; | |
| 181 | + if (++idx >= c->size) idx = 0; | |
| 182 | + samp1 = c->tables[c->oct+1][idx] + | |
| 183 | + (c->tables[c->oct][idx] - c->tables[c->oct+1][idx]) * c->w; | |
| 184 | + | |
| 185 | + return (samp0 + (samp1 - samp0) * fracPart); | |
| 186 | +} | |
| 187 | + | |
| 188 | +void tWavetable_setFreq(tWavetable* const cy, float freq) | |
| 189 | +{ | |
| 190 | + _tWavetable* c = *cy; | |
| 191 | + | |
| 192 | + LEAF* leaf = c->mempool->leaf; | |
| 193 | + | |
| 194 | + c->freq = freq; | |
| 195 | + | |
| 196 | + c->inc = c->freq * leaf->invSampleRate; | |
| 197 | + | |
| 198 | + c->w = c->freq * c->invBaseFreq; | |
| 199 | + for (c->oct = 0; c->w > 2.0f; c->oct++) | |
| 200 | + { | |
| 201 | + c->w = 0.5f * c->w; | |
| 202 | + } | |
| 203 | + c->w = 2.0f - c->w; | |
| 204 | +} | |
| 205 | + | |
| 89 | 206 | #if LEAF_INCLUDE_SINE_TABLE |
| 90 | 207 | // Cycle |
| 91 | 208 | void tCycle_init(tCycle* const cy, LEAF* const leaf) |
| @@ -338,6 +455,7 @@ void tSawtooth_setFreq(tSawtooth* const cy, float freq) · 246 unmodified lines | ||
| 338 | 455 | |
| 339 | 456 | c->inc = c->freq * leaf->invSampleRate; |
| 340 | 457 | |
| 458 | + // base freq 20 | |
| 341 | 459 | c->w = c->freq * INV_20; |
| 342 | 460 | for (c->oct = 0; c->w > 2.0f; c->oct++) |
| 343 | 461 | { |
| @@ -361,7 +479,7 @@ float tSawtooth_tick(tSawtooth* const cy) · 17 unmodified lines | ||
| 361 | 479 | |
| 362 | 480 | // Wavetable synthesis |
| 363 | 481 | out = __leaf_table_sawtooth[c->oct+1][idx] + |
| 364 | − (__leaf_table_sawtooth[c->oct][idx] - __leaf_table_sawtooth[c->oct+1][idx]) * c->w; | |
| 482 | + (__leaf_table_sawtooth[c->oct][idx] - __leaf_table_sawtooth[c->oct+1][idx]) * c->w; | |
| 365 | 483 | |
| 366 | 484 | return out; |
| 367 | 485 | } |
| @@ -54,6 +54,10 @@ · 53 unmodified lines | ||
| 54 | 54 | //! Include tables for minblep insertion, required for all tMB objects. |
| 55 | 55 | #define LEAF_INCLUDE_MINBLEP_TABLES 1 |
| 56 | 56 | |
| 57 | +#define LEAF_NO_DENORMAL_CHECK 0 | |
| 58 | + | |
| 59 | +#define LEAF_USE_CMSIS 0 | |
| 60 | + | |
| 57 | 61 | //============================================================================== |
| 58 | 62 | |
| 59 | 63 | #endif // LEAF_CONFIG_H_INCLUDED |