electro-smith / libDaisy

Hardware Library for the Daisy Audio Platform
https://www.electro-smith.com/daisy
MIT License
314 stars 131 forks source link

Knob example doesn't work if Oscillator.setAmp or .setFreq called #479

Open dfeeuh opened 2 years ago

dfeeuh commented 2 years ago

BUG: Getting up and running with Daisy Seed and trying to debug the DSP/oscillator example by working from the Knob example. I discovered the LED brightness does not change in the example code attached unless I comment out osc.SetAmp and osc.SetFreq in main(). It doesn't matter whether the audio callback is running or not (it can be completely removed and same behaviour). There's nothing fancy about these functions and digging into the depths of the libs is not what I want to do, but I'd like to understand why.

#include "daisy_seed.h"
#include "daisysp.h"
using namespace daisy;
using namespace daisysp;

DaisySeed  hardware;
Oscillator osc;

void AudioCallback(AudioHandle::InputBuffer in, AudioHandle::OutputBuffer out, size_t size)
{
    osc.SetAmp(1.f);

    //Convert floating point knob to midi (0-127)
    //Then convert midi to freq. in Hz
    osc.SetFreq(mtof(hardware.adc.GetFloat(0) * 127));

    for(size_t i = 0; i < size; i ++)
    {
        //Set the oscillator volume to the latest env value
        //get the next oscillator sample
        float osc_out = osc.Process();

        //Set the left and right outputs
        out[0][i] = osc_out;
        out[1][i] = osc_out;
    }
}

int main(void)
{
// Declare a variable to store the state we want to set for the LED.
    bool led_state;
    led_state = true;

    hardware.Init();
    hardware.SetAudioBlockSize(4); // number of samples handled per callback
    float samplerate = hardware.AudioSampleRate();

    Led led1;
    //Initialize led1. We'll plug it into pin 28.
    //false here indicates the value is uninverted
    led1.Init(hardware.GetPin(28), false);

    //This is our ADC configuration
    AdcChannelConfig adcConfig;
    //Configure pin 21 as an ADC input. This is where we'll read the knob.
    adcConfig.InitSingle(hardware.GetPin(21));

    //Initialize the adc with the config we just made
    hardware.adc.Init(&adcConfig, 1);

    // Set up oscillator
    osc.Init(samplerate);
    osc.SetWaveform(osc.WAVE_SIN);
    // BUG! If these lines are uncommented then for some reason the
    // led1 is not updated in main while loop. It doesn't matter whether
    // the audio callback is running or not.
    osc.SetAmp(1.f);
    osc.SetFreq(1000);
    ///////////////////////////////

    //Start reading values
    hardware.adc.Start();

    hardware.StartAudio(AudioCallback);

    while(1) {
        // Set the onboard LED to the value we read from the knob
        led1.Set(hardware.adc.GetFloat(0));

        //Update the led to reflect the set value
        led1.Update();

        //wait 1 ms
        System::Delay(1);
    }
}
stephenhensley commented 2 years ago

Fascinating -- This looks pretty similar to how a lot of other examples work. We'll take a look and see if we can reproduce this and post back here once we've figured it out.

Thanks for the report!