Aliasing Oscillators

I tried again, and now I am sure, when the mod-matrix which I posted first is commented in, the overall pitch is 1-2 octaves higher.

With NO mod source selected and NO mod target and NO mod-amount.
As if this mod-matrix would speed up the code.

This is black magic to me.

I am also observing a very high frequency going along with the expected oscillator wave. It might be responsible for the aliasing, and I have no idea where it comes from. Maybe I just broke the hardware?
But then…why is it only bad with that mod-matrix commented in?

The apparent change in pitch, and possibly the ‘aliasing’, can be attributed to incorrect indexing of output samples.

I would bet money against this being a hardware problem.

1 Like

thank you teleplayer,
taking you by the word,
here is the code, you can copy it into the oscillator example and build it.

the lfo sweeps the osc frequency and produces horrible aliasing,
the only code involved is the mod matrix(doing nothing), lfo and osc.

if you delete the mod matrix, aliasing is gone:

#include "daisysp.h"
#include <vector>
#include <string.h>
#include "daisy_seed.h"
#include "Utility/dsp.h"

using namespace daisysp;
using namespace daisy;



DaisySeed         hw;

Encoder encoder;
Switch  button;


static Oscillator osc;
static Oscillator osc2;
static Oscillator lfo;
static Svf        filt;
static Svf        dFilt;
static Metro      seqclk;
static Adsr       env;
static Adsr       envM;                 
float             envout=0, sig=0;
float             oscF=24, osc2F=24, osc2seq=0, Cut=0, peak=0;
float             seqF=0;
float             seqPeak=0;
float             seqDec = 0; 
int               trig=0, trigo = 0, trigA=0, trigB=0; 
int               Mod1Source=0, Mod1Targ=0, Mod2Source, Mod2Targ=0, Mod3Source=0, Mod3Targ=0, Mod4Source, Mod4Targ=0;
float             CutMod=0, PeakMod=0, ResMod=0, WavMod=0, PwMod=0, F1Mod=0, F2Mod=0, OctMod=0, GlideMod=0, LfoFmod=0, LfoAmod=0, TimeMod=0, fbMod=0, colMod=0, dResMod=0, dlvMod=0, AMod=0, DMod=0, SMod=0, RMod=0,
                  Cut2Mod=0, Peak2Mod=0, Res2Mod=0, Wav2Mod=0, Pw2Mod=0, F12Mod=0, F22Mod=0, Oct2Mod=0, Glide2Mod=0, Lfo2Fmod=0, Lfo2Amod=0, Time2Mod=0, fb2Mod=0, col2Mod=0, dRes2Mod=0, dlv2Mod=0, A2Mod=0, D2Mod=0, S2Mod=0, R2Mod=0,
                  Cut3Mod=0, Peak3Mod=0, Res3Mod=0, Wav3Mod=0, Pw3Mod=0, F13Mod=0, F23Mod=0, Oct3Mod=0, Glide3Mod=0, Lfo3Fmod=0, Lfo3Amod=0, Time3Mod=0, fb3Mod=0, col3Mod=0, dRes3Mod=0, dlv3Mod=0, A3Mod=0, D3Mod=0, S3Mod=0, R3Mod=0,
                  Cut4Mod=0, Peak4Mod=0, Res4Mod=0, Wav4Mod=0, Pw4Mod=0, F14Mod=0, F24Mod=0, Oct4Mod=0, Glide4Mod=0, Lfo4Fmod=0, Lfo4Amod=0, Time4Mod=0, fb4Mod=0, col4Mod=0, dRes4Mod=0, dlv4Mod=0, A4Mod=0, D4Mod=0, S4Mod=0, R4Mod=0, Mod1Amt=0, delTfone=.5, delT=.5, dCut=1500, dCtf=5, fb=.5, dlv=.5;
