Variable sample rate oscillator

Hi, I’m trying to coding a variable sample rate oscillator with Daisy.
I’ve a pre-compiled sine lookup table of 512 entry. A timer, which speed is regulated by a potentiometer, periodically trigger a function which pick up the new sine value and output it from the two internal 12bit DAC.
It works, but I can’t get it works for sine faster than 1.250 kHz ( timer speed 1.250 kHz * 512 = 640 kHz).
Is there a way to speed up the process?

#include "daisy_seed.h"
#include "daisysp.h"

#include <stdio.h>
#include <string.h>

using namespace daisy;
using namespace daisy::seed;
using namespace daisysp;


DaisySeed hw;


TimerHandle         tim2;
TimerHandle::Config tim_cfg;

///////////// Global  ///////////////////

const uint16_t      nSample = 512;
const uint16_t      sampleLimit = (nSample - 1);// * 1024;

float sine[nSample+1];
float final[2];


void routineOutput(){


    static int16_t I = 0;


    for(int i = 0; i < 2; i++){
        final[i]  =  sine[I] * 4000.f;
    }

     hw.dac.WriteValue(DacHandle::Channel::ONE, final[0]); // CV0
     hw.dac.WriteValue(DacHandle::Channel::TWO, final[1]); // CV0


    I++;
    if (I >= sampleLimit ) {   I = 0;  }

}


void CallbackOut(void* data){ routineOutput(); }  


int main(void)
{

    
    float Step = TWOPI_F / nSample;

    for (int a = 0; a < nSample; a++) { 
        sine[a] = sinf(Step * a);
        sine[a] = ((sine[a]+1.f)/2.f);
    }
    sine[sampleLimit] = sine[0];

    tim_cfg.periph     = TimerHandle::Config::Peripheral::TIM_5;
    tim_cfg.enable_irq = true;
    tim_cfg.period = 500;
    tim2.Init(tim_cfg);
    tim2.SetCallback(CallbackOut);
    tim2.Start();


    hw.Configure();
    hw.Init();


    const int num_adc_channels = 1;
    AdcChannelConfig adc_config[num_adc_channels]; 
    adc_config[0].InitSingle(A0);


    hw.adc.Init(adc_config, num_adc_channels);
    hw.adc.Start();
 
   
	// init DAC outputs
	DacHandle::Config cfg;
	cfg.bitdepth   = DacHandle::BitDepth::BITS_12;
	cfg.buff_state = DacHandle::BufferState::ENABLED;
	cfg.mode       = DacHandle::Mode::POLLING;
	cfg.chn        = DacHandle::Channel::BOTH;
	hw.dac.Init(cfg);



    // Loop forever
    for(;;)
    {
    uint32_t vOct = hw.adc.Get(0);
    static uint32_t  oldVOct;

    if(oldVOct > vOct + 5 || oldVOct < vOct - 5 ){
      oldVOct =  vOct;
      tim_cfg.period = vOct;
      tim2.Init(tim_cfg);
    }


    }
}




I’m really sorry for the delay in response.

This is an interesting issue. I’ll bring this up with the team and get back to you once I have an answer. Thank you for the wait.

1 Like