Adressing multiple sine oscilators in for loop for additive synthesis

Status
Not open for further replies.

interbellum

New member
Hello guys,

I would like to make a sketch that has about 32 sine wave oscillators running at the same time as to create an additive syntheser.
Every loop I'd like to update the frequency and amplitude of each of these 32 sine waves individually.
However I can't really seem to find a flexible way to do this inside of the Teensy Audio Library.
I'd like to be able to do something like the following: (this is pseudo code and does not work)

Code:
for (int i =1; i < numOscs; i ++) { 
    sine[i].frequency(baseFreq * i);
}

The best I can do now is to mix groups of 4 sine waves into mixers into mixers etc. and then control each sine wave by calling it's seperate .frequency and .amplitude function in one huge function.
But this seems so crude and I feel there must a more elegant way of achieving this.

Does anyone here know of a way to create something like an Array of sine waves that mix automatically with each other and are adressable as described above?

Any help would be greatly appreciated! :)
 
Trying to make a FM synth?

Yea I too have had difficulty with addressing each oscillator individually instead of using a for loop.

Would love to hear a solution for it also..
 
Haven’t tried this myself, but maybe you could set up an array of POINTERS to your 32 sine objects. Then the code would look like:

Code:
for (int i =1; i < numOscs; i ++) { 
    sinePointerArray[i]->frequency(baseFreq * i);
}
 
...although, I'd think you could also just make an array of 'AudioSynthWaveformSine' objects. Did you try that?
Either way, I'd think you would still have to combine their outputs with mixers.
 
Last edited:
Yes, the array of pointers approach is probably best.

Don't forget AudioNoInterrupts() while you're doing the updates, so you can be sure all the updates apply at the same moment after AudioInterrupts() re-enables the audio update.
 
You can totally make an array of audio library objects, I did this for a quad FM oscillator test years ago. if I recall it was just a matter of creating the audio objects as :
pseudocode::

AudioObjectSine SineOsc[32];

and then addressing them like you were trying before but with regard to what @PaulStoffregen mentioned

AudioNoInterrupts();
for( index through 32){
SineOsc[index].frequency = index*multiplier;
}
AudioInterrupts()

Having said all this Im not certain how many sine oscillators will overload the CPU


Now, the way that I think could be a better option if it suits your agenda, specifically for creating a bank of sines at fixed intervals you could use an IFFT or DCT (google)
What I would do though, even lighter weight on the processor is to generate a wavetable with your desired harmonics. And/or look at chebychev polynomial wave shaping (basically a wave shaper doing something similar to a harmonic wavetable)
 
Oh also, if you are brave, I have a technique on the FV-1 DSP chip assembly language that only requires about 6 instructions to create a sine and cosine wave. I believe I posted it somewhere on the forum but here is the FV-1 code:



Code:
equ	oscSin	reg0
equ	oscCos	reg1

equ	oscFreq	pot0 ;reg2	

;----------- load ---------------
SKP 	RUN ,	3
WRAX 	oscSin,	0
SOF 	               0,	-1
WRAX 	oscCos,	0

;___________________
;------ Oscillator--------------
RDAX 	oscSin,	0.6
MULX 	oscFreq

RDAX 	oscCos,	1
WRAX 	oscCos,	-0.6
MULX 	oscFreq

RDAX 	oscSin,	1
WRAX 	oscSin,	0

You could probably get a boatload of sine and cosine pairs using this technique. I don't know how to translate to ARM ASM but I can translate to arduino. Roughly:

Code:
float sine = 0.0;
float cos = -1.0;
float oscFreq = 1.0;
loop{
oscCos = oscSin*oscFreq+oscCos;
oscSin = -oscCos*oscFreq+oscSin;
}

This is based on something called the Magic Circle if I remember correctly. It is basically a full feedback resonator. A resonant bandpass IIR filter with the Q turned all the way to infinite and the state initialized so that it circulates.

It is amazing for physical modeling. I made banks of these and added a damping decay multiplier, and you just send in a pop or other exciter and can pretty much model any percussive sound. It also ends up sounding more organic because the state of the resonators is always different upon a new excitation coming in, and this causes slight fluctuation that feels natural.
 
Last edited:
Status
Not open for further replies.
Back
Top