float             keyF=0, oct=0; 
int               beat[8] {1, 1, 1, 1, 1, 1, 1, 1};
int               seqP[8] {0, 0, 0, 0, 0, 0, 0, 0};
float             seqD[8] {0, 0, 0, 0, 0, 0, 0, 0};
float             seDc[8] {0, 0, 0, 0, 0, 0, 0, 0};
int               Pval=0, Pval2=0, Pval3=0;           
int               cnt = 0, step = 0, stepped = 0, steppedO = 0, stepO=0, osc2pv=0;
int               pg=0, pg4=0, pgtrig=0, pgtrigO=0;              
int               Mod4Amt=0, Mod3Amt=0, Mod2Amt=0;
int               subP=0, subP4=0, subP3=0, subP5=0;             
float             lfoF=0, lfo_=0, lfoF_=0, lfoOut=0,lfoFA=0, lfoFB=0, lfoFfn=0, deltalfoF= lfoFA - lfoFB;          
int               gate_=0, gate=0, scale=0;
int               current_preset=0;
float             Clfo=0,  fPeak=0, Res=0;
float             Att=0,  dec=0,  sus=0, deltasus=0, sus_=0, sus__=0, rel=0;
float             AttM=0,  decM1=0,  susM=0,  relM=0;
float             lfoP=0,  lfoAmpp=0, lfoAmp =0;
float             oscFk=0, oscF2k=0;
float             wav=0, octi=0;
float             pwk=0, pwmk=0;
int               cntO=0, ArpOn=0, ArpDir=0;           
int               pgO=0, btnUp=0, btnDw=0, btnUpO=0, btnDwO=0, btnUproc=0, btnDproc=0, btnL=0, btnR=0, btnLO=0, btnRO=0, btnLproc=0, btnRproc=0, pgtrig2O, pgtrig2;
float             fbFin=0, finF1=0, pwm=0, finalF1=0, finalF2=0, lfopamt=0, lfopwamt=0, resFin=0, lfoamt=0, cutFin=0, Menv=0, finF2=0, none=0, finsig=0, glide=0, glidefn=0, finF11=0, finF12=0;
int               Filterchoice=0; 
int output_value = 0;
int arpmem2=0, arpmem=0;
    float my1[8]={0}, my2[8]={0}, my3[8]={0};
    float my1_[8]={0}, my2_[8]={0}, my3_[8]={0};
    float my1delta[8]={0}, my2delta[8], my3delta[8]={0};
    float myP[8]={0}, myP2[8]={0}, myP3[8]={0};
        int Major[7]{0,2,4,5,7,9,11};
        int Minor[7]{0,2,3,5,8,9,10};
        int Penta[5]{0,3,5,8,10};
        int keyFsc=0;
        int keysc=0;
        int scoct=0;

 






void AudioCallback(AudioHandle::InputBuffer  in,
                          AudioHandle::OutputBuffer out,
                          size_t                    size)

