History

split Wavetable into WaveTable and WaveOsc; rework Waveset into WaveSynth

Matthew Wang committed 5 years ago

Commit 23656d71 parent 6da3c644 files · +651 −230Browse files

Unified · Split

4 files
  1. TestPlugin/Source/MyTest.cpp +19 −20
  2. leaf/Inc/leaf-oscillators.h +248 −105
  3. leaf/Src/leaf-oscillators.c +383 −104
  4. leaf/leaf-config.h +1 −1
TestPlugin/Source/MyTest.cpp+19−20
@@ -31,15 +31,15 @@ tTriangle tri; · 30 unmodified lines
31tNoise noise;31tNoise noise;
32tButterworth bw;32tButterworth bw;
33 33
34tWavetable wt;34tWaveTable wt;
35tCompactWavetable cwt;35tCompactWaveTable cwt;
36tWaveset ws;36tWaveSynth ws;
37 37
38tBuffer samp;38tBuffer samp;
39tMBSampler sampler;39tMBSampler sampler;
40 40
41const int numWavetables = 1;41const int numWavetables = 1;
42tWavetable wavetables[numWavetables];42tWaveTable wavetables[numWavetables];
43 43
44float gain;44float gain;
45float dtime;45float dtime;
@@ -63,8 +63,8 @@ void LEAFTest_init (float sampleRate, int blockSize) · 17 unmodified lines
63{63{
64 LEAF_init(&leaf, sampleRate, blockSize, memory, MSIZE, &getRandomFloat);64 LEAF_init(&leaf, sampleRate, blockSize, memory, MSIZE, &getRandomFloat);
65 65
66// tWavetable_init(&wt, __leaf_table_sawtooth[0], 2048, 10000.f, &leaf);66// tWaveTable_init(&wt, __leaf_table_sawtooth[0], 2048, 10000.f, &leaf);
67// tCompactWavetable_init(&cwt, __leaf_table_sawtooth[0], 2048, 10000.f, &leaf);67// tCompactWaveTable_init(&cwt, __leaf_table_sawtooth[0], 2048, 10000.f, &leaf);
68 68
69 tMBTriangle_init(&btri, &leaf);69 tMBTriangle_init(&btri, &leaf);
70 tMBPulse_init(&bpulse, &leaf);70 tMBPulse_init(&bpulse, &leaf);
@@ -77,15 +77,14 @@ void LEAFTest_init (float sampleRate, int blockSize) · 6 unmodified lines
77 tPhasor_setFreq(&phasor, 220.f);77 tPhasor_setFreq(&phasor, 220.f);
78 78
79 float* set[4];79 float* set[4];
80 set[0] = __leaf_table_sinewave;80 set[0] = (float*)__leaf_table_sinewave;
81 set[1] = __leaf_table_triangle[0];81 set[1] = (float*)__leaf_table_triangle[0];
82 set[2] = __leaf_table_squarewave[0];82 set[2] = (float*)__leaf_table_squarewave[0];
83 set[3] = __leaf_table_sawtooth[0];83 set[3] = (float*)__leaf_table_sawtooth[0];
84 int sizes[4];84 int sizes[4];
85 for (int i = 0; i < 4; i++) sizes[i] = 2048;85 for (int i = 0; i < 4; i++) sizes[i] = 2048;
86 86
87 tWaveset_init(&ws, set, 4, sizes, 10000.f, &leaf);87 tWaveSynth_init(&ws, 1, set, sizes, 4, 10000.f, &leaf);
88 tWaveset_setIndexGain(&ws, 0, -1.0f);
89 88
90 lastLoadedAudioSize = 0;89 lastLoadedAudioSize = 0;
91 loadedAudio.clear();90 loadedAudio.clear();
@@ -105,7 +104,7 @@ float LEAFTest_tick (float input) · 13 unmodified lines
105 float out = 0.0f;104 float out = 0.0f;
106 for (int i = 0; i < fmin(loadedAudio.size(), numWavetables); ++i)105 for (int i = 0; i < fmin(loadedAudio.size(), numWavetables); ++i)
107 {106 {
108 out += tWavetable_tick(&wavetables[i]);107// out += tWaveTable_tick(&wavetables[i]);
109 }108 }
110 return out;109 return out;
111}110}
@@ -118,14 +117,14 @@ void LEAFTest_block (void) · 6 unmodified lines
118 tMBTriangle_setFreq(&btri, val * 440.f);117 tMBTriangle_setFreq(&btri, val * 440.f);
119 tMBPulse_setFreq(&bpulse, val * 160000.f - 80000.0f);118 tMBPulse_setFreq(&bpulse, val * 160000.f - 80000.0f);
120 tMBSaw_setFreq(&bsaw, val * 10000.f);119 tMBSaw_setFreq(&bsaw, val * 10000.f);
121// tWavetable_setFreq(&wt, val * 160000.f - 80000.0f);120// tWaveTable_setFreq(&wt, val * 160000.f - 80000.0f);
122// tCompactWavetable_setFreq(&cwt, val * 10000.);121// tCompactWaveTable_setFreq(&cwt, val * 10000.);
123 tWaveset_setFreq(&ws, val * 10000.f);122 tWaveSynth_setFreq(&ws, 0, val * 10000.f);
124// tRetune_tuneVoice(&retune, 0, val * 3.0f + 0.5f);123// tRetune_tuneVoice(&retune, 0, val * 3.0f + 0.5f);
125// tSimpleRetune_tuneVoice(&sretune, 0, 300);124// tSimpleRetune_tuneVoice(&sretune, 0, 300);
126 125
127 val = getSliderValue("slider2");126 val = getSliderValue("slider2");
128 tWaveset_setIndex(&ws, val);127 tWaveSynth_setIndex(&ws, val);
129// tRetune_setPitchFactor(&retune, val * 3.0f + 0.5f, 1);128// tRetune_setPitchFactor(&retune, val * 3.0f + 0.5f, 1);
130 129
131 val = getSliderValue("slider3");130 val = getSliderValue("slider3");
@@ -134,12 +133,12 @@ void LEAFTest_block (void) · 2 unmodified lines
134 if (lastLoadedAudioSize < loadedAudio.size())133 if (lastLoadedAudioSize < loadedAudio.size())
135 {134 {
136 int i = (loadedAudio.size() - 1) % numWavetables;135 int i = (loadedAudio.size() - 1) % numWavetables;
137 if (loadedAudio.size() - 1 >= numWavetables) tWavetable_free(&wavetables[i]);136 if (loadedAudio.size() - 1 >= numWavetables) tWaveTable_free(&wavetables[i]);
138 tWavetable_init(&wavetables[i], loadedAudio[loadedAudio.size() - 1].getReadPointer(0), loadedAudio[loadedAudio.size() - 1].getNumSamples(), 20000, &leaf);137 tWaveTable_init(&wavetables[i], (float*)loadedAudio[loadedAudio.size() - 1].getReadPointer(0), loadedAudio[loadedAudio.size() - 1].getNumSamples(), 20000, &leaf);
139 138
140 lastLoadedAudioSize = loadedAudio.size();139 lastLoadedAudioSize = loadedAudio.size();
141 }140 }
142 if (loadedAudio.size() > 0) tWavetable_setFreq(&wavetables[0], 220);//val * 10000.f);141// if (loadedAudio.size() > 0) tWaveTable_setFreq(&wavetables[0], 220);//val * 10000.f);
143}142}
144 143
145void LEAFTest_controllerInput (int cnum, float cval)144void LEAFTest_controllerInput (int cnum, float cval)
leaf/Inc/leaf-oscillators.h+248−105
@@ -922,44 +922,34 @@ extern "C" { · 921 unmodified lines
922 //==============================================================================922 //==============================================================================
923 923
924 /*!924 /*!
925 @defgroup twavetable tWavetable925 @defgroup twavetable tWaveTable
926 @ingroup oscillators926 @ingroup oscillators
927 @brief Anti-aliased wavetable oscillator.927 @brief Anti-aliased wavetable generator.
928 @{928 @{
929 929
930 @fn void tWavetable_init (tWavetable* const osc, float* table, int size, float maxFreq, LEAF* const leaf)930 @fn void tWaveTable_init (tWaveTable* const osc, float* table, int size, float maxFreq, LEAF* const leaf)
931 @brief Initialize a tWavetable to the default mempool of a LEAF instance.931 @brief Initialize a tWaveTable to the default mempool of a LEAF instance.
932 @param osc A pointer to the tWavetable to initialize.932 @param osc A pointer to the tWaveTable to initialize.
933 @param table A pointer to the wavetable data.933 @param table A pointer to the wavetable data.
934 @param size The number of samples in the wavetable.934 @param size The number of samples in the wavetable.
935 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.935 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.
936 @param leaf A pointer to the leaf instance.936 @param leaf A pointer to the leaf instance.
937 937
938 @fn void tWavetable_initToPool (tWavetable* const osc, float* table, int size, float maxFreq, tMempool* const mempool)938 @fn void tWaveTable_initToPool (tWaveTable* const osc, float* table, int size, float maxFreq, tMempool* const mempool)
939 @brief Initialize a tWavetable to a specified mempool.939 @brief Initialize a tWaveTable to a specified mempool.
940 @param osc A pointer to the tWavetable to initialize.940 @param osc A pointer to the tWaveTable to initialize.
941 @param table A pointer to the wavetable data.941 @param table A pointer to the wavetable data.
942 @param size The number of samples in the wave table.942 @param size The number of samples in the wave table.
943 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.943 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.
944 @param mempool A pointer to the tMempool to use.944 @param mempool A pointer to the tMempool to use.
945 945
946 @fn void tWavetable_free (tWavetable* const osc)946 @fn void tWaveTable_free (tWaveTable* const osc)
947 @brief Free a tWavetable from its mempool.947 @brief Free a tWaveTable from its mempool.
948 @param osc A pointer to the tWavetable to free.948 @param osc A pointer to the tWaveTable to free.
949
950 @fn float tWavetable_tick (tWavetable* const osc)
951 @brief Tick a tWavetable oscillator.
952 @param osc A pointer to the relevant tWavetable.
953 @return The ticked sample as a float from -1 to 1.
954
955 @fn void tWavetable_setFreq (tWavetable* const osc, float freq)
956 @brief Set the frequency of a tWavetable oscillator.
957 @param osc A pointer to the relevant tWavetable.
958 @param freq The frequency to set the oscillator to.
959 949
960 @} */950 @} */
961 951
962 typedef struct _tWavetable952 typedef struct _tWaveTable
963 {953 {
964 tMempool mempool;954 tMempool mempool;
965 955
@@ -967,6 +957,41 @@ extern "C" { · 1 unmodified line
967 int size;957 int size;
968 int numTables;958 int numTables;
969 float baseFreq, invBaseFreq;959 float baseFreq, invBaseFreq;
960 tButterworth bl;
961 } _tWaveTable;
962
963 typedef _tWaveTable* tWaveTable;
964
965 void tWaveTable_init(tWaveTable* const osc, float* table, int size,
966 float maxFreq, LEAF* const leaf);
967 void tWaveTable_initToPool(tWaveTable* const osc, float* table, int size,
968 float maxFreq, tMempool* const mempool);
969 void tWaveTable_free(tWaveTable* const osc);
970
971 //==============================================================================
972
973 /*!
974 @defgroup twavetableosc tWaveOsc
975 @ingroup oscillators
976 @brief Anti-aliased wavetable oscillator.
977 @{
978
979 @fn float tWaveTable_tick (tWaveTable* const osc)
980 @brief Tick a tWaveTable oscillator.
981 @param osc A pointer to the relevant tWaveTable.
982 @return The ticked sample as a float from -1 to 1.
983
984 @fn void tWaveTable_setFreq (tWaveTable* const osc, float freq)
985 @brief Set the frequency of a tWaveTable oscillator.
986 @param osc A pointer to the relevant tWaveTable.
987 @param freq The frequency to set the oscillator to.
988
989 @} */
990
991 typedef struct _tWaveOsc
992 {
993 tMempool mempool;
994 tWaveTable table;
970 float inc, freq;995 float inc, freq;
971 float phase;996 float phase;
972 float phaseOffset;997 float phaseOffset;
@@ -974,62 +999,126 @@ extern "C" { · 1 unmodified line
974 int oct;999 int oct;
975 float w;1000 float w;
976 float aa;1001 float aa;
977 1002 } _tWaveOsc;
978 tButterworth bl;
979 } _tWavetable;
980 1003
981 typedef _tWavetable* tWavetable;1004 typedef _tWaveOsc* tWaveOsc;
982 1005
983 void tWavetable_init(tWavetable* const osc, float* table, int size, float maxFreq, LEAF* const leaf);1006 void tWaveOsc_init(tWaveOsc* const osc, tWaveTable* const table, LEAF* const leaf);
984 void tWavetable_initToPool(tWavetable* const osc, float* table, int size, float maxFreq, tMempool* const mempool);1007 void tWaveOsc_initToPool(tWaveOsc* const osc, tWaveTable* const table, tMempool* const mempool);
985 void tWavetable_free(tWavetable* const osc);1008 void tWaveOsc_free(tWaveOsc* const osc);
986 1009
987 float tWavetable_tick(tWavetable* const osc);1010 float tWaveOsc_tick(tWaveOsc* const osc);
988 void tWavetable_setFreq(tWavetable* const osc, float freq);1011 void tWaveOsc_setFreq(tWaveOsc* const osc, float freq);
989 void tWavetable_setAntiAliasing(tWavetable* const osc, float aa);1012 void tWaveOsc_setAntiAliasing(tWaveOsc* const osc, float aa);
990 void tWavetable_setPhaseOffset(tWavetable* const osc, float phase);1013 void tWaveOsc_setPhaseOffset(tWaveOsc* const osc, float phase);
991 1014
992 //==============================================================================1015 //==============================================================================
993 1016
994 /*!1017 /*!
995 @defgroup tcompactwavetable tCompactWavetable1018 @defgroup twaveset tWaveSynth
996 @ingroup oscillators1019 @ingroup oscillators
997 @brief A more space-efficient anti-aliased wavetable oscillator than tWavetable but with slightly worse fidelity.1020 @brief Set of anti-aliased wavetable oscillators that can be faded between.
998 @{1021 @{
999 1022
1000 @fn void tCompactWavetable_init (tCompactWavetable* const osc, float* table, int size, float maxFreq, LEAF* const leaf)1023 @fn void tWaveSynth_init(tWaveSynth* const osc, const float** tables, int n, int size, float maxFreq, LEAF* const leaf)
1001 @brief Initialize a tCompactWavetable to the default mempool of a LEAF instance.1024 @brief Initialize a tWaveSynth to the default mempool of a LEAF instance.
1002 @param osc A pointer to the tCompactWavetable to initialize.1025 @param osc A pointer to the tWaveSynth to initialize.
1003 @param table A pointer to the wavetable data.1026 @param tables An array of pointers to wavetable data.
1004 @param size The number of samples in the wavetable.1027 @param n The number of wavetables.
1028 @param size The number of samples in each of the wavetables.
1005 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.1029 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.
1006 @param leaf A pointer to the leaf instance.1030 @param leaf A pointer to the leaf instance.
1007 1031
1008 @fn void tCompactWavetable_initToPool (tCompactWavetable* const osc, float* table, int size, float maxFreq, tMempool* const mempool)1032 @fn void tWaveSynth_initToPool(tWaveSynth* const osc, const float** tables, int n, int size, float maxFreq, tMempool* const mempool)
1009 @brief Initialize a tCompactWavetable to a specified mempool.1033 @brief Initialize a tWaveSynth to a specified mempool.
1010 @param osc A pointer to the tCompactWavetable to initialize.1034 @param osc A pointer to the tWaveTable to initialize.
1011 @param table A pointer to the wavetable data.1035 @param tables An array of pointers to wavetable data.
1012 @param size The number of samples in the wave table.1036 @param n The number of wavetables.
1037 @param size The number of samples in each of the wavetables.
1013 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.1038 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.
1014 @param mempool A pointer to the tMempool to use.1039 @param mempool A pointer to the tMempool to use.
1015 1040
1016 @fn void tCompactWavetable_free (tCompactWavetable* const osc)1041 @fn void tWaveSynth_free (tWaveSynth* const osc)
1017 @brief Free a tCompactWavetable from its mempool.1042 @brief Free a tWaveSynth from its mempool.
1018 @param osc A pointer to the tCompactWavetable to free.1043 @param osc A pointer to the tWaveSynth to free.
1019 1044
1020 @fn float tCompactWavetable_tick (tCompactWavetable* const osc)1045 @fn float tWaveSynth_tick (tWaveSynth* const osc)
1021 @brief Tick a tCompactWavetable oscillator.1046 @brief Tick a tWaveSynth oscillator.
1022 @param osc A pointer to the relevant tCompactWavetable.1047 @param osc A pointer to the relevant tWaveSynth.
1023 @return The ticked sample as a float from -1 to 1.1048 @return The ticked sample as a float from -1 to 1.
1024 1049
1025 @fn void tCompactWavetable_setFreq (tCompactWavetable* const osc, float freq)1050 @fn void tWaveSynth_setFreq (tWaveSynth* const osc, float freq)
1026 @brief Set the frequency of a tCompactWavetable oscillator.1051 @brief Set the frequency of a tWaveSynth oscillator.
1027 @param osc A pointer to the relevant tCompactWavetable.1052 @param osc A pointer to the relevant tWaveSynth.
1028 @param freq The frequency to set the oscillator to.1053 @param freq The frequency to set the oscillator to.
1029 1054
1055 @fn void tWaveSynth_setIndex(tWaveSynth* const osc, float index)
1056 @brief Set the output index of the wavetable set.
1057 @param index The new index from 0.0 to 1.0 as a smooth fade from the first wavetable in the set to the last.
1058
1059 @} */
1060
1061 typedef struct _tWaveSynth
1062 {
1063 tMempool mempool;
1064
1065 tWaveTable* tables;
1066 tWaveOsc** oscs;
1067 int numTables;
1068 int numVoices;
1069 float* g;
1070 float index;
1071 float maxFreq;
1072 } _tWaveSynth;
1073
1074 typedef _tWaveSynth* tWaveSynth;
1075
1076 void tWaveSynth_init(tWaveSynth* const osc, int numVoices, float** tables, int* sizes,
1077 int numTables, float maxFreq, LEAF* const leaf);
1078 void tWaveSynth_initToPool(tWaveSynth* const osc, int numVoices, float** tables, int* sizes,
1079 int numTables, float maxFreq, tMempool* const mempool);
1080 void tWaveSynth_free(tWaveSynth* const osc);
1081
1082 float tWaveSynth_tick(tWaveSynth* const osc);
1083 float tWaveSynth_tickVoice(tWaveSynth* const cy, int voice);
1084 void tWaveSynth_setFreq(tWaveSynth* const osc, int voice, float freq);
1085 void tWaveSynth_setAntiAliasing(tWaveSynth* const osc, float aa);
1086 void tWaveSynth_setIndex(tWaveSynth* const osc, float index);
1087 void tWaveSynth_setIndexGain(tWaveSynth* const osc, int i, float gain);
1088 void tWaveSynth_setIndexPhase(tWaveSynth* const osc, int i, float phase);
1089// void tWaveSynth_setIndexTable(tWaveSynth* const osc, int i, float* table, int size);
1090
1091 //==============================================================================
1092
1093 /*!
1094 @defgroup tcompactwavetable tCompactWaveTable
1095 @ingroup oscillators
1096 @brief A more space-efficient anti-aliased wavetable generator than tWaveTable but with slightly worse fidelity.
1097 @{
1098
1099 @fn void tCompactWaveTable_init (tCompactWaveTable* const osc, float* table, int size, float maxFreq, LEAF* const leaf)
1100 @brief Initialize a tCompactWaveTable to the default mempool of a LEAF instance.
1101 @param osc A pointer to the tCompactWaveTable to initialize.
1102 @param table A pointer to the wavetable data.
1103 @param size The number of samples in the wavetable.
1104 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.
1105 @param leaf A pointer to the leaf instance.
1106
1107 @fn void tCompactWaveTable_initToPool (tCompactWaveTable* const osc, float* table, int size, float maxFreq, tMempool* const mempool)
1108 @brief Initialize a tCompactWaveTable to a specified mempool.
1109 @param osc A pointer to the tCompactWaveTable to initialize.
1110 @param table A pointer to the wavetable data.
1111 @param size The number of samples in the wave table.
1112 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.
1113 @param mempool A pointer to the tMempool to use.
1114
1115 @fn void tCompactWaveTable_free (tCompactWaveTable* const osc)
1116 @brief Free a tCompactWaveTable from its mempool.
1117 @param osc A pointer to the tCompactWaveTable to free.
1118
1030 @} */1119 @} */
1031 1120
1032 typedef struct _tCompactWavetable1121 typedef struct _tCompactWaveTable
1033 {1122 {
1034 tMempool mempool;1123 tMempool mempool;
1035 1124
@@ -1037,99 +1126,153 @@ extern "C" { · 1 unmodified line
1037 int numTables;1126 int numTables;
1038 int* sizes;1127 int* sizes;
1039 float baseFreq, invBaseFreq;1128 float baseFreq, invBaseFreq;
1129 tButterworth bl;
1130 float dsBuffer[2];
1131 tOversampler ds;
1132 } _tCompactWaveTable;
1133
1134 typedef _tCompactWaveTable* tCompactWaveTable;
1135
1136 void tCompactWaveTable_init(tCompactWaveTable* const osc, float* table, int size, float maxFreq, LEAF* const leaf);
1137 void tCompactWaveTable_initToPool(tCompactWaveTable* const osc, float* table, int size, float maxFreq, tMempool* const mempool);
1138 void tCompactWaveTable_free(tCompactWaveTable* const osc);
1139
1140 /*!
1141 @defgroup tcompactwaveosc tCompactWaveOsc
1142 @ingroup oscillators
1143 @brief A more space-efficient anti-aliased wavetable oscillator than tWaveOsc but with slightly worse fidelity.
1144 @{
1145
1146 @fn void tCompactWaveOsc_init (tCompactWaveOsc* const osc, float* table, int size, float maxFreq, LEAF* const leaf)
1147 @brief Initialize a tCompactWaveOsc to the default mempool of a LEAF instance.
1148 @param osc A pointer to the tCompactWaveOsc to initialize.
1149 @param table A pointer to the wavetable data.
1150 @param size The number of samples in the wavetable.
1151 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.
1152 @param leaf A pointer to the leaf instance.
1153
1154 @fn void tCompactWaveOsc_initToPool (tCompactWaveOsc* const osc, float* table, int size, float maxFreq, tMempool* const mempool)
1155 @brief Initialize a tCompactWaveOsc to a specified mempool.
1156 @param osc A pointer to the tCompactWaveOsc to initialize.
1157 @param table A pointer to the wavetable data.
1158 @param size The number of samples in the wave table.
1159 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.
1160 @param mempool A pointer to the tMempool to use.
1161
1162 @fn void tCompactWaveOsc_free (tCompactWaveOsc* const osc)
1163 @brief Free a tCompactWaveOsc from its mempool.
1164 @param osc A pointer to the tCompactWaveOsc to free.
1165
1166 @fn float tCompactWaveOsc_tick (tCompactWaveOsc* const osc)
1167 @brief Tick a tCompactWaveOsc oscillator.
1168 @param osc A pointer to the relevant tCompactWaveOsc.
1169 @return The ticked sample as a float from -1 to 1.
1170
1171 @fn void tCompactWaveOsc_setFreq (tCompactWaveOsc* const osc, float freq)
1172 @brief Set the frequency of a tCompactWaveOsc oscillator.
1173 @param osc A pointer to the relevant tCompactWaveOsc.
1174 @param freq The frequency to set the oscillator to.
1175
1176 @} */
1177
1178 typedef struct _tCompactWaveOsc
1179 {
1180 tMempool mempool;
1181 tCompactWaveTable table;
1040 float inc, freq;1182 float inc, freq;
1041 float phase;1183 float phase;
1042 1184 float phaseOffset;
1043 int oct;1185 int oct;
1044 float w;1186 float w;
1045 float aa;1187 float aa;
1046 1188 } _tCompactWaveOsc;
1047 tButterworth bl;
1048
1049 float dsBuffer[2];
1050 tOversampler ds;
1051 } _tCompactWavetable;
1052 1189
1053 typedef _tCompactWavetable* tCompactWavetable;1190 typedef _tCompactWaveOsc* tCompactWaveOsc;
1054 1191
1055 void tCompactWavetable_init(tCompactWavetable* const osc, float* table, int size, float maxFreq, LEAF* const leaf);1192 void tCompactWaveOsc_init(tCompactWaveOsc* const osc, tCompactWaveTable* const table, LEAF* const leaf);
1056 void tCompactWavetable_initToPool(tCompactWavetable* const osc, float* table, int size, float maxFreq, tMempool* const mempool);1193 void tCompactWaveOsc_initToPool(tCompactWaveOsc* const osc, tCompactWaveTable* const table, tMempool* const mempool);
1057 void tCompactWavetable_free(tCompactWavetable* const osc);1194 void tCompactWaveOsc_free(tCompactWaveOsc* const osc);
1058 1195
1059 float tCompactWavetable_tick(tCompactWavetable* const osc);1196 float tCompactWaveOsc_tick(tCompactWaveOsc* const osc);
1060 void tCompactWavetable_setFreq(tCompactWavetable* const osc, float freq);1197 void tCompactWaveOsc_setFreq(tCompactWaveOsc* const osc, float freq);
1061 void tCompactWavetable_setAntiAliasing(tCompactWavetable* const osc, float aa);1198 void tCompactWaveOsc_setAntiAliasing(tCompactWaveOsc* const osc, float aa);
1199 void tCompactWaveOsc_setPhaseOffset(tCompactWaveOsc* const osc, float phase);
1062 1200
1063 //==============================================================================1201 //==============================================================================
1064 1202
1065 /*!1203 /*!
1066 @defgroup twaveset tWaveset1204 @defgroup tCompactWaveset tCompactWaveSynth
1067 @ingroup oscillators1205 @ingroup oscillators
1068 @brief Set of anti-aliased wavetable oscillators that can be faded between.1206 @brief Set of anti-aliased wavetable oscillators that can be faded between.
1069 @{1207 @{
1070 1208
1071 @fn void tWaveset_init(tWaveset* const osc, const float** tables, int n, int size, float maxFreq, LEAF* const leaf)1209 @fn void tCompactWaveSynth_init(tWaveSynth* const osc, const float** tables, int n, int size, float maxFreq, LEAF* const leaf)
1072 @brief Initialize a tWaveset to the default mempool of a LEAF instance.1210 @brief Initialize a tCompactWaveSynth to the default mempool of a LEAF instance.
1073 @param osc A pointer to the tWaveset to initialize.1211 @param osc A pointer to the tCompactWaveSynth to initialize.
1074 @param tables An array of pointers to wavetable data.1212 @param tables An array of pointers to wavetable data.
1075 @param n The number of wavetables.1213 @param n The number of wavetables.
1076 @param size The number of samples in each of the wavetables.1214 @param size The number of samples in each of the wavetables.
1077 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.1215 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.
1078 @param leaf A pointer to the leaf instance.1216 @param leaf A pointer to the leaf instance.
1079 1217
1080 @fn void tWaveset_initToPool(tWaveset* const osc, const float** tables, int n, int size, float maxFreq, tMempool* const mempool)1218 @fn void tCompactWaveSynth_initToPool(tWaveSynth* const osc, const float** tables, int n, int size, float maxFreq, tMempool* const mempool)
1081 @brief Initialize a tWaveset to a specified mempool.1219 @brief Initialize a tCompactWaveSynth to a specified mempool.
1082 @param osc A pointer to the tWavetable to initialize.1220 @param osc A pointer to the tCompactWaveTable to initialize.
1083 @param tables An array of pointers to wavetable data.1221 @param tables An array of pointers to wavetable data.
1084 @param n The number of wavetables.1222 @param n The number of wavetables.
1085 @param size The number of samples in each of the wavetables.1223 @param size The number of samples in each of the wavetables.
1086 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.1224 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.
1087 @param mempool A pointer to the tMempool to use.1225 @param mempool A pointer to the tMempool to use.
1088 1226
1089 @fn void tWaveset_free (tWaveset* const osc)1227 @fn void tCompactWaveSynth_free (tWaveSynth* const osc)
1090 @brief Free a tWaveset from its mempool.1228 @brief Free a tCompactWaveSynth from its mempool.
1091 @param osc A pointer to the tWaveset to free.1229 @param osc A pointer to the tCompactWaveSynth to free.
1092 1230
1093 @fn float tWaveset_tick (tWaveset* const osc)1231 @fn float tCompactWaveSynth_tick (tWaveSynth* const osc)
1094 @brief Tick a tWaveset oscillator.1232 @brief Tick a tCompactWaveSynth oscillator.
1095 @param osc A pointer to the relevant tWaveset.1233 @param osc A pointer to the relevant tCompactWaveSynth.
1096 @return The ticked sample as a float from -1 to 1.1234 @return The ticked sample as a float from -1 to 1.
1097 1235
1098 @fn void tWaveset_setFreq (tWaveset* const osc, float freq)1236 @fn void tCompactWaveSynth_setFreq (tWaveSynth* const osc, float freq)
1099 @brief Set the frequency of a tWaveset oscillator.1237 @brief Set the frequency of a tCompactWaveSynth oscillator.
1100 @param osc A pointer to the relevant tWaveset.1238 @param osc A pointer to the relevant tCompactWaveSynth.
1101 @param freq The frequency to set the oscillator to.1239 @param freq The frequency to set the oscillator to.
1102 1240
1103 @fn void tWaveset_setIndex(tWaveset* const osc, float index)1241 @fn void tCompactWaveSynth_setIndex(tWaveSynth* const osc, float index)
1104 @brief Set the output index of the wavetable set.1242 @brief Set the output index of the wavetable set.
1105 @param index The new index from 0.0 to 1.0 as a smooth fade from the first wavetable in the set to the last.1243 @param index The new index from 0.0 to 1.0 as a smooth fade from the first wavetable in the set to the last.
1106 1244
1107 @} */1245 @} */
1108 1246
1109 typedef struct _tWaveset1247 typedef struct _tCompactWaveSynth
1110 {1248 {
1111 tMempool mempool;1249 tMempool mempool;
1112 1250
1113 tWavetable* wt;1251 tCompactWaveTable* tables;
1114 int n;1252 tCompactWaveOsc** oscs;
1253 int numTables;
1254 int numVoices;
1115 float* g;1255 float* g;
1116 float* p;
1117 float index;1256 float index;
1118 } _tWaveset;1257 float maxFreq;
1119 1258 } _tCompactWaveSynth;
1120 typedef _tWaveset* tWaveset;1259
1121 1260 typedef _tCompactWaveSynth* tCompactWaveSynth;
1122 void tWaveset_init(tWaveset* const osc, float** tables, int n, int* sizes, float maxFreq, LEAF* const leaf);1261
1123 void tWaveset_initToPool(tWaveset* const osc, float** tables, int n, int* sizes, float maxFreq, tMempool* const mempool);1262 void tCompactWaveSynth_init(tCompactWaveSynth* const osc, int numVoices, float** tables, int* sizes,
1124 void tWaveset_free(tWaveset* const osc);1263 int numTables, float maxFreq, LEAF* const leaf);
1125 1264 void tCompactWaveSynth_initToPool(tCompactWaveSynth* const osc, int numVoices, float** tables, int* sizes,
1126 float tWaveset_tick(tWaveset* const osc);1265 int numTables, float maxFreq, tMempool* const mempool);
1127 void tWaveset_setFreq(tWaveset* const osc, float freq);1266 void tCompactWaveSynth_free(tCompactWaveSynth* const osc);
1128 void tWaveset_setAntiAliasing(tWaveset* const osc, float aa);1267
1129 void tWaveset_setIndex(tWaveset* const osc, float index);1268 float tCompactWaveSynth_tick(tCompactWaveSynth* const osc);
1130 void tWaveset_setIndexGain(tWaveset* const osc, int i, float gain);1269 float tCompactWaveSynth_tickVoice(tCompactWaveSynth* const cy, int voice);
1131 void tWaveset_setIndexPhase(tWaveset* const osc, int i, float phase);1270 void tCompactWaveSynth_setFreq(tCompactWaveSynth* const osc, int voice, float freq);
1132 1271 void tCompactWaveSynth_setAntiAliasing(tCompactWaveSynth* const osc, float aa);
1272 void tCompactWaveSynth_setIndex(tCompactWaveSynth* const osc, float index);
1273 void tCompactWaveSynth_setIndexGain(tCompactWaveSynth* const osc, int i, float gain);
1274 void tCompactWaveSynth_setIndexPhase(tCompactWaveSynth* const osc, int i, float phase);
1275// void tCompactWaveSynth_setIndexTable(tCompactWaveSynth* const osc, int i, float* table, int size);
1133 1276
1134#ifdef __cplusplus1277#ifdef __cplusplus
1135}1278}
leaf/Src/leaf-oscillators.c+383−104
@@ -1704,15 +1704,15 @@ void tTableSampleRateChanged(tTable* const cy) · 1703 unmodified lines
1704 c->inc -= (int)c->inc;1704 c->inc -= (int)c->inc;
1705}1705}
1706 1706
1707void tWavetable_init(tWavetable* const cy, float* table, int size, float maxFreq, LEAF* const leaf)1707void tWaveTable_init(tWaveTable* const cy, float* table, int size, float maxFreq, LEAF* const leaf)
1708{1708{
1709 tWavetable_initToPool(cy, table, size, maxFreq, &leaf->mempool);1709 tWaveTable_initToPool(cy, table, size, maxFreq, &leaf->mempool);
1710}1710}
1711 1711
1712void tWavetable_initToPool(tWavetable* const cy, float* table, int size, float maxFreq, tMempool* const mp)1712void tWaveTable_initToPool(tWaveTable* const cy, float* table, int size, float maxFreq, tMempool* const mp)
1713{1713{
1714 _tMempool* m = *mp;1714 _tMempool* m = *mp;
1715 _tWavetable* c = *cy = (_tWavetable*) mpool_alloc(sizeof(_tWavetable), m);1715 _tWaveTable* c = *cy = (_tWaveTable*) mpool_alloc(sizeof(_tWaveTable), m);
1716 c->mempool = m;1716 c->mempool = m;
1717 1717
1718 // Determine base frequency1718 // Determine base frequency
@@ -1764,18 +1764,11 @@ void tWavetable_initToPool(tWavetable* const cy, float* table, int size, float m · 45 unmodified lines
1764 f *= 0.5f; //halve the cutoff for next pass1764 f *= 0.5f; //halve the cutoff for next pass
1765 }1765 }
1766 tButterworth_free(&c->bl);1766 tButterworth_free(&c->bl);
1767
1768
1769 c->inc = 0.0f;
1770 c->phase = 0.0f;
1771 c->aa = 0.5f;
1772
1773 tWavetable_setFreq(cy, 220);
1774}1767}
1775 1768
1776void tWavetable_free(tWavetable* const cy)1769void tWaveTable_free(tWaveTable* const cy)
1777{1770{
1778 _tWavetable* c = *cy;1771 _tWaveTable* c = *cy;
1779 1772
1780 for (int t = 0; t < c->numTables; ++t)1773 for (int t = 0; t < c->numTables; ++t)
1781 {1774 {
@@ -1785,9 +1778,39 @@ void tWavetable_free(tWavetable* const cy) · 3 unmodified lines
1785 mpool_free((char*)c, c->mempool);1778 mpool_free((char*)c, c->mempool);
1786}1779}
1787 1780
1788float tWavetable_tick(tWavetable* const cy)1781//=======================================================================================
1782//=======================================================================================
1783
1784void tWaveOsc_init(tWaveOsc* const cy, tWaveTable* const table, LEAF* const leaf)
1785{
1786 tWaveOsc_initToPool(cy, table, &leaf->mempool);
1787}
1788
1789void tWaveOsc_initToPool(tWaveOsc* const cy, tWaveTable* const table, tMempool* const mp)
1789{1790{
1790 _tWavetable* c = *cy;1791 _tMempool* m = *mp;
1792 _tWaveOsc* c = *cy = (_tWaveOsc*) mpool_alloc(sizeof(_tWaveOsc), m);
1793 c->mempool = m;
1794
1795 c->table = *table;
1796
1797 c->inc = 0.0f;
1798 c->phase = 0.0f;
1799 c->phaseOffset = 0.0f;
1800 c->aa = 0.5f;
1801
1802 tWaveOsc_setFreq(cy, 220);
1803}
1804
1805void tWaveOsc_free(tWaveOsc* const cy)
1806{
1807 _tWaveOsc* c = *cy;
1808 mpool_free((char*)c, c->mempool);
1809}
1810
1811float tWaveOsc_tick(tWaveOsc* const cy)
1812{
1813 _tWaveOsc* c = *cy;
1791 1814
1792 float temp;1815 float temp;
1793 int idx;1816 int idx;
@@ -1795,35 +1818,38 @@ float tWavetable_tick(tWavetable* const cy) · 1 unmodified line
1795 float samp0;1818 float samp0;
1796 float samp1;1819 float samp1;
1797 1820
1821 int size = c->table->size;
1822 float** tables = c->table->tables;
1823
1798 // Phasor increment1824 // Phasor increment
1799 c->phase += c->inc;1825 c->phase += c->inc;
1800 if (c->phase + c->phaseOffset >= 1.0f) c->phase -= 1.0f;1826 if (c->phase + c->phaseOffset >= 1.0f) c->phase -= 1.0f;
1801 if (c->phase + c->phaseOffset < 0.0f) c->phase += 1.0f;1827 if (c->phase + c->phaseOffset < 0.0f) c->phase += 1.0f;
1802 1828
1803 // Wavetable synthesis1829 // Wavetable synthesis
1804 temp = c->size * (c->phase + c->phaseOffset);1830 temp = size * (c->phase + c->phaseOffset);
1805 1831
1806 idx = (int)temp;1832 idx = (int)temp;
1807 frac = temp - (float)idx;1833 frac = temp - (float)idx;
1808 samp0 = c->tables[c->oct][idx];1834 samp0 = tables[c->oct][idx];
1809 if (++idx >= c->size) idx = 0;1835 if (++idx >= size) idx = 0;
1810 samp1 = c->tables[c->oct][idx];1836 samp1 = tables[c->oct][idx];
1811 1837
1812 float oct0 = (samp0 + (samp1 - samp0) * frac);1838 float oct0 = (samp0 + (samp1 - samp0) * frac);
1813 1839
1814 idx = (int)temp;1840 idx = (int)temp;
1815 samp0 = c->tables[c->oct+1][idx];1841 samp0 = tables[c->oct+1][idx];
1816 if (++idx >= c->size) idx = 0;1842 if (++idx >= size) idx = 0;
1817 samp1 = c->tables[c->oct+1][idx];1843 samp1 = tables[c->oct+1][idx];
1818 1844
1819 float oct1 = (samp0 + (samp1 - samp0) * frac);1845 float oct1 = (samp0 + (samp1 - samp0) * frac);
1820 1846
1821 return oct0 + (oct1 - oct0) * c->w;1847 return oct0 + (oct1 - oct0) * c->w;
1822}1848}
1823 1849
1824void tWavetable_setFreq(tWavetable* const cy, float freq)1850void tWaveOsc_setFreq(tWaveOsc* const cy, float freq)
1825{1851{
1826 _tWavetable* c = *cy;1852 _tWaveOsc* c = *cy;
1827 1853
1828 LEAF* leaf = c->mempool->leaf;1854 LEAF* leaf = c->mempool->leaf;
1829 1855
@@ -1833,7 +1859,7 @@ void tWavetable_setFreq(tWavetable* const cy, float freq) · 3 unmodified lines
1833 c->inc -= (int)c->inc;1859 c->inc -= (int)c->inc;
1834 1860
1835 // abs for negative frequencies1861 // abs for negative frequencies
1836 c->w = fabsf(c->freq * c->invBaseFreq);1862 c->w = fabsf(c->freq * c->table->invBaseFreq);
1837 1863
1838 // Probably ok to use a log2 approx here; won't effect tuning at all, just crossfading between octave tables1864 // Probably ok to use a log2 approx here; won't effect tuning at all, just crossfading between octave tables
1839 c->w = log2f_approx(c->w) + c->aa; // adding an offset here will shift our table selection upward, reducing aliasing but lower high freq fidelity. +1.0f should remove all aliasing1865 c->w = log2f_approx(c->w) + c->aa; // adding an offset here will shift our table selection upward, reducing aliasing but lower high freq fidelity. +1.0f should remove all aliasing
@@ -1843,32 +1869,201 @@ void tWavetable_setFreq(tWavetable* const cy, float freq) · 3 unmodified lines
1843 1869
1844 // When out of range of our tables, this will prevent a crash.1870 // When out of range of our tables, this will prevent a crash.
1845 // Also causes a blip but fine since we're above maxFreq at this point.1871 // Also causes a blip but fine since we're above maxFreq at this point.
1846 if (c->oct >= c->numTables - 1) c->oct = c->numTables - 2;1872 if (c->oct >= c->table->numTables - 1) c->oct = c->table->numTables - 2;
1847}1873}
1848 1874
1849void tWavetable_setAntiAliasing(tWavetable* const cy, float aa)1875void tWaveOsc_setAntiAliasing(tWaveOsc* const cy, float aa)
1850{1876{
1851 _tWavetable* c = *cy;1877 _tWaveOsc* c = *cy;
1852 c->aa = aa;1878 c->aa = aa;
1853 tWavetable_setFreq(cy, c->freq);1879 tWaveOsc_setFreq(cy, c->freq);
1854}1880}
1855 1881
1856void tWavetable_setPhaseOffset(tWavetable* const cy, float phase)1882void tWaveOsc_setPhaseOffset(tWaveOsc* const cy, float phase)
1857{1883{
1858 _tWavetable* c = *cy;1884 _tWaveOsc* c = *cy;
1859 c->phaseOffset = phase - (int)phase;1885 c->phaseOffset = phase - (int)phase;
1860}1886}
1861 1887
1888//================================================================================================
1889//================================================================================================
1890
1891void tWaveSynth_init(tWaveSynth* const cy, int numVoices, float** tables, int* sizes,
1892 int numTables, float maxFreq, LEAF* const leaf)
1893{
1894 tWaveSynth_initToPool(cy, numVoices, tables, sizes, numTables, maxFreq, &leaf->mempool);
1895}
1896
1897void tWaveSynth_initToPool(tWaveSynth* const cy, int numVoices, float** tables, int* sizes,
1898 int numTables, float maxFreq, tMempool* const mp)
1899{
1900 _tMempool* m = *mp;
1901 _tWaveSynth* c = *cy = (_tWaveSynth*) mpool_alloc(sizeof(_tWaveSynth), m);
1902 c->mempool = m;
1903
1904 c->numTables = 0;
1905 for (int t = 0; t < numTables; ++t)
1906 {
1907 if (sizes[t] > 0) c->numTables++;
1908 }
1909
1910 c->tables = (tWaveTable*) mpool_alloc(sizeof(tWaveTable) * c->numTables, m);
1911 c->oscs = (tWaveOsc**) mpool_alloc(sizeof(tWaveOsc*) * c->numTables, m);
1912
1913 c->numVoices = numVoices;
1914
1915 int i = 0;
1916 for (int t = 0; t < numTables; ++t)
1917 {
1918 if (sizes[t] > 0)
1919 {
1920 tWaveTable_initToPool(&c->tables[i], tables[t], sizes[t], maxFreq, mp);
1921 c->oscs[i] = (tWaveOsc*) mpool_alloc(sizeof(tWaveOsc) * c->numVoices, m);
1922 for (int v = 0; v < c->numVoices; ++v) tWaveOsc_initToPool(&c->oscs[i][v], &c->tables[i], mp);
1923 i++;
1924 }
1925 }
1926
1927 c->g = (float*) mpool_alloc(sizeof(float) * c->numTables, m);
1928 for (int i = 0; i < c->numTables; ++i) c->g[i] = 1.0f;
1929
1930 c->index = 0.0f;
1931 c->maxFreq = maxFreq;
1932}
1933
1934void tWaveSynth_free(tWaveSynth* const cy)
1935{
1936 _tWaveSynth* c = *cy;
1937
1938 for (int i = 0; i < c->numTables; ++i)
1939 {
1940 tWaveTable_free(&c->tables[i]);
1941 for (int v = 0; v < c->numVoices; ++v) tWaveOsc_free(&c->oscs[i][v]);
1942 mpool_free((char*)c->oscs[i], c->mempool);
1943 }
1944 mpool_free((char*)c->g, c->mempool);
1945 mpool_free((char*)c->oscs, c->mempool);
1946 mpool_free((char*)c->tables, c->mempool);
1947 mpool_free((char*)c, c->mempool);
1948}
1949
1950float tWaveSynth_tick(tWaveSynth* const cy)
1951{
1952 _tWaveSynth* c = *cy;
1953
1954 float f = c->index * (c->numTables - 1);
1955
1956 int o1 = (int)f;
1957 int o2 = o1 + 1;
1958 if (c->index >= 1.0f) o2 = o1;
1959 float mix = f - o1;
1960
1961 float s1 = 0.f, s2 = 0.f;
1962 for (int t = 0; t < c->numTables; ++t)
1963 {
1964 float s0 = 0.f;
1965 for (int v = 0; v < c->numVoices; ++v) s0 += tWaveOsc_tick(&c->oscs[t][v]);
1966 if (t == o1) s1 = s0 * c->g[t];
1967 if (t == o2) s2 = s0 * c->g[t];
1968 }
1969
1970 // Ideally should determine correlation to get a good equal power fade between tables
1971 return s1 + (s2 - s1) * mix;
1972}
1973
1974float tWaveSynth_tickVoice(tWaveSynth* const cy, int voice)
1975{
1976 _tWaveSynth* c = *cy;
1977
1978 float f = c->index * (c->numTables - 1);
1979
1980 int o1 = (int)f;
1981 int o2 = o1 + 1;
1982 if (c->index >= 1.0f) o2 = o1;
1983 float mix = f - o1;
1984
1985 float s1 = 0.f, s2 = 0.f;
1986 for (int t = 0; t < c->numTables; ++t)
1987 {
1988 // Should we tick every voice anyway to preserve relative phases?
1989 float s0 = tWaveOsc_tick(&c->oscs[t][voice]);
1990 if (t == o1) s1 = s0 * c->g[t];
1991 if (t == o2) s2 = s0 * c->g[t];
1992 }
1993
1994 // Ideally should determine correlation to get a good equal power fade between tables
1995 return s1 + (s2 - s1) * mix;
1996}
1997
1998void tWaveSynth_setFreq(tWaveSynth* const cy, int voice, float freq)
1999{
2000 _tWaveSynth* c = *cy;
2001 for (int t = 0; t < c->numTables; ++t)
2002 {
2003 tWaveOsc_setFreq(&c->oscs[t][voice], freq);
2004 }
2005}
1862 2006
1863void tCompactWavetable_init(tCompactWavetable* const cy, float* table, int size, float maxFreq, LEAF* const leaf)2007void tWaveSynth_setAntiAliasing(tWaveSynth* const cy, float aa)
1864{2008{
1865 tCompactWavetable_initToPool(cy, table, size, maxFreq, &leaf->mempool);2009 _tWaveSynth* c = *cy;
2010 for (int t = 0; t < c->numTables; ++t)
2011 {
2012 for (int v = 0; v < c->numVoices; ++v)
2013 {
2014 tWaveOsc_setAntiAliasing(&c->oscs[t][v], aa);
2015 }
2016 }
2017}
2018
2019void tWaveSynth_setIndex(tWaveSynth* const cy, float index)
2020{
2021 _tWaveSynth* c = *cy;
2022 c->index = index;
2023}
2024
2025void tWaveSynth_setIndexGain(tWaveSynth* const cy, int i, float gain)
2026{
2027 _tWaveSynth* c = *cy;
2028 if (i >= c->numTables) return;
2029 c->g[i] = gain;
1866}2030}
1867 2031
1868void tCompactWavetable_initToPool(tCompactWavetable* const cy, float* table, int size, float maxFreq, tMempool* const mp)2032void tWaveSynth_setIndexPhase(tWaveSynth* const cy, int i, float phase)
2033{
2034 _tWaveSynth* c = *cy;
2035 if (i >= c->numTables) return;
2036 for (int v = 0; v < c->numVoices; ++v)
2037 {
2038 tWaveOsc_setPhaseOffset(&c->oscs[i][v], phase);
2039 }
2040}
2041
2042//void tWaveSynth_setIndexTable(tWaveSynth* const cy, int i, float* table, int size)
2043//{
2044// _tWaveSynth* c = *cy;
2045// if (i >= c->numTables) return;
2046// if (
2047// tWaveTable_free(&c->tables[i]);
2048// tWaveTable_initToPool(&c->tables[i], table, size, c->maxFreq, &c->mempool);
2049// for (int v = 0; v < c->numVoices; ++v)
2050// {
2051// tWaveOsc_setFreq(&c->oscs[i][v], c->oscs[i][v]->freq);
2052// }
2053//}
2054
2055//=======================================================================================
2056//=======================================================================================
2057
2058void tCompactWaveTable_init(tCompactWaveTable* const cy, float* table, int size, float maxFreq, LEAF* const leaf)
2059{
2060 tCompactWaveTable_initToPool(cy, table, size, maxFreq, &leaf->mempool);
2061}
2062
2063void tCompactWaveTable_initToPool(tCompactWaveTable* const cy, float* table, int size, float maxFreq, tMempool* const mp)
1869{2064{
1870 _tMempool* m = *mp;2065 _tMempool* m = *mp;
1871 _tCompactWavetable* c = *cy = (_tCompactWavetable*) mpool_alloc(sizeof(_tCompactWavetable), m);2066 _tCompactWaveTable* c = *cy = (_tCompactWaveTable*) mpool_alloc(sizeof(_tCompactWaveTable), m);
1872 c->mempool = m;2067 c->mempool = m;
1873 2068
1874 // Determine base frequency2069 // Determine base frequency
@@ -1907,7 +2102,7 @@ void tCompactWavetable_initToPool(tCompactWavetable* const cy, float* table, int · 32 unmodified lines
1907 tOversampler_initToPool(&c->ds, 2, 1, mp);2102 tOversampler_initToPool(&c->ds, 2, 1, mp);
1908 for (int t = 1; t < c->numTables; ++t)2103 for (int t = 1; t < c->numTables; ++t)
1909 {2104 {
1910 // Similar to tWavetable, doing multiple passes here helps, but not sure what number is optimal2105 // Similar to tWaveTable, doing multiple passes here helps, but not sure what number is optimal
1911 for (int p = 0; p < 12; ++p)2106 for (int p = 0; p < 12; ++p)
1912 {2107 {
1913 for (int i = 0; i < c->sizes[t]; ++i)2108 for (int i = 0; i < c->sizes[t]; ++i)
@@ -1920,17 +2115,11 @@ void tCompactWavetable_initToPool(tCompactWavetable* const cy, float* table, int · 6 unmodified lines
1920 }2115 }
1921 tOversampler_free(&c->ds);2116 tOversampler_free(&c->ds);
1922 tButterworth_free(&c->bl);2117 tButterworth_free(&c->bl);
1923
1924 c->inc = 0.0f;
1925 c->phase = 0.0f;
1926 c->aa = 0.5f;
1927
1928 tCompactWavetable_setFreq(cy, 220);
1929}2118}
1930 2119
1931void tCompactWavetable_free(tCompactWavetable* const cy)2120void tCompactWaveTable_free(tCompactWaveTable* const cy)
1932{2121{
1933 _tCompactWavetable* c = *cy;2122 _tCompactWaveTable* c = *cy;
1934 2123
1935 for (int t = 0; t < c->numTables; ++t)2124 for (int t = 0; t < c->numTables; ++t)
1936 {2125 {
@@ -1941,9 +2130,37 @@ void tCompactWavetable_free(tCompactWavetable* const cy) · 4 unmodified lines
1941 mpool_free((char*)c, c->mempool);2130 mpool_free((char*)c, c->mempool);
1942}2131}
1943 2132
1944float tCompactWavetable_tick(tCompactWavetable* const cy)2133//================================================================================================
2134//================================================================================================
2135
2136void tCompactWaveOsc_init(tCompactWaveOsc* const cy, tCompactWaveTable* const table, LEAF* const leaf)
1945{2137{
1946 _tCompactWavetable* c = *cy;2138 tCompactWaveOsc_initToPool(cy, table, &leaf->mempool);
2139}
2140
2141void tCompactWaveOsc_initToPool(tCompactWaveOsc* const cy, tCompactWaveTable* const table, tMempool* const mp)
2142{
2143 _tMempool* m = *mp;
2144 _tCompactWaveOsc* c = *cy = (_tCompactWaveOsc*) mpool_alloc(sizeof(_tCompactWaveOsc), m);
2145 c->mempool = m;
2146
2147 c->inc = 0.0f;
2148 c->phase = 0.0f;
2149 c->phaseOffset = 0.0f;
2150 c->aa = 0.5f;
2151
2152 tCompactWaveOsc_setFreq(cy, 220);
2153}
2154
2155void tCompactWaveOsc_free(tCompactWaveOsc* const cy)
2156{
2157 _tCompactWaveOsc* c = *cy;
2158 mpool_free((char*)c, c->mempool);
2159}
2160
2161float tCompactWaveOsc_tick(tCompactWaveOsc* const cy)
2162{
2163 _tCompactWaveOsc* c = *cy;
1947 2164
1948 float temp;2165 float temp;
1949 int idx;2166 int idx;
@@ -1956,31 +2173,34 @@ float tCompactWavetable_tick(tCompactWavetable* const cy) · 6 unmodified lines
1956 if (c->phase >= 1.0f) c->phase -= 1.0f;2173 if (c->phase >= 1.0f) c->phase -= 1.0f;
1957 if (c->phase < 0.0f) c->phase += 1.0f;2174 if (c->phase < 0.0f) c->phase += 1.0f;
1958 2175
2176 int* sizes = c->table->sizes;
2177 float** tables = c->table->tables;
2178
1959 // Wavetable synthesis2179 // Wavetable synthesis
1960 temp = c->sizes[c->oct] * c->phase;2180 temp = sizes[c->oct] * (c->phase + c->phaseOffset);
1961 idx = (int)temp;2181 idx = (int)temp;
1962 frac = temp - (float)idx;2182 frac = temp - (float)idx;
1963 samp0 = c->tables[c->oct][idx];2183 samp0 = tables[c->oct][idx];
1964 if (++idx >= c->sizes[c->oct]) idx = 0;2184 if (++idx >= sizes[c->oct]) idx = 0;
1965 samp1 = c->tables[c->oct][idx];2185 samp1 = tables[c->oct][idx];
1966 2186
1967 float oct0 = (samp0 + (samp1 - samp0) * frac);2187 float oct0 = (samp0 + (samp1 - samp0) * frac);
1968 2188
1969 temp = c->sizes[c->oct+1] * c->phase;2189 temp = sizes[c->oct+1] * c->phase;
1970 idx = (int)temp;2190 idx = (int)temp;
1971 frac = temp - (float)idx;2191 frac = temp - (float)idx;
1972 samp0 = c->tables[c->oct+1][idx];2192 samp0 = tables[c->oct+1][idx];
1973 if (++idx >= c->sizes[c->oct+1]) idx = 0;2193 if (++idx >= sizes[c->oct+1]) idx = 0;
1974 samp1 = c->tables[c->oct+1][idx];2194 samp1 = tables[c->oct+1][idx];
1975 2195
1976 float oct1 = (samp0 + (samp1 - samp0) * frac);2196 float oct1 = (samp0 + (samp1 - samp0) * frac);
1977 2197
1978 return oct0 + (oct1 - oct0) * c->w;2198 return oct0 + (oct1 - oct0) * c->w;
1979}2199}
1980 2200
1981void tCompactWavetable_setFreq(tCompactWavetable* const cy, float freq)2201void tCompactWaveOsc_setFreq(tCompactWaveOsc* const cy, float freq)
1982{2202{
1983 _tCompactWavetable* c = *cy;2203 _tCompactWaveOsc* c = *cy;
1984 2204
1985 LEAF* leaf = c->mempool->leaf;2205 LEAF* leaf = c->mempool->leaf;
1986 2206
@@ -1990,132 +2210,191 @@ void tCompactWavetable_setFreq(tCompactWavetable* const cy, float freq) · 3 unmodified lines
1990 c->inc -= (int)c->inc;2210 c->inc -= (int)c->inc;
1991 2211
1992 // abs for negative frequencies2212 // abs for negative frequencies
1993 c->w = fabsf(c->freq * c->invBaseFreq);2213 c->w = fabsf(c->freq * c->table->invBaseFreq);
1994 2214
1995 // Probably ok to use a log2 approx here; won't effect tuning at all, just crossfading between octave tables2215 // Probably ok to use a log2 approx here; won't effect tuning at all, just crossfading between octave tables
1996 c->w = log2f_approx(c->w) + c->aa;//+ LEAF_SQRT2 - 1.0f; adding an offset here will shift our table selection upward, reducing aliasing but lower high freq fidelity. +1.0f should remove all aliasing2216 c->w = log2f_approx(c->w) + c->aa;//+ LEAF_SQRT2 - 1.0f; adding an offset here will shift our table selection upward, reducing aliasing but lower high freq fidelity. +1.0f should remove all aliasing
1997 if (c->w < 0.0f) c->w = 0.0f; // If c->w is < 0.0f, then freq is less than our base freq2217 if (c->w < 0.0f) c->w = 0.0f; // If c->w is < 0.0f, then freq is less than our base freq
1998 c->oct = (int)c->w;2218 c->oct = (int)c->w;
1999 c->w -= c->oct;2219 c->w -= c->oct;
2000 if (c->oct >= c->numTables - 1) c->oct = c->numTables - 2;2220 if (c->oct >= c->table->numTables - 1) c->oct = c->table->numTables - 2;
2001}2221}
2002 2222
2003void tCompactWavetable_setAntiAliasing(tCompactWavetable* const cy, float aa)2223void tCompactWaveOsc_setAntiAliasing(tCompactWaveOsc* const cy, float aa)
2004{2224{
2005 _tCompactWavetable* c = *cy;2225 _tCompactWaveOsc* c = *cy;
2006
2007 c->aa = aa;2226 c->aa = aa;
2008 tCompactWavetable_setFreq(cy, c->freq);2227 tCompactWaveOsc_setFreq(cy, c->freq);
2228}
2229
2230void tCompactWaveOsc_setPhaseOffset(tCompactWaveOsc* const cy, float phase)
2231{
2232 _tCompactWaveOsc* c = *cy;
2233 c->phaseOffset = phase - (int)phase;
2009}2234}
2010 2235
2011//================================================================================================2236//================================================================================================
2012//================================================================================================2237//================================================================================================
2013 2238
2014void tWaveset_init(tWaveset* const cy, float** tables, int n, int* sizes, float maxFreq, LEAF* const leaf)2239void tCompactWaveSynth_init(tCompactWaveSynth* const cy, int numVoices, float** tables, int* sizes,
2240 int numTables, float maxFreq, LEAF* const leaf)
2015{2241{
2016 tWaveset_initToPool(cy, tables, n, sizes, maxFreq, &leaf->mempool);2242 tCompactWaveSynth_initToPool(cy, numVoices, tables, sizes, numTables, maxFreq, &leaf->mempool);
2017}2243}
2018 2244
2019void tWaveset_initToPool(tWaveset* const cy, float** tables, int n, int* sizes, float maxFreq, tMempool* const mp)2245void tCompactWaveSynth_initToPool(tCompactWaveSynth* const cy, int numVoices, float** tables, int* sizes,
2246 int numTables, float maxFreq, tMempool* const mp)
2020{2247{
2021 _tMempool* m = *mp;2248 _tMempool* m = *mp;
2022 _tWaveset* c = *cy = (_tWaveset*) mpool_alloc(sizeof(_tWaveset), m);2249 _tCompactWaveSynth* c = *cy = (_tCompactWaveSynth*) mpool_alloc(sizeof(_tCompactWaveSynth), m);
2023 c->mempool = m;2250 c->mempool = m;
2024 2251
2025 c->n = 0;2252 c->numTables = 0;
2026 for (int t = 0; t < n; ++t)2253 for (int t = 0; t < numTables; ++t)
2027 {2254 {
2028 if (sizes[t] > 0) c->n++;2255 if (sizes[t] > 0) c->numTables++;
2029 }2256 }
2030 2257
2031 c->wt = (tWavetable*) mpool_alloc(sizeof(tWavetable) * c->n, m);2258 c->tables = (tCompactWaveTable*) mpool_alloc(sizeof(tCompactWaveTable) * c->numTables, m);
2259 c->oscs = (tCompactWaveOsc**) mpool_alloc(sizeof(tCompactWaveOsc*) * c->numTables, m);
2260
2261 c->numVoices = numVoices;
2032 2262
2033 int i = 0;2263 int i = 0;
2034 for (int t = 0; t < n; ++t)2264 for (int t = 0; t < numTables; ++t)
2035 {2265 {
2036 if (sizes[t] > 0)2266 if (sizes[t] > 0)
2037 {2267 {
2038 tWavetable_initToPool(&c->wt[i], tables[t], sizes[t], maxFreq, mp);2268 tCompactWaveTable_initToPool(&c->tables[i], tables[t], sizes[t], maxFreq, mp);
2269 c->oscs[i] = (tCompactWaveOsc*) mpool_alloc(sizeof(tCompactWaveOsc) * c->numVoices, m);
2270 for (int v = 0; v < c->numVoices; ++v) tCompactWaveOsc_initToPool(&c->oscs[i][v], &c->tables[i], mp);
2039 i++;2271 i++;
2040 }2272 }
2041 }2273 }
2042 2274
2043 c->g = (float*) mpool_alloc(sizeof(tWavetable) * c->n, m);2275 c->g = (float*) mpool_alloc(sizeof(float) * c->numTables, m);
2044 for (int i = 0; i < c->n; ++i) c->g[i] = 1.0f;2276 for (int i = 0; i < c->numTables; ++i) c->g[i] = 1.0f;
2045 2277
2046 c->index = 0.0f;2278 c->index = 0.0f;
2279 c->maxFreq = maxFreq;
2047}2280}
2048 2281
2049void tWaveset_free(tWaveset* const cy)2282void tCompactWaveSynth_free(tCompactWaveSynth* const cy)
2050{2283{
2051 _tWaveset* c = *cy;2284 _tCompactWaveSynth* c = *cy;
2052 2285
2053 for (int i = 0; i < c->n; ++i)2286 for (int i = 0; i < c->numTables; ++i)
2054 {2287 {
2055 tWavetable_free(&c->wt[i]);2288 tCompactWaveTable_free(&c->tables[i]);
2289 for (int v = 0; v < c->numVoices; ++v) tCompactWaveOsc_free(&c->oscs[i][v]);
2290 mpool_free((char*)c->oscs[i], c->mempool);
2056 }2291 }
2057 mpool_free((char*)c->g, c->mempool);2292 mpool_free((char*)c->g, c->mempool);
2058 mpool_free((char*)c->wt, c->mempool);2293 mpool_free((char*)c->oscs, c->mempool);
2294 mpool_free((char*)c->tables, c->mempool);
2059 mpool_free((char*)c, c->mempool);2295 mpool_free((char*)c, c->mempool);
2060}2296}
2061 2297
2062float tWaveset_tick(tWaveset* const cy)2298float tCompactWaveSynth_tick(tCompactWaveSynth* const cy)
2299{
2300 _tCompactWaveSynth* c = *cy;
2301
2302 float f = c->index * (c->numTables - 1);
2303
2304 int o1 = (int)f;
2305 int o2 = o1 + 1;
2306 if (c->index >= 1.0f) o2 = o1;
2307 float mix = f - o1;
2308
2309 float s1 = 0.f, s2 = 0.f;
2310 for (int t = 0; t < c->numTables; ++t)
2311 {
2312 float s0 = 0.f;
2313 for (int v = 0; v < c->numVoices; ++v) s0 += tCompactWaveOsc_tick(&c->oscs[t][v]);
2314 if (t == o1) s1 = s0 * c->g[t];
2315 if (t == o2) s2 = s0 * c->g[t];
2316 }
2317
2318 // Ideally should determine correlation to get a good equal power fade between tables
2319 return s1 + (s2 - s1) * mix;
2320}
2321
2322float tCompactWaveSynth_tickVoice(tCompactWaveSynth* const cy, int voice)
2063{2323{
2064 _tWaveset* c = *cy;2324 _tCompactWaveSynth* c = *cy;
2065 2325
2066 float f = c->index * (c->n - 1);2326 float f = c->index * (c->numTables - 1);
2067 2327
2068 int o1 = (int)f;2328 int o1 = (int)f;
2069 int o2 = o1 + 1;2329 int o2 = o1 + 1;
2070 if (c->index >= 1.0f) o2 = o1;2330 if (c->index >= 1.0f) o2 = o1;
2071 float mix = f - o1;2331 float mix = f - o1;
2072 2332
2073 float s0 = 0.f, s1 = 0.f, s2 = 0.f;2333 float s1 = 0.f, s2 = 0.f;
2074 for (int i = 0; i < c->n; ++i)2334 for (int t = 0; t < c->numTables; ++t)
2075 {2335 {
2076 s0 = tWavetable_tick(&c->wt[i]) * c->g[i];2336 // Should we tick every voice anyway to preserve relative phases?
2077 if (i == o1) s1 = s0;2337 float s0 = tCompactWaveOsc_tick(&c->oscs[t][voice]);
2078 if (i == o2) s2 = s0;2338 if (t == o1) s1 = s0 * c->g[t];
2339 if (t == o2) s2 = s0 * c->g[t];
2079 }2340 }
2080 2341
2081 // Ideally should determine correlation to get a good equal power fade between tables2342 // Ideally should determine correlation to get a good equal power fade between tables
2082 return s1 + (s2 - s1) * mix;2343 return s1 + (s2 - s1) * mix;
2083}2344}
2084 2345
2085void tWaveset_setFreq(tWaveset* const cy, float freq)2346void tCompactWaveSynth_setFreq(tCompactWaveSynth* const cy, int voice, float freq)
2086{2347{
2087 _tWaveset* c = *cy;2348 _tCompactWaveSynth* c = *cy;
2088 for (int i = 0; i < c->n; ++i)2349 for (int t = 0; t < c->numTables; ++t)
2089 {2350 {
2090 tWavetable_setFreq(&c->wt[i], freq);2351 tCompactWaveOsc_setFreq(&c->oscs[t][voice], freq);
2091 }2352 }
2092}2353}
2093 2354
2094void tWaveset_setAntiAliasing(tWaveset* const cy, float aa)2355void tCompactWaveSynth_setAntiAliasing(tCompactWaveSynth* const cy, float aa)
2095{2356{
2096 _tWaveset* c = *cy;2357 _tCompactWaveSynth* c = *cy;
2097 for (int i = 0; i < c->n; ++i)2358 for (int t = 0; t < c->numTables; ++t)
2098 {2359 {
2099 tWavetable_setAntiAliasing(&c->wt[i], aa);2360 for (int v = 0; v < c->numVoices; ++v)
2361 {
2362 tCompactWaveOsc_setAntiAliasing(&c->oscs[t][v], aa);
2363 }
2100 }2364 }
2101}2365}
2102 2366
2103void tWaveset_setIndex(tWaveset* const cy, float index)2367void tCompactWaveSynth_setIndex(tCompactWaveSynth* const cy, float index)
2104{2368{
2105 _tWaveset* c = *cy;2369 _tCompactWaveSynth* c = *cy;
2106 c->index = index;2370 c->index = index;
2107}2371}
2108 2372
2109void tWaveset_setIndexGain(tWaveset* const cy, int i, float gain)2373void tCompactWaveSynth_setIndexGain(tCompactWaveSynth* const cy, int i, float gain)
2110{2374{
2111 _tWaveset* c = *cy;2375 _tCompactWaveSynth* c = *cy;
2112 if (i >= c->n) return;2376 if (i >= c->numTables) return;
2113 c->g[i] = gain;2377 c->g[i] = gain;
2114}2378}
2115 2379
2116void tWaveset_setIndexPhase(tWaveset* const cy, int i, float phase)2380void tCompactWaveSynth_setIndexPhase(tCompactWaveSynth* const cy, int i, float phase)
2117{2381{
2118 _tWaveset* c = *cy;2382 _tCompactWaveSynth* c = *cy;
2119 if (i >= c->n) return;2383 if (i >= c->numTables) return;
2120 tWavetable_setPhaseOffset(&c->wt[i], phase);2384 for (int v = 0; v < c->numVoices; ++v)
2385 {
2386 tCompactWaveOsc_setPhaseOffset(&c->oscs[i][v], phase);
2387 }
2121}2388}
2389//
2390//void tCompactWaveSynth_setIndexTable(tCompactWaveSynth* const cy, int i, float* table, int size)
2391//{
2392// _tCompactWaveSynth* c = *cy;
2393// if (i >= c->numTables) return;
2394// tCompactWaveTable_free(&c->tables[i]);
2395// tCompactWaveTable_initToPool(&c->tables[i], table, size, c->maxFreq, &c->mempool);
2396// for (int v = 0; v < c->numVoices; ++v)
2397// {
2398// tCompactWaveOsc_setFreq(&c->oscs[i][v], c->oscs[i][v]->freq);
2399// }
2400//}
leaf/leaf-config.h+1−1
@@ -18,7 +18,7 @@ · 17 unmodified lines
18 18
19//==============================================================================19//==============================================================================
20 20
21//! Include FIR tables required to use tOversampler and tCompactWavetable which uses tOversampler. 21//! Include FIR tables required to use tOversampler and tCompactWaveTable which uses tOversampler.
22#define LEAF_INCLUDE_OVERSAMPLER_TABLES 122#define LEAF_INCLUDE_OVERSAMPLER_TABLES 1
23 23
24// Unused24// Unused

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t