Unified · Split
| @@ -12,9 +12,11 @@ · 11 unmodified lines | |||
| 12 | 12 | ||
| 13 | void exampleInit() | 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 | tCycle_setFreq(&cycle, 220); | 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 | char mempool[1000]; | 13 | char mempool[1000]; |
| 14 | tCycle cycle; | 14 | tCycle cycle; |
| @@ -15,7 +15,7 @@ · 14 unmodified lines | |||
| 15 | jucerFormatVersion="1"> | 15 | jucerFormatVersion="1"> |
| 16 | <MAINGROUP id="F7Bywq" name="LEAF"> | 16 | <MAINGROUP id="F7Bywq" name="LEAF"> |
| 17 | <GROUP id="{F7096CF4-1A84-4CC8-A236-06FAE894451E}" name="Examples"> | 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 | file="../Examples/basic-oscillators.c"/> | 19 | file="../Examples/basic-oscillators.c"/> |
| 20 | <FILE id="mVSe2h" name="basic-oscillators.h" compile="0" resource="0" | 20 | <FILE id="mVSe2h" name="basic-oscillators.h" compile="0" resource="0" |
| 21 | file="../Examples/basic-oscillators.h"/> | 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 | @ingroup analysis | 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 | @fn void tDualPitchDetector_init (tDualPitchDetector* const detector, float lowestFreq, float highestFreq, float* inBuffer, int bufSize, LEAF* const leaf) | 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 | @brief Initialize a tButterworth to the default mempool of a LEAF instance. | 777 | @brief Initialize a tButterworth to the default mempool of a LEAF instance. |
| 778 | @param filter A pointer to the tButterworth to initialize. | 778 | @param filter A pointer to the tButterworth to initialize. |
| 779 | @param leaf A pointer to the leaf instance. | 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 | @fn void tButterworth_initToPool (tButterworth* const, int N, float f1, float f2, tMempool* const) | 784 | @fn void tButterworth_initToPool (tButterworth* const, int N, float f1, float f2, tMempool* const) |
| 782 | @brief Initialize a tButterworth to a specified mempool. | 785 | @brief Initialize a tButterworth to a specified mempool. |
| 783 | @param filter A pointer to the tButterworth to initialize. | 786 | @param filter A pointer to the tButterworth to initialize. |
| 784 | @param mempool A pointer to the tMempool to use. | 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 | @fn void tButterworth_free (tButterworth* const) | 792 | @fn void tButterworth_free (tButterworth* const) |
| 787 | @brief Free a tButterworth from its mempool. | 793 | @brief Free a tButterworth from its mempool. |
| @@ -808,15 +814,13 @@ extern "C" { · 20 unmodified lines | |||
| 808 | #define NUM_SVF_BW 16 | 814 | #define NUM_SVF_BW 16 |
| 809 | typedef struct _tButterworth | 815 | typedef struct _tButterworth |
| 810 | { | 816 | { |
| 811 | |||
| 812 | tMempool mempool; | 817 | tMempool mempool; |
| 813 | 818 | ||
| 814 | float gain; | 819 | float gain; |
| 820 | int order; | ||
| 821 | int numSVF; | ||
| 815 | 822 | ||
| 816 | int N; | 823 | tSVF* svf; |
| 817 | |||
| 818 | tSVF low[NUM_SVF_BW]; | ||
| 819 | tSVF high[NUM_SVF_BW]; | ||
| 820 | 824 | ||
| 821 | float f1,f2; | 825 | float f1,f2; |
| 822 | } _tButterworth; | 826 | } _tButterworth; |
| @@ -31,20 +31,20 @@ extern "C" { · 30 unmodified lines | |||
| 31 | /*! | 31 | /*! |
| 32 | @defgroup ttable tTable | 32 | @defgroup ttable tTable |
| 33 | @ingroup oscillators | 33 | @ingroup oscillators |
| 34 | @brief General wavetable oscillator. | 34 | @brief Simple aliasing wavetable oscillator. |
| 35 | @{ | 35 | @{ |
| 36 | 36 | ||
| 37 | @fn void tTable_init (tTable* const osc, float* table, int size, LEAF* const leaf) | 37 | @fn void tTable_init (tTable* const osc, float* table, int size, LEAF* const leaf) |
| 38 | @brief Initialize a tTable to the default mempool of a LEAF instance. | 38 | @brief Initialize a tTable to the default mempool of a LEAF instance. |
| 39 | @param osc A pointer to the tTable to initialize. | 39 | @param osc A pointer to the tTable to initialize. |
| 40 | @param table A pointer to the wave table data. | 40 | @param table A pointer to the wavetable data. |
| 41 | @param size The number of samples in the wave table. | 41 | @param size The number of samples in the wavetable. |
| 42 | @param leaf A pointer to the leaf instance. | 42 | @param leaf A pointer to the leaf instance. |
| 43 | 43 | ||
| 44 | @fn void tTable_initToPool (tTable* const osc, float* table, int size, tMempool* const mempool) | 44 | @fn void tTable_initToPool (tTable* const osc, float* table, int size, tMempool* const mempool) |
| 45 | @brief Initialize a tTable to a specified mempool. | 45 | @brief Initialize a tTable to a specified mempool. |
| 46 | @param osc A pointer to the tTable to initialize. | 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 | @param size The number of samples in the wave table. | 48 | @param size The number of samples in the wave table. |
| 49 | @param mempool A pointer to the tMempool to use. | 49 | @param mempool A pointer to the tMempool to use. |
| 50 | 50 | ||
| @@ -66,7 +66,6 @@ extern "C" { · 15 unmodified lines | |||
| 66 | 66 | ||
| 67 | typedef struct _tTable | 67 | typedef struct _tTable |
| 68 | { | 68 | { |
| 69 | |||
| 70 | tMempool mempool; | 69 | tMempool mempool; |
| 71 | 70 | ||
| 72 | float* waveTable; | 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 | @defgroup tcycle tCycle | 153 | @defgroup tcycle tCycle |
| 91 | @ingroup oscillators | 154 | @ingroup oscillators |
| @@ -828,7 +828,6 @@ void tSVF_initToPool (tSVF* const svff, SVFType type, float freq, float Q · 827 unmodified lines | |||
| 828 | svf->cL = 0.0f; | 828 | svf->cL = 0.0f; |
| 829 | } | 829 | } |
| 830 | 830 | ||
| 831 | |||
| 832 | else if (type == SVFTypePeak) | 831 | else if (type == SVFTypePeak) |
| 833 | { | 832 | { |
| 834 | svf->cH = 1.0f; | 833 | svf->cH = 1.0f; |
| @@ -974,12 +973,12 @@ void tEfficientSVF_setQ(tEfficientSVF* const svff, float Q) · 139 unmodified lines | |||
| 974 | #endif // LEAF_INCLUDE_FILTERTAN_TABLE | 973 | #endif // LEAF_INCLUDE_FILTERTAN_TABLE |
| 975 | 974 | ||
| 976 | /* Highpass */ | 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 | tHighpass_initToPool(ft, freq, &leaf->mempool); | 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 | _tMempool* m = *mp; | 983 | _tMempool* m = *mp; |
| 985 | _tHighpass* f = *ft = (_tHighpass*) mpool_calloc(sizeof(_tHighpass), m); | 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 | f->frequency = freq; | 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 | _tHighpass* f = *ft; | 998 | _tHighpass* f = *ft; |
| 1000 | 999 | ||
| 1001 | mpool_free((char*)f, f->mempool); | 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 | _tHighpass* f = *ft; | 1005 | _tHighpass* f = *ft; |
| 1007 | LEAF* leaf = f->mempool->leaf; | 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 | _tHighpass* f = *ft; | 1015 | _tHighpass* f = *ft; |
| 1017 | return f->frequency; | 1016 | return f->frequency; |
| 1018 | } | 1017 | } |
| 1019 | 1018 | ||
| 1020 | // From JOS DC Blocker | 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 | _tHighpass* f = *ft; | 1022 | _tHighpass* f = *ft; |
| 1024 | f->ys = x - f->xs + f->R * f->ys; | 1023 | f->ys = x - f->xs + f->R * f->ys; |
| @@ -1034,12 +1033,12 @@ void tHighpassSampleRateChanged(tHighpass* const ft) · 9 unmodified lines | |||
| 1034 | f->R = (1.0f-((f->frequency * 2.0f * 3.14f) * leaf->invSampleRate)); | 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 | _tMempool* m = *mp; | 1043 | _tMempool* m = *mp; |
| 1045 | _tButterworth* f = *ft = (_tButterworth*) mpool_alloc(sizeof(_tButterworth), m); | 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 | f->f2 = f2; | 1048 | f->f2 = f2; |
| 1050 | f->gain = 1.0f; | 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); | 1060 | if (f1 >= 0.0f) |
| 1059 | tSVF_initToPool(&f->high[i], SVFTypeLowpass, f2, 0.5f/cosf((1.0f+2.0f*i)*PI/(2*N)), mp); | 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 | _tButterworth* f = *ft; | 1069 | _tButterworth* f = *ft; |
| 1066 | 1070 | ||
| 1067 | for(int i = 0; i < f->N/2; ++i) | 1071 | for(int i = 0; i < f->numSVF; ++i) |
| 1068 | { | 1072 | tSVF_free(&f->svf[i]); |
| 1069 | tSVF_free(&f->low[i]); | ||
| 1070 | tSVF_free(&f->high[i]); | ||
| 1071 | } | ||
| 1072 | 1073 | ||
| 1073 | mpool_free((char*)f, f->mempool); | 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 | _tButterworth* f = *ft; | 1079 | _tButterworth* f = *ft; |
| 1079 | 1080 | ||
| 1080 | for(int i = 0; i < ((f->N)/2); ++i) | 1081 | for(int i = 0; i < f->numSVF; ++i) |
| 1081 | { | 1082 | samp = tSVF_tick(&f->svf[i], samp); |
| 1082 | samp = tSVF_tick(&f->low[i],samp); | 1083 | |
| 1083 | samp = tSVF_tick(&f->high[i],samp); | ||
| 1084 | } | ||
| 1085 | return samp; | 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 | _tButterworth* f = *ft; | 1089 | _tButterworth* f = *ft; |
| 1091 | 1090 | ||
| 1091 | if (f->f1 < 0.0f || f1 < 0.0f) return; | ||
| 1092 | |||
| 1092 | f->f1 = f1; | 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 | void tButterworth_setF2(tButterworth* const ft, float f2) | 1097 | void tButterworth_setF2(tButterworth* const ft, float f2) |
| 1097 | { | 1098 | { |
| 1098 | _tButterworth* f = *ft; | 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 | f->f2 = f2; | 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 | void tButterworth_setFreqs(tButterworth* const ft, float f1, float f2) | 1109 | void tButterworth_setFreqs(tButterworth* const ft, float f1, float f2) |
| 1105 | { | 1110 | { |
| 1106 | _tButterworth* f = *ft; | 1111 | // _tButterworth* f = *ft; |
| 1107 | 1112 | tButterworth_setF1(ft, f1); | |
| 1108 | f->f1 = f1; | 1113 | tButterworth_setF1(ft, f2); |
| 1109 | f->f2 = f2; | 1114 | // f->f1 = f1; |
| 1110 | for(int i = 0; i < ((f->N)/2); ++i) | 1115 | // f->f2 = f2; |
| 1111 | { | 1116 | // for(int i = 0; i < ((f->N)/2); ++i) |
| 1112 | tSVF_setFreq(&f->low[i], f1); | 1117 | // { |
| 1113 | tSVF_setFreq(&f->high[i], f2); | 1118 | // tSVF_setFreq(&f->low[i], f1); |
| 1114 | } | 1119 | // tSVF_setFreq(&f->high[i], f2); |
| 1120 | // } | ||
| 1115 | } | 1121 | } |
| 1116 | 1122 | ||
| 1117 | void tFIR_init(tFIR* const firf, float* coeffs, int numTaps, LEAF* const leaf) | 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 | c->inc = c->freq * leaf->invSampleRate; | 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 | #if LEAF_INCLUDE_SINE_TABLE | 206 | #if LEAF_INCLUDE_SINE_TABLE |
| 90 | // Cycle | 207 | // Cycle |
| 91 | void tCycle_init(tCycle* const cy, LEAF* const leaf) | 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 | c->inc = c->freq * leaf->invSampleRate; | 456 | c->inc = c->freq * leaf->invSampleRate; |
| 340 | 457 | ||
| 458 | // base freq 20 | ||
| 341 | c->w = c->freq * INV_20; | 459 | c->w = c->freq * INV_20; |
| 342 | for (c->oct = 0; c->w > 2.0f; c->oct++) | 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 | // Wavetable synthesis | 480 | // Wavetable synthesis |
| 363 | out = __leaf_table_sawtooth[c->oct+1][idx] + | 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 | return out; | 484 | return out; |
| 367 | } | 485 | } |
| @@ -54,6 +54,10 @@ · 53 unmodified lines | |||
| 54 | //! Include tables for minblep insertion, required for all tMB objects. | 54 | //! Include tables for minblep insertion, required for all tMB objects. |
| 55 | #define LEAF_INCLUDE_MINBLEP_TABLES 1 | 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 | #endif // LEAF_CONFIG_H_INCLUDED | 63 | #endif // LEAF_CONFIG_H_INCLUDED |