{  

//MODARRAY
//MODARRAY

float Mod1Sources[11]={0, env.Process(trig&&gate_), envM.Process(trig&&gate_), lfoOut, seqDec, seqPeak, seqF, osc.Process(), osc2.Process(), keyF };

float* Mod1Targets[21]={0, &CutMod, &PeakMod, &ResMod, &WavMod, &PwMod, &F1Mod, &F2Mod, &OctMod, &GlideMod, &LfoFmod, &LfoAmod, &TimeMod, &fbMod, &colMod, &dResMod, &dlvMod, &AMod, &DMod, &SMod, &RMod};

for(int i=0; i<21; i++)

{*Mod1Targets[i] = 0;}

*Mod1Targets[Mod1Targ] = Mod1Sources[Mod1Source]*Mod1Amt/24;

float Mod2Sources[11]={0, env.Process(trig&&gate_), envM.Process(trig&&gate_), lfoOut, seqDec, seqPeak, seqF, osc.Process(), osc2.Process(), keyF };

float* Mod2Targets[21]={0, &Cut2Mod, &Peak2Mod, &Res2Mod, &Wav2Mod, &Pw2Mod, &F12Mod, &F22Mod, &Oct2Mod, &Glide2Mod, &Lfo2Fmod, &Lfo2Amod, &Time2Mod, &fb2Mod, &col2Mod, &dRes2Mod, &dlv2Mod, &A2Mod, &D2Mod, &S2Mod, &R2Mod};

for(int i=0; i<21; i++)

{*Mod2Targets[i] = 0;}

*Mod2Targets[Mod2Targ] = Mod2Sources[Mod2Source]*Mod2Amt/24;

float Mod3Sources[11]={0, env.Process(trig&&gate_), envM.Process(trig&&gate_), lfoOut, seqDec, seqPeak, seqF, osc.Process(), osc2.Process(), keyF };

float* Mod3Targets[21]={0, &Cut3Mod, &Peak3Mod, &Res3Mod, &Wav3Mod, &Pw3Mod, &F13Mod, &F23Mod, &Oct3Mod, &Glide3Mod, &Lfo3Fmod, &Lfo3Amod, &Time3Mod, &fb3Mod, &col3Mod, &dRes3Mod, &dlv3Mod, &A3Mod, &D3Mod, &S3Mod, &R3Mod};

for(int i=0; i<21; i++)

{*Mod3Targets[i] = 0;}

*Mod3Targets[Mod3Targ] = Mod3Sources[Mod3Source]*Mod3Amt/24;

float Mod4Sources[11]={0, env.Process(trig&&gate_), envM.Process(trig&&gate_), lfoOut, seqDec, seqPeak, seqF, osc.Process(), osc2.Process(), keyF };

float* Mod4Targets[21]={0, &Cut4Mod, &Peak4Mod, &Res4Mod, &Wav4Mod, &Pw4Mod, &F14Mod, &F24Mod, &Oct4Mod, &Glide4Mod, &Lfo4Fmod, &Lfo4Amod, &Time4Mod, &fb4Mod, &col4Mod, &dRes4Mod, &dlv4Mod, &A4Mod, &D4Mod, &S4Mod, &R4Mod};

for(int i=0; i<21; i++)

{*Mod4Targets[i] = 0;}

*Mod4Targets[Mod4Targ] = Mod4Sources[Mod4Source]*Mod4Amt/24;

    osc.SetFreq(lfo.Process()*12000+6000);

    finsig=osc.Process();

    for(size_t i = 0; i < size; i++)
    {
        out[0][i]=finsig*.7f;
        out[1][i]=finsig*.7f;
    }
}

int main(void)
{
    
    
    hw.Configure();
    hw.Init(true);
    hw.SetAudioBlockSize(4);
    //hw.SetAudioSampleRate(SaiHandle::Config::SampleRate::SAI_96KHZ);
    float sample_rate = hw.AudioSampleRate();

    lfo.Init(sample_rate);

    //init metro object
    seqclk.Init(2, sample_rate);
    seqclk.SetFreq (200);

    //Set envelope parameters
    env.Init(sample_rate);
    env.SetTime(ADSR_SEG_ATTACK, .1);
    env.SetTime(ADSR_SEG_DECAY, .5);
    env.SetTime(ADSR_SEG_RELEASE, .5);  
    env.SetSustainLevel(.5);

    //Mod>Env Init
    envM.Init(sample_rate);
    envM.SetTime(ADSR_SEG_ATTACK, .1);
    envM.SetTime(ADSR_SEG_DECAY, .5);
    envM.SetTime(ADSR_SEG_RELEASE, .5);  
    envM.SetSustainLevel(.5);

    // Set parameters for oscillator
    osc.Init(sample_rate);
    osc.SetWaveform(6);
    osc.SetFreq(6220);
    osc.SetAmp(0.5);

    // Set parameters for oscillator
    osc2.Init(sample_rate);
    osc2.SetWaveform(6);
    osc2.SetFreq(6220);
    osc2.SetAmp(0.5);
    
    lfo.SetWaveform(0);
    lfo.SetFreq(.2);

    // Initialize Filter, and set parameters.
    filt.Init(sample_rate);
    filt.SetFreq(9500.0);
    filt.SetRes(0.1);
    filt.SetDrive(0.8);


    dFilt.Init(sample_rate);
    dFilt.SetFreq(1500);
    dFilt.SetRes(0.1);
    dFilt.SetDrive(0.1);


    /** Initialize our Encoder */
    encoder.Init(seed::D6, seed::D7, seed::D8);
    
    // start callback
    hw.StartAudio(AudioCallback);

    
	// Setup to print 
	hw.StartLog();
    

    while(1) {

    } 
}

