Sine bank oscillator


#1

hi there,

i had an idea for a anti aliased wavetable oscillator, but i would need some guidance/ideas.

basically i created a pd patch that spits out the 32 first harmonics of an arbitrary waveform. (hand drawn or generated) i thought i would save those values in a table and use them in axolotiland like this:

i would create an object with 32 sine oscillators running in the relation to the overtones. so:

base frequency = oscillator1
base frequency * 2 = oscillator2
base frequency * 3 = oscillator3 etc.

with the info of the table i would then adjust the gain of each oscillator. now the clue for anti aliasing!
i would check in the code if the base frequency * x is above nyquist and if it is, i would simply set the gain of that oscillator (and any above) to 0. brilliant, no?

my main questions are, what is the most efficient way to create a 32-sine oscillator with adjustable gain for each oscillator? (a patch with 32 oscillators and 32 math objects takes 30%)

are there any other simpler ways of band limited wavetable playback?

cheers


#2

Turns out i've already done something like that (but never published it like most of the experiments i did this summer)
esperim spectr.axp (7.7 KB)

The object that does the magic is that anonymous patch/object in the bottom side, while the coefficients are generated in the top left side of the patch and stored inside a table. The code is fairly simple and i'll let you study it

Some considerations:
1) in order to play more partials i used sine2t[] instead of SINE2TINTERP() to generate the partials, without interpolation. It doesn't sound awful at all and allows to play richer tones.
2) coefficient handling is done in k-rate, again for performance considerations. The partials playback is in s-rate and consists just of a for loop that scans from 0 to the highest partial. This means that dsp load is wildly variable (not really great)
3) coefficients (amplitudes of the partials) are kept inside an external table. This should allow for a better interaction of other axoloti objects.
4) partials are all played at phase 0, so the signal is very likely to clip.

Ask me anything if you need

EDIT: the object in itself is already functional, you should just figure a way to generate the amplitude coefficients and store them inside the table


#3

To get this compiled, I had to delete the spectral analyser object.


#4

Thanks for the report, i reuploaded the patch without the analyzer


#5

thanks for this! i will check it out soon. i could compile the patch even with the analyser, strange...


#6

Strange, indeed. Even with a patch with only the analyser I get a:
"xpatch.cpp:50:39: error: invalid conversion from 'int' to 'arm_cfft_radix4_instance_q31*' [-fpermissive]
arm_rfft_init_q31(&rfft, 128,0,1);"