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
3131 tNoise noise;
3232 tButterworth bw;
3333
34−tWavetable wt;
35−tCompactWavetable cwt;
36−tWaveset ws;
34+tWaveTable wt;
35+tCompactWaveTable cwt;
36+tWaveSynth ws;
3737
3838 tBuffer samp;
3939 tMBSampler sampler;
4040
4141 const int numWavetables = 1;
42−tWavetable wavetables[numWavetables];
42+tWaveTable wavetables[numWavetables];
4343
4444 float gain;
4545 float dtime;
@@ -63,8 +63,8 @@ void LEAFTest_init (float sampleRate, int blockSize) · 17 unmodified lines
6363 {
6464 LEAF_init(&leaf, sampleRate, blockSize, memory, MSIZE, &getRandomFloat);
6565
66−// tWavetable_init(&wt, __leaf_table_sawtooth[0], 2048, 10000.f, &leaf);
67−// tCompactWavetable_init(&cwt, __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);
6868
6969 tMBTriangle_init(&btri, &leaf);
7070 tMBPulse_init(&bpulse, &leaf);
@@ -77,15 +77,14 @@ void LEAFTest_init (float sampleRate, int blockSize) · 6 unmodified lines
7777 tPhasor_setFreq(&phasor, 220.f);
7878
7979 float* set[4];
80− set[0] = __leaf_table_sinewave;
81− set[1] = __leaf_table_triangle[0];
82− set[2] = __leaf_table_squarewave[0];
83− set[3] = __leaf_table_sawtooth[0];
80+ set[0] = (float*)__leaf_table_sinewave;
81+ set[1] = (float*)__leaf_table_triangle[0];
82+ set[2] = (float*)__leaf_table_squarewave[0];
83+ set[3] = (float*)__leaf_table_sawtooth[0];
8484 int sizes[4];
8585 for (int i = 0; i < 4; i++) sizes[i] = 2048;
8686
87− tWaveset_init(&ws, set, 4, sizes, 10000.f, &leaf);
88− tWaveset_setIndexGain(&ws, 0, -1.0f);
87+ tWaveSynth_init(&ws, 1, set, sizes, 4, 10000.f, &leaf);
8988
9089 lastLoadedAudioSize = 0;
9190 loadedAudio.clear();
@@ -105,7 +104,7 @@ float LEAFTest_tick (float input) · 13 unmodified lines
105104 float out = 0.0f;
106105 for (int i = 0; i < fmin(loadedAudio.size(), numWavetables); ++i)
107106 {
108− out += tWavetable_tick(&wavetables[i]);
107+// out += tWaveTable_tick(&wavetables[i]);
109108 }
110109 return out;
111110 }
@@ -118,14 +117,14 @@ void LEAFTest_block (void) · 6 unmodified lines
118117 tMBTriangle_setFreq(&btri, val * 440.f);
119118 tMBPulse_setFreq(&bpulse, val * 160000.f - 80000.0f);
120119 tMBSaw_setFreq(&bsaw, val * 10000.f);
121−// tWavetable_setFreq(&wt, val * 160000.f - 80000.0f);
122−// tCompactWavetable_setFreq(&cwt, val * 10000.);
123− tWaveset_setFreq(&ws, val * 10000.f);
120+// tWaveTable_setFreq(&wt, val * 160000.f - 80000.0f);
121+// tCompactWaveTable_setFreq(&cwt, val * 10000.);
122+ tWaveSynth_setFreq(&ws, 0, val * 10000.f);
124123 // tRetune_tuneVoice(&retune, 0, val * 3.0f + 0.5f);
125124 // tSimpleRetune_tuneVoice(&sretune, 0, 300);
126125
127126 val = getSliderValue("slider2");
128− tWaveset_setIndex(&ws, val);
127+ tWaveSynth_setIndex(&ws, val);
129128 // tRetune_setPitchFactor(&retune, val * 3.0f + 0.5f, 1);
130129
131130 val = getSliderValue("slider3");
@@ -134,12 +133,12 @@ void LEAFTest_block (void) · 2 unmodified lines
134133 if (lastLoadedAudioSize < loadedAudio.size())
135134 {
136135 int i = (loadedAudio.size() - 1) % numWavetables;
137− 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);
136+ if (loadedAudio.size() - 1 >= numWavetables) tWaveTable_free(&wavetables[i]);
137+ tWaveTable_init(&wavetables[i], (float*)loadedAudio[loadedAudio.size() - 1].getReadPointer(0), loadedAudio[loadedAudio.size() - 1].getNumSamples(), 20000, &leaf);
139138
140139 lastLoadedAudioSize = loadedAudio.size();
141140 }
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);
143142 }
144143
145144 void LEAFTest_controllerInput (int cnum, float cval)
leaf/Inc/leaf-oscillators.h+248−105
@@ -922,44 +922,34 @@ extern "C" { · 921 unmodified lines
922922 //==============================================================================
923923
924924 /*!
925− @defgroup twavetable tWavetable
925+ @defgroup twavetable tWaveTable
926926 @ingroup oscillators
927− @brief Anti-aliased wavetable oscillator.
927+ @brief Anti-aliased wavetable generator.
928928 @{
929929
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.
932− @param osc A pointer to the tWavetable to initialize.
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.
932+ @param osc A pointer to the tWaveTable to initialize.
933933 @param table A pointer to the wavetable data.
934934 @param size The number of samples in the wavetable.
935935 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.
936936 @param leaf A pointer to the leaf instance.
937937
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.
940− @param osc A pointer to the tWavetable to initialize.
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.
940+ @param osc A pointer to the tWaveTable to initialize.
941941 @param table A pointer to the wavetable data.
942942 @param size The number of samples in the wave table.
943943 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.
944944 @param mempool A pointer to the tMempool to use.
945945
946− @fn void tWavetable_free (tWavetable* const osc)
947− @brief Free a tWavetable from its mempool.
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.
946+ @fn void tWaveTable_free (tWaveTable* const osc)
947+ @brief Free a tWaveTable from its mempool.
948+ @param osc A pointer to the tWaveTable to free.
959949
960950 @} */
961951
962− typedef struct _tWavetable
952+ typedef struct _tWaveTable
963953 {
964954 tMempool mempool;
965955
@@ -967,6 +957,41 @@ extern "C" { · 1 unmodified line
967957 int size;
968958 int numTables;
969959 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;
970995 float inc, freq;
971996 float phase;
972997 float phaseOffset;
@@ -974,62 +999,126 @@ extern "C" { · 1 unmodified line
974999 int oct;
9751000 float w;
9761001 float aa;
977−
978− tButterworth bl;
979− } _tWavetable;
1002+ } _tWaveOsc;
9801003
981− typedef _tWavetable* tWavetable;
1004+ typedef _tWaveOsc* tWaveOsc;
9821005
983− void tWavetable_init(tWavetable* const osc, float* table, int size, float maxFreq, LEAF* const leaf);
984− void tWavetable_initToPool(tWavetable* const osc, float* table, int size, float maxFreq, tMempool* const mempool);
985− void tWavetable_free(tWavetable* const osc);
1006+ void tWaveOsc_init(tWaveOsc* const osc, tWaveTable* const table, LEAF* const leaf);
1007+ void tWaveOsc_initToPool(tWaveOsc* const osc, tWaveTable* const table, tMempool* const mempool);
1008+ void tWaveOsc_free(tWaveOsc* const osc);
9861009
987− float tWavetable_tick(tWavetable* const osc);
988− void tWavetable_setFreq(tWavetable* const osc, float freq);
989− void tWavetable_setAntiAliasing(tWavetable* const osc, float aa);
990− void tWavetable_setPhaseOffset(tWavetable* const osc, float phase);
1010+ float tWaveOsc_tick(tWaveOsc* const osc);
1011+ void tWaveOsc_setFreq(tWaveOsc* const osc, float freq);
1012+ void tWaveOsc_setAntiAliasing(tWaveOsc* const osc, float aa);
1013+ void tWaveOsc_setPhaseOffset(tWaveOsc* const osc, float phase);
9911014
9921015 //==============================================================================
9931016
9941017 /*!
995− @defgroup tcompactwavetable tCompactWavetable
1018+ @defgroup twaveset tWaveSynth
9961019 @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.
9981021 @{
9991022
1000− @fn void tCompactWavetable_init (tCompactWavetable* const osc, float* table, int size, float maxFreq, LEAF* const leaf)
1001− @brief Initialize a tCompactWavetable to the default mempool of a LEAF instance.
1002− @param osc A pointer to the tCompactWavetable to initialize.
1003− @param table A pointer to the wavetable data.
1004− @param size The number of samples in the wavetable.
1023+ @fn void tWaveSynth_init(tWaveSynth* const osc, const float** tables, int n, int size, float maxFreq, LEAF* const leaf)
1024+ @brief Initialize a tWaveSynth to the default mempool of a LEAF instance.
1025+ @param osc A pointer to the tWaveSynth to initialize.
1026+ @param tables An array of pointers to wavetable data.
1027+ @param n The number of wavetables.
1028+ @param size The number of samples in each of the wavetables.
10051029 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.
10061030 @param leaf A pointer to the leaf instance.
10071031
1008− @fn void tCompactWavetable_initToPool (tCompactWavetable* const osc, float* table, int size, float maxFreq, tMempool* const mempool)
1009− @brief Initialize a tCompactWavetable to a specified mempool.
1010− @param osc A pointer to the tCompactWavetable to initialize.
1011− @param table A pointer to the wavetable data.
1012− @param size The number of samples in the wave table.
1032+ @fn void tWaveSynth_initToPool(tWaveSynth* const osc, const float** tables, int n, int size, float maxFreq, tMempool* const mempool)
1033+ @brief Initialize a tWaveSynth to a specified mempool.
1034+ @param osc A pointer to the tWaveTable to initialize.
1035+ @param tables An array of pointers to wavetable data.
1036+ @param n The number of wavetables.
1037+ @param size The number of samples in each of the wavetables.
10131038 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.
10141039 @param mempool A pointer to the tMempool to use.
10151040
1016− @fn void tCompactWavetable_free (tCompactWavetable* const osc)
1017− @brief Free a tCompactWavetable from its mempool.
1018− @param osc A pointer to the tCompactWavetable to free.
1041+ @fn void tWaveSynth_free (tWaveSynth* const osc)
1042+ @brief Free a tWaveSynth from its mempool.
1043+ @param osc A pointer to the tWaveSynth to free.
10191044
1020− @fn float tCompactWavetable_tick (tCompactWavetable* const osc)
1021− @brief Tick a tCompactWavetable oscillator.
1022− @param osc A pointer to the relevant tCompactWavetable.
1045+ @fn float tWaveSynth_tick (tWaveSynth* const osc)
1046+ @brief Tick a tWaveSynth oscillator.
1047+ @param osc A pointer to the relevant tWaveSynth.
10231048 @return The ticked sample as a float from -1 to 1.
10241049
1025− @fn void tCompactWavetable_setFreq (tCompactWavetable* const osc, float freq)
1026− @brief Set the frequency of a tCompactWavetable oscillator.
1027− @param osc A pointer to the relevant tCompactWavetable.
1050+ @fn void tWaveSynth_setFreq (tWaveSynth* const osc, float freq)
1051+ @brief Set the frequency of a tWaveSynth oscillator.
1052+ @param osc A pointer to the relevant tWaveSynth.
10281053 @param freq The frequency to set the oscillator to.
10291054
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+
10301119 @} */
10311120
1032− typedef struct _tCompactWavetable
1121+ typedef struct _tCompactWaveTable
10331122 {
10341123 tMempool mempool;
10351124
@@ -1037,99 +1126,153 @@ extern "C" { · 1 unmodified line
10371126 int numTables;
10381127 int* sizes;
10391128 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;
10401182 float inc, freq;
10411183 float phase;
1042−
1184+ float phaseOffset;
10431185 int oct;
10441186 float w;
10451187 float aa;
1046−
1047− tButterworth bl;
1048−
1049− float dsBuffer[2];
1050− tOversampler ds;
1051− } _tCompactWavetable;
1188+ } _tCompactWaveOsc;
10521189
1053− typedef _tCompactWavetable* tCompactWavetable;
1190+ typedef _tCompactWaveOsc* tCompactWaveOsc;
10541191
1055− void tCompactWavetable_init(tCompactWavetable* const osc, float* table, int size, float maxFreq, LEAF* const leaf);
1056− void tCompactWavetable_initToPool(tCompactWavetable* const osc, float* table, int size, float maxFreq, tMempool* const mempool);
1057− void tCompactWavetable_free(tCompactWavetable* const osc);
1192+ void tCompactWaveOsc_init(tCompactWaveOsc* const osc, tCompactWaveTable* const table, LEAF* const leaf);
1193+ void tCompactWaveOsc_initToPool(tCompactWaveOsc* const osc, tCompactWaveTable* const table, tMempool* const mempool);
1194+ void tCompactWaveOsc_free(tCompactWaveOsc* const osc);
10581195
1059− float tCompactWavetable_tick(tCompactWavetable* const osc);
1060− void tCompactWavetable_setFreq(tCompactWavetable* const osc, float freq);
1061− void tCompactWavetable_setAntiAliasing(tCompactWavetable* const osc, float aa);
1196+ float tCompactWaveOsc_tick(tCompactWaveOsc* const osc);
1197+ void tCompactWaveOsc_setFreq(tCompactWaveOsc* const osc, float freq);
1198+ void tCompactWaveOsc_setAntiAliasing(tCompactWaveOsc* const osc, float aa);
1199+ void tCompactWaveOsc_setPhaseOffset(tCompactWaveOsc* const osc, float phase);
10621200
10631201 //==============================================================================
10641202
10651203 /*!
1066− @defgroup twaveset tWaveset
1204+ @defgroup tCompactWaveset tCompactWaveSynth
10671205 @ingroup oscillators
10681206 @brief Set of anti-aliased wavetable oscillators that can be faded between.
10691207 @{
10701208
1071− @fn void tWaveset_init(tWaveset* 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.
1073− @param osc A pointer to the tWaveset to initialize.
1209+ @fn void tCompactWaveSynth_init(tWaveSynth* const osc, const float** tables, int n, int size, float maxFreq, LEAF* const leaf)
1210+ @brief Initialize a tCompactWaveSynth to the default mempool of a LEAF instance.
1211+ @param osc A pointer to the tCompactWaveSynth to initialize.
10741212 @param tables An array of pointers to wavetable data.
10751213 @param n The number of wavetables.
10761214 @param size The number of samples in each of the wavetables.
10771215 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.
10781216 @param leaf A pointer to the leaf instance.
10791217
1080− @fn void tWaveset_initToPool(tWaveset* const osc, const float** tables, int n, int size, float maxFreq, tMempool* const mempool)
1081− @brief Initialize a tWaveset to a specified mempool.
1082− @param osc A pointer to the tWavetable to initialize.
1218+ @fn void tCompactWaveSynth_initToPool(tWaveSynth* const osc, const float** tables, int n, int size, float maxFreq, tMempool* const mempool)
1219+ @brief Initialize a tCompactWaveSynth to a specified mempool.
1220+ @param osc A pointer to the tCompactWaveTable to initialize.
10831221 @param tables An array of pointers to wavetable data.
10841222 @param n The number of wavetables.
10851223 @param size The number of samples in each of the wavetables.
10861224 @param maxFreq The maximum expected frequency of the oscillator. The higher this is, the more memory will be needed.
10871225 @param mempool A pointer to the tMempool to use.
10881226
1089− @fn void tWaveset_free (tWaveset* const osc)
1090− @brief Free a tWaveset from its mempool.
1091− @param osc A pointer to the tWaveset to free.
1227+ @fn void tCompactWaveSynth_free (tWaveSynth* const osc)
1228+ @brief Free a tCompactWaveSynth from its mempool.
1229+ @param osc A pointer to the tCompactWaveSynth to free.
10921230
1093− @fn float tWaveset_tick (tWaveset* const osc)
1094− @brief Tick a tWaveset oscillator.
1095− @param osc A pointer to the relevant tWaveset.
1231+ @fn float tCompactWaveSynth_tick (tWaveSynth* const osc)
1232+ @brief Tick a tCompactWaveSynth oscillator.
1233+ @param osc A pointer to the relevant tCompactWaveSynth.
10961234 @return The ticked sample as a float from -1 to 1.
10971235
1098− @fn void tWaveset_setFreq (tWaveset* const osc, float freq)
1099− @brief Set the frequency of a tWaveset oscillator.
1100− @param osc A pointer to the relevant tWaveset.
1236+ @fn void tCompactWaveSynth_setFreq (tWaveSynth* const osc, float freq)
1237+ @brief Set the frequency of a tCompactWaveSynth oscillator.
1238+ @param osc A pointer to the relevant tCompactWaveSynth.
11011239 @param freq The frequency to set the oscillator to.
11021240
1103− @fn void tWaveset_setIndex(tWaveset* const osc, float index)
1241+ @fn void tCompactWaveSynth_setIndex(tWaveSynth* const osc, float index)
11041242 @brief Set the output index of the wavetable set.
11051243 @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.
11061244
11071245 @} */
11081246
1109− typedef struct _tWaveset
1247+ typedef struct _tCompactWaveSynth
11101248 {
11111249 tMempool mempool;
11121250
1113− tWavetable* wt;
1114− int n;
1251+ tCompactWaveTable* tables;
1252+ tCompactWaveOsc** oscs;
1253+ int numTables;
1254+ int numVoices;
11151255 float* g;
1116− float* p;
11171256 float index;
1118− } _tWaveset;
1119−
1120− typedef _tWaveset* tWaveset;
1121−
1122− void tWaveset_init(tWaveset* const osc, float** tables, int n, int* sizes, float maxFreq, LEAF* const leaf);
1123− void tWaveset_initToPool(tWaveset* const osc, float** tables, int n, int* sizes, float maxFreq, tMempool* const mempool);
1124− void tWaveset_free(tWaveset* const osc);
1125−
1126− float tWaveset_tick(tWaveset* const osc);
1127− void tWaveset_setFreq(tWaveset* const osc, float freq);
1128− void tWaveset_setAntiAliasing(tWaveset* const osc, float aa);
1129− void tWaveset_setIndex(tWaveset* const osc, float index);
1130− void tWaveset_setIndexGain(tWaveset* const osc, int i, float gain);
1131− void tWaveset_setIndexPhase(tWaveset* const osc, int i, float phase);
1132−
1257+ float maxFreq;
1258+ } _tCompactWaveSynth;
1259+
1260+ typedef _tCompactWaveSynth* tCompactWaveSynth;
1261+
1262+ void tCompactWaveSynth_init(tCompactWaveSynth* const osc, int numVoices, float** tables, int* sizes,
1263+ int numTables, float maxFreq, LEAF* const leaf);
1264+ void tCompactWaveSynth_initToPool(tCompactWaveSynth* const osc, int numVoices, float** tables, int* sizes,
1265+ int numTables, float maxFreq, tMempool* const mempool);
1266+ void tCompactWaveSynth_free(tCompactWaveSynth* const osc);
1267+
1268+ float tCompactWaveSynth_tick(tCompactWaveSynth* const osc);
1269+ float tCompactWaveSynth_tickVoice(tCompactWaveSynth* const cy, int voice);
1270+ void tCompactWaveSynth_setFreq(tCompactWaveSynth* const osc, int voice, float freq);
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);
11331276
11341277 #ifdef __cplusplus
11351278 }
leaf/Src/leaf-oscillators.c+383−104
@@ -1704,15 +1704,15 @@ void tTableSampleRateChanged(tTable* const cy) · 1703 unmodified lines
17041704 c->inc -= (int)c->inc;
17051705 }
17061706
1707−void tWavetable_init(tWavetable* const cy, float* table, int size, float maxFreq, LEAF* const leaf)
1707+void tWaveTable_init(tWaveTable* const cy, float* table, int size, float maxFreq, LEAF* const leaf)
17081708 {
1709− tWavetable_initToPool(cy, table, size, maxFreq, &leaf->mempool);
1709+ tWaveTable_initToPool(cy, table, size, maxFreq, &leaf->mempool);
17101710 }
17111711
1712−void tWavetable_initToPool(tWavetable* const cy, float* table, int size, float maxFreq, tMempool* const mp)
1712+void tWaveTable_initToPool(tWaveTable* const cy, float* table, int size, float maxFreq, tMempool* const mp)
17131713 {
17141714 _tMempool* m = *mp;
1715− _tWavetable* c = *cy = (_tWavetable*) mpool_alloc(sizeof(_tWavetable), m);
1715+ _tWaveTable* c = *cy = (_tWaveTable*) mpool_alloc(sizeof(_tWaveTable), m);
17161716 c->mempool = m;
17171717
17181718 // Determine base frequency
@@ -1764,18 +1764,11 @@ void tWavetable_initToPool(tWavetable* const cy, float* table, int size, float m · 45 unmodified lines
17641764 f *= 0.5f; //halve the cutoff for next pass
17651765 }
17661766 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);
17741767 }
17751768
1776−void tWavetable_free(tWavetable* const cy)
1769+void tWaveTable_free(tWaveTable* const cy)
17771770 {
1778− _tWavetable* c = *cy;
1771+ _tWaveTable* c = *cy;
17791772
17801773 for (int t = 0; t < c->numTables; ++t)
17811774 {
@@ -1785,9 +1778,39 @@ void tWavetable_free(tWavetable* const cy) · 3 unmodified lines
17851778 mpool_free((char*)c, c->mempool);
17861779 }
17871780
1788−float tWavetable_tick(tWavetable* const cy)
1781+//=======================================================================================
1782+//=======================================================================================
1783+
1784+void tWaveOsc_init(tWaveOsc* const cy, tWaveTable* const table, LEAF* const leaf)
1785+{
1786+ tWaveOsc_initToPool(cy, table, &leaf->mempool);
1787+}
1788+
1789+void tWaveOsc_initToPool(tWaveOsc* const cy, tWaveTable* const table, tMempool* const mp)
17891790 {
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+
1805+void tWaveOsc_free(tWaveOsc* const cy)
1806+{
1807+ _tWaveOsc* c = *cy;
1808+ mpool_free((char*)c, c->mempool);
1809+}
1810+
1811+float tWaveOsc_tick(tWaveOsc* const cy)
1812+{
1813+ _tWaveOsc* c = *cy;
17911814
17921815 float temp;
17931816 int idx;
@@ -1795,35 +1818,38 @@ float tWavetable_tick(tWavetable* const cy) · 1 unmodified line
17951818 float samp0;
17961819 float samp1;
17971820
1821+ int size = c->table->size;
1822+ float** tables = c->table->tables;
1823+
17981824 // Phasor increment
17991825 c->phase += c->inc;
18001826 if (c->phase + c->phaseOffset >= 1.0f) c->phase -= 1.0f;
18011827 if (c->phase + c->phaseOffset < 0.0f) c->phase += 1.0f;
18021828
18031829 // Wavetable synthesis
1804− temp = c->size * (c->phase + c->phaseOffset);
1830+ temp = size * (c->phase + c->phaseOffset);
18051831
18061832 idx = (int)temp;
18071833 frac = temp - (float)idx;
1808− samp0 = c->tables[c->oct][idx];
1809− if (++idx >= c->size) idx = 0;
1810− samp1 = c->tables[c->oct][idx];
1834+ samp0 = tables[c->oct][idx];
1835+ if (++idx >= size) idx = 0;
1836+ samp1 = tables[c->oct][idx];
18111837
18121838 float oct0 = (samp0 + (samp1 - samp0) * frac);
18131839
18141840 idx = (int)temp;
1815− samp0 = c->tables[c->oct+1][idx];
1816− if (++idx >= c->size) idx = 0;
1817− samp1 = c->tables[c->oct+1][idx];
1841+ samp0 = tables[c->oct+1][idx];
1842+ if (++idx >= size) idx = 0;
1843+ samp1 = tables[c->oct+1][idx];
18181844
18191845 float oct1 = (samp0 + (samp1 - samp0) * frac);
18201846
18211847 return oct0 + (oct1 - oct0) * c->w;
18221848 }
18231849
1824−void tWavetable_setFreq(tWavetable* const cy, float freq)
1850+void tWaveOsc_setFreq(tWaveOsc* const cy, float freq)
18251851 {
1826− _tWavetable* c = *cy;
1852+ _tWaveOsc* c = *cy;
18271853
18281854 LEAF* leaf = c->mempool->leaf;
18291855
@@ -1833,7 +1859,7 @@ void tWavetable_setFreq(tWavetable* const cy, float freq) · 3 unmodified lines
18331859 c->inc -= (int)c->inc;
18341860
18351861 // abs for negative frequencies
1836− c->w = fabsf(c->freq * c->invBaseFreq);
1862+ c->w = fabsf(c->freq * c->table->invBaseFreq);
18371863
18381864 // Probably ok to use a log2 approx here; won't effect tuning at all, just crossfading between octave tables
18391865 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
18431869
18441870 // When out of range of our tables, this will prevent a crash.
18451871 // 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;
18471873 }
18481874
1849−void tWavetable_setAntiAliasing(tWavetable* const cy, float aa)
1875+void tWaveOsc_setAntiAliasing(tWaveOsc* const cy, float aa)
18501876 {
1851− _tWavetable* c = *cy;
1877+ _tWaveOsc* c = *cy;
18521878 c->aa = aa;
1853− tWavetable_setFreq(cy, c->freq);
1879+ tWaveOsc_setFreq(cy, c->freq);
18541880 }
18551881
1856−void tWavetable_setPhaseOffset(tWavetable* const cy, float phase)
1882+void tWaveOsc_setPhaseOffset(tWaveOsc* const cy, float phase)
18571883 {
1858− _tWavetable* c = *cy;
1884+ _tWaveOsc* c = *cy;
18591885 c->phaseOffset = phase - (int)phase;
18601886 }
18611887
1888+//================================================================================================
1889+//================================================================================================
1890+
1891+void 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+
1897+void 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+
1934+void 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+
1950+float 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+
1974+float 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+
1998+void 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+}
18622006
1863−void tCompactWavetable_init(tCompactWavetable* const cy, float* table, int size, float maxFreq, LEAF* const leaf)
2007+void tWaveSynth_setAntiAliasing(tWaveSynth* const cy, float aa)
18642008 {
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+
2019+void tWaveSynth_setIndex(tWaveSynth* const cy, float index)
2020+{
2021+ _tWaveSynth* c = *cy;
2022+ c->index = index;
2023+}
2024+
2025+void 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;
18662030 }
18672031
1868−void tCompactWavetable_initToPool(tCompactWavetable* const cy, float* table, int size, float maxFreq, tMempool* const mp)
2032+void 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+
2058+void 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+
2063+void tCompactWaveTable_initToPool(tCompactWaveTable* const cy, float* table, int size, float maxFreq, tMempool* const mp)
18692064 {
18702065 _tMempool* m = *mp;
1871− _tCompactWavetable* c = *cy = (_tCompactWavetable*) mpool_alloc(sizeof(_tCompactWavetable), m);
2066+ _tCompactWaveTable* c = *cy = (_tCompactWaveTable*) mpool_alloc(sizeof(_tCompactWaveTable), m);
18722067 c->mempool = m;
18732068
18742069 // Determine base frequency
@@ -1907,7 +2102,7 @@ void tCompactWavetable_initToPool(tCompactWavetable* const cy, float* table, int · 32 unmodified lines
19072102 tOversampler_initToPool(&c->ds, 2, 1, mp);
19082103 for (int t = 1; t < c->numTables; ++t)
19092104 {
1910− // Similar to tWavetable, doing multiple passes here helps, but not sure what number is optimal
2105+ // Similar to tWaveTable, doing multiple passes here helps, but not sure what number is optimal
19112106 for (int p = 0; p < 12; ++p)
19122107 {
19132108 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
19202115 }
19212116 tOversampler_free(&c->ds);
19222117 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);
19292118 }
19302119
1931−void tCompactWavetable_free(tCompactWavetable* const cy)
2120+void tCompactWaveTable_free(tCompactWaveTable* const cy)
19322121 {
1933− _tCompactWavetable* c = *cy;
2122+ _tCompactWaveTable* c = *cy;
19342123
19352124 for (int t = 0; t < c->numTables; ++t)
19362125 {
@@ -1941,9 +2130,37 @@ void tCompactWavetable_free(tCompactWavetable* const cy) · 4 unmodified lines
19412130 mpool_free((char*)c, c->mempool);
19422131 }
19432132
1944−float tCompactWavetable_tick(tCompactWavetable* const cy)
2133+//================================================================================================
2134+//================================================================================================
2135+
2136+void tCompactWaveOsc_init(tCompactWaveOsc* const cy, tCompactWaveTable* const table, LEAF* const leaf)
19452137 {
1946− _tCompactWavetable* c = *cy;
2138+ tCompactWaveOsc_initToPool(cy, table, &leaf->mempool);
2139+}
2140+
2141+void 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+
2155+void tCompactWaveOsc_free(tCompactWaveOsc* const cy)
2156+{
2157+ _tCompactWaveOsc* c = *cy;
2158+ mpool_free((char*)c, c->mempool);
2159+}
2160+
2161+float tCompactWaveOsc_tick(tCompactWaveOsc* const cy)
2162+{
2163+ _tCompactWaveOsc* c = *cy;
19472164
19482165 float temp;
19492166 int idx;
@@ -1956,31 +2173,34 @@ float tCompactWavetable_tick(tCompactWavetable* const cy) · 6 unmodified lines
19562173 if (c->phase >= 1.0f) c->phase -= 1.0f;
19572174 if (c->phase < 0.0f) c->phase += 1.0f;
19582175
2176+ int* sizes = c->table->sizes;
2177+ float** tables = c->table->tables;
2178+
19592179 // Wavetable synthesis
1960− temp = c->sizes[c->oct] * c->phase;
2180+ temp = sizes[c->oct] * (c->phase + c->phaseOffset);
19612181 idx = (int)temp;
19622182 frac = temp - (float)idx;
1963− samp0 = c->tables[c->oct][idx];
1964− if (++idx >= c->sizes[c->oct]) idx = 0;
1965− samp1 = c->tables[c->oct][idx];
2183+ samp0 = tables[c->oct][idx];
2184+ if (++idx >= sizes[c->oct]) idx = 0;
2185+ samp1 = tables[c->oct][idx];
19662186
19672187 float oct0 = (samp0 + (samp1 - samp0) * frac);
19682188
1969− temp = c->sizes[c->oct+1] * c->phase;
2189+ temp = sizes[c->oct+1] * c->phase;
19702190 idx = (int)temp;
19712191 frac = temp - (float)idx;
1972− samp0 = c->tables[c->oct+1][idx];
1973− if (++idx >= c->sizes[c->oct+1]) idx = 0;
1974− samp1 = c->tables[c->oct+1][idx];
2192+ samp0 = tables[c->oct+1][idx];
2193+ if (++idx >= sizes[c->oct+1]) idx = 0;
2194+ samp1 = tables[c->oct+1][idx];
19752195
19762196 float oct1 = (samp0 + (samp1 - samp0) * frac);
19772197
19782198 return oct0 + (oct1 - oct0) * c->w;
19792199 }
19802200
1981−void tCompactWavetable_setFreq(tCompactWavetable* const cy, float freq)
2201+void tCompactWaveOsc_setFreq(tCompactWaveOsc* const cy, float freq)
19822202 {
1983− _tCompactWavetable* c = *cy;
2203+ _tCompactWaveOsc* c = *cy;
19842204
19852205 LEAF* leaf = c->mempool->leaf;
19862206
@@ -1990,132 +2210,191 @@ void tCompactWavetable_setFreq(tCompactWavetable* const cy, float freq) · 3 unmodified lines
19902210 c->inc -= (int)c->inc;
19912211
19922212 // abs for negative frequencies
1993− c->w = fabsf(c->freq * c->invBaseFreq);
2213+ c->w = fabsf(c->freq * c->table->invBaseFreq);
19942214
19952215 // Probably ok to use a log2 approx here; won't effect tuning at all, just crossfading between octave tables
19962216 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
19972217 if (c->w < 0.0f) c->w = 0.0f; // If c->w is < 0.0f, then freq is less than our base freq
19982218 c->oct = (int)c->w;
19992219 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;
20012221 }
20022222
2003−void tCompactWavetable_setAntiAliasing(tCompactWavetable* const cy, float aa)
2223+void tCompactWaveOsc_setAntiAliasing(tCompactWaveOsc* const cy, float aa)
20042224 {
2005− _tCompactWavetable* c = *cy;
2006−
2225+ _tCompactWaveOsc* c = *cy;
20072226 c->aa = aa;
2008− tCompactWavetable_setFreq(cy, c->freq);
2227+ tCompactWaveOsc_setFreq(cy, c->freq);
2228+}
2229+
2230+void tCompactWaveOsc_setPhaseOffset(tCompactWaveOsc* const cy, float phase)
2231+{
2232+ _tCompactWaveOsc* c = *cy;
2233+ c->phaseOffset = phase - (int)phase;
20092234 }
20102235
20112236 //================================================================================================
20122237 //================================================================================================
20132238
2014−void tWaveset_init(tWaveset* const cy, float** tables, int n, int* sizes, float maxFreq, LEAF* const leaf)
2239+void tCompactWaveSynth_init(tCompactWaveSynth* const cy, int numVoices, float** tables, int* sizes,
2240+ int numTables, float maxFreq, LEAF* const leaf)
20152241 {
2016− tWaveset_initToPool(cy, tables, n, sizes, maxFreq, &leaf->mempool);
2242+ tCompactWaveSynth_initToPool(cy, numVoices, tables, sizes, numTables, maxFreq, &leaf->mempool);
20172243 }
20182244
2019−void tWaveset_initToPool(tWaveset* const cy, float** tables, int n, int* sizes, float maxFreq, tMempool* const mp)
2245+void tCompactWaveSynth_initToPool(tCompactWaveSynth* const cy, int numVoices, float** tables, int* sizes,
2246+ int numTables, float maxFreq, tMempool* const mp)
20202247 {
20212248 _tMempool* m = *mp;
2022− _tWaveset* c = *cy = (_tWaveset*) mpool_alloc(sizeof(_tWaveset), m);
2249+ _tCompactWaveSynth* c = *cy = (_tCompactWaveSynth*) mpool_alloc(sizeof(_tCompactWaveSynth), m);
20232250 c->mempool = m;
20242251
2025− c->n = 0;
2026− for (int t = 0; t < n; ++t)
2252+ c->numTables = 0;
2253+ for (int t = 0; t < numTables; ++t)
20272254 {
2028− if (sizes[t] > 0) c->n++;
2255+ if (sizes[t] > 0) c->numTables++;
20292256 }
20302257
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;
20322262
20332263 int i = 0;
2034− for (int t = 0; t < n; ++t)
2264+ for (int t = 0; t < numTables; ++t)
20352265 {
20362266 if (sizes[t] > 0)
20372267 {
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);
20392271 i++;
20402272 }
20412273 }
20422274
2043− c->g = (float*) mpool_alloc(sizeof(tWavetable) * c->n, m);
2044− for (int i = 0; i < c->n; ++i) c->g[i] = 1.0f;
2275+ c->g = (float*) mpool_alloc(sizeof(float) * c->numTables, m);
2276+ for (int i = 0; i < c->numTables; ++i) c->g[i] = 1.0f;
20452277
20462278 c->index = 0.0f;
2279+ c->maxFreq = maxFreq;
20472280 }
20482281
2049−void tWaveset_free(tWaveset* const cy)
2282+void tCompactWaveSynth_free(tCompactWaveSynth* const cy)
20502283 {
2051− _tWaveset* c = *cy;
2284+ _tCompactWaveSynth* c = *cy;
20522285
2053− for (int i = 0; i < c->n; ++i)
2286+ for (int i = 0; i < c->numTables; ++i)
20542287 {
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);
20562291 }
20572292 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);
20592295 mpool_free((char*)c, c->mempool);
20602296 }
20612297
2062−float tWaveset_tick(tWaveset* const cy)
2298+float 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+
2322+float tCompactWaveSynth_tickVoice(tCompactWaveSynth* const cy, int voice)
20632323 {
2064− _tWaveset* c = *cy;
2324+ _tCompactWaveSynth* c = *cy;
20652325
2066− float f = c->index * (c->n - 1);
2326+ float f = c->index * (c->numTables - 1);
20672327
20682328 int o1 = (int)f;
20692329 int o2 = o1 + 1;
20702330 if (c->index >= 1.0f) o2 = o1;
20712331 float mix = f - o1;
20722332
2073− float s0 = 0.f, s1 = 0.f, s2 = 0.f;
2074− for (int i = 0; i < c->n; ++i)
2333+ float s1 = 0.f, s2 = 0.f;
2334+ for (int t = 0; t < c->numTables; ++t)
20752335 {
2076− s0 = tWavetable_tick(&c->wt[i]) * c->g[i];
2077− if (i == o1) s1 = s0;
2078− if (i == o2) s2 = s0;
2336+ // Should we tick every voice anyway to preserve relative phases?
2337+ float s0 = tCompactWaveOsc_tick(&c->oscs[t][voice]);
2338+ if (t == o1) s1 = s0 * c->g[t];
2339+ if (t == o2) s2 = s0 * c->g[t];
20792340 }
20802341
20812342 // Ideally should determine correlation to get a good equal power fade between tables
20822343 return s1 + (s2 - s1) * mix;
20832344 }
20842345
2085−void tWaveset_setFreq(tWaveset* const cy, float freq)
2346+void tCompactWaveSynth_setFreq(tCompactWaveSynth* const cy, int voice, float freq)
20862347 {
2087− _tWaveset* c = *cy;
2088− for (int i = 0; i < c->n; ++i)
2348+ _tCompactWaveSynth* c = *cy;
2349+ for (int t = 0; t < c->numTables; ++t)
20892350 {
2090− tWavetable_setFreq(&c->wt[i], freq);
2351+ tCompactWaveOsc_setFreq(&c->oscs[t][voice], freq);
20912352 }
20922353 }
20932354
2094−void tWaveset_setAntiAliasing(tWaveset* const cy, float aa)
2355+void tCompactWaveSynth_setAntiAliasing(tCompactWaveSynth* const cy, float aa)
20952356 {
2096− _tWaveset* c = *cy;
2097− for (int i = 0; i < c->n; ++i)
2357+ _tCompactWaveSynth* c = *cy;
2358+ for (int t = 0; t < c->numTables; ++t)
20982359 {
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+ }
21002364 }
21012365 }
21022366
2103−void tWaveset_setIndex(tWaveset* const cy, float index)
2367+void tCompactWaveSynth_setIndex(tCompactWaveSynth* const cy, float index)
21042368 {
2105− _tWaveset* c = *cy;
2369+ _tCompactWaveSynth* c = *cy;
21062370 c->index = index;
21072371 }
21082372
2109−void tWaveset_setIndexGain(tWaveset* const cy, int i, float gain)
2373+void tCompactWaveSynth_setIndexGain(tCompactWaveSynth* const cy, int i, float gain)
21102374 {
2111− _tWaveset* c = *cy;
2112− if (i >= c->n) return;
2375+ _tCompactWaveSynth* c = *cy;
2376+ if (i >= c->numTables) return;
21132377 c->g[i] = gain;
21142378 }
21152379
2116−void tWaveset_setIndexPhase(tWaveset* const cy, int i, float phase)
2380+void tCompactWaveSynth_setIndexPhase(tCompactWaveSynth* const cy, int i, float phase)
21172381 {
2118− _tWaveset* c = *cy;
2119− if (i >= c->n) return;
2120− tWavetable_setPhaseOffset(&c->wt[i], phase);
2382+ _tCompactWaveSynth* c = *cy;
2383+ if (i >= c->numTables) return;
2384+ for (int v = 0; v < c->numVoices; ++v)
2385+ {
2386+ tCompactWaveOsc_setPhaseOffset(&c->oscs[i][v], phase);
2387+ }
21212388 }
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
1818
1919 //==============================================================================
2020
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.
2222 #define LEAF_INCLUDE_OVERSAMPLER_TABLES 1
2323
2424 // 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