You are calling osc.Process() way too many times.
It is called in the initializers for: Mod1Sources,Mod2Sources,Mod3Sources,Mod4Sources.

And then it’s called:
finsig=osc.Process();

…to produce the actual sample. But that’s incorrect, it’s only called once per block, should be called once per sample, so the actual frequency will be off by a factor of 4 (blocksize)

I’m not going to try to figure out what you’re trying to do with that mod matrix, it makes sense to you, that’s good enough for me.

I’d suggest starting from simple, and building up to complex, testing and saving your work along the way.

1 Like

thanks, thats a useful bit of information.

“it’s only called once per block, should be called once per sample”
so should I call osc.Process, lfo.Process and env.Process
in the final for-loop, so they are called once per sample,
and then say osc=osc.Process, and then go on using osc in all the different places?

that mod matrix has multiple sources like envelopes, lfo, osc
and multiple targets like cutoff, delay time or envelope segment.
I use the oled and encoder to select source, target and mod amount.
the for-loop zeroes everything so that only the selected connection is active.

I understand the concept, I just didn’t want to think about how it works.

The details about how to call the Process() function are up to you, but they must be called at the rate they are initialized for.

Anyway, I ran your code, and the misuse of osc.Process() in the initializers is the cause of the ‘aliasing’. Changing the osc.Process() to osc2.Process() (which is unused) in those locations gets the unaliased frequency sweep, though it was just a quick way to check it out; it’s obviously not correct for your mod matrix scheme, and the frequency is still wrong, because osc.Process() is called per block.

1 Like

thanks for looking into this.

would you bear with me with another very weird problem?

I have another project, an fx device which I am building. the daisy in on a pcb, circuits for audio and cv are borrowed from the bluemchen module.

the daisy is powered with 5v from eurorack.

when I disconnect usb, the oled freezes, and when I restart the eurorack, the screen stays frozen.

when I reboot the daisy and move the encoder, the daisy freezes.

when the daisy is powered by eurorack AND usb
everything works fine.

also, after flashing I always have to hit the reboot button (not necessary in my synth project).

the daisy takes long to boot.

sorry if this makes bo sense to you, but maybe you came across similar problems already….

oled and encoder are powered by the daisys digital voltage output. could it be that this is not sufficient without usb connected and I should use the analog voltage only?

I wonder why you chose not to power it like Bluemchen? To save the expense of the dc-dc converter?

Without seeing a schematic, it’s hard to say what might be happening. The only thing to do is start measuring voltages.

bluemchen uses the B2405S-1W, but due to availability I used the B0505S-1W instead.

Bad idea, the daisy would not power up, so I ripped it out and used eurorack 5v directly because why not.

I think it fried the daisy onboard 3.3v converter.
Maybe it has a different pinout, to me it looked the same.

Measuring voltage gave me fluctuation on daisys 5v input,
using a 5v battery made the daisy power lamp fluctuate.

I plugged in a fresh daisy today and everything works fine so far.
Daisy boots up quickly again and no crashes.

This is my first fried daisy, yikes.

Thank you so much, teleplayer for leading me to the right path again!