Hi everyone! I’ve been programming Arduino for a few years now. This is my first shot at Daisy Seed, and I started with Daisyduino. It worked ok, but I wanted access to more robust effects ect.so I switched to Daisylib. Just to tug at your heart strings a bit and give you a little context, I’m building a simple synth for my 4 year old niece. My mom (her Grandma) is a ukulele virtuoso. My plan is to have an encoder and a 7 segment display that can set the buttons to any key major or minor, so Grandma can set the key and Niece can play along and make real in key music! So far I have 7 buttons, 7 pots 1 encoder and 1 7 segment display. The pots are set up to set the frequency for the Oscillators on each button. I saw the DaisyDrone ( https://github.com/cutlasses/DaisyDrone ) and figured it would be relatively easy to port it over… it wasn’t. I have the pots, encoder and 7 segment display wired up to the seed exactly like the Daisydrone schematic but I am having a heck of a time adding in my buttons and scales. Here’s my code so far. I’d love any suggestions on how to complete my project and any suggestions on improving my code would be fantastic as well… this is my first foray away from arduino and into C++. Me, my Mom and my Niece Caiden thank you SO much in advance! Feel free to ask for any clarification you may need. Thanks so much!
#include <array>
#include "daisy_seed.h"
#include "daisysp.h"
using namespace daisy;
using namespace daisysp;
using namespace daisy::seed;
// Declare a DaisySeed object called hw
DaisySeed hw;
// Declare Oscillators
Oscillator osc1, osc2, osc3, osc4, osc5, osc6, osc7;
// Declare Attack/Decay Envelopes
AdEnv env1, env2, env3, env4, env5, env6, env7;
// Declare Buttons
Switch button1, button2, button3, button4, button5, button6, button7;
void AudioCallback(AudioHandle::InterleavingInputBuffer in,
AudioHandle::InterleavingOutputBuffer out, size_t size)
{
// Create a mess of float variables
float osc1_out, env1_out, osc2_out, env2_out, osc3_out, env3_out, osc4_out, env4_out, osc5_out, env5_out, osc6_out, env6_out, osc7_out, env7_out;
//Nobody likes a bouncy button
button1.Debounce();
button2.Debounce();
button3.Debounce();
button4.Debounce();
button5.Debounce();
button6.Debounce();
button7.Debounce();
//If you push the button,...
if(button1.RisingEdge())
{
env1.Trigger(); //Trigger the envelope!
}
if(button2.RisingEdge())
{
env2.Trigger();
}
if(button3.RisingEdge())
{
env3.Trigger();
}
if(button4.RisingEdge())
{
env4.Trigger();
}
if(button5.RisingEdge())
{
env5.Trigger();
}
if(button6.RisingEdge())
{
env6.Trigger();
}
if(button7.RisingEdge())
{
env7.Trigger();
}
//Set Oscillators to a static "A minor" scale
//osc1.SetFreq(220);
//osc2.SetFreq(246.94);
//osc3.SetFreq(261.63);
//osc4.SetFreq(293.66);
//osc5.SetFreq(329.63);
//osc6.SetFreq(349.23);
//osc7.SetFreq(392);
//Use the knobs to set the frequency of each Oscillator
//Convert floating point knob to midi (0-127)
//Then convert midi to freq. in Hz
osc1.SetFreq(mtof(hw.adc.GetFloat(0) * 127));
osc2.SetFreq(mtof(hw.adc.GetFloat(1) * 127));
osc3.SetFreq(mtof(hw.adc.GetFloat(2) * 127));
osc4.SetFreq(mtof(hw.adc.GetFloat(3) * 127));
osc5.SetFreq(mtof(hw.adc.GetFloat(4) * 127));
osc6.SetFreq(mtof(hw.adc.GetFloat(5) * 127));
osc7.SetFreq(mtof(hw.adc.GetFloat(6) * 127));
//Fill the block with samples
for(size_t i = 0; i < size; i+=7)
{
//Get the next envelope value
env1_out = env1.Process();
//Set the oscillator volume to the latest env value
osc1.SetAmp(env1_out);
//get the next oscillator sample
osc1_out = osc1.Process();
env2_out = env2.Process();
osc2.SetAmp(env2_out);
osc2_out = osc2.Process();
env3_out = env3.Process();
osc3.SetAmp(env3_out);
osc3_out = osc3.Process();
env4_out = env4.Process();
osc4.SetAmp(env4_out);
osc4_out = osc4.Process();
env5_out = env5.Process();
osc5.SetAmp(env5_out);
osc5_out = osc5.Process();
env6_out = env6.Process();
osc6.SetAmp(env6_out);
osc6_out = osc6.Process();
env7_out = env7.Process();
osc7.SetAmp(env7_out);
osc7_out = osc7.Process();
//Set the left and right outputs
out[i] = osc1_out + osc2_out + osc3_out + osc4_out + osc5_out + osc6_out + osc7_out;
out[i + 1] = osc1_out + osc2_out + osc3_out + osc4_out + osc5_out + osc6_out + osc7_out;
}
}
int main(void)
{
// Configure and Initialize the Daisy Seed
// These are separate to allow reconfiguration of any of the internal
// components before initialization.
hw.Configure();
hw.Init(true);
hw.SetAudioBlockSize(6); // number of samples handled
//How many samples well output per second
float sample_rate = hw.AudioSampleRate();
// Create an array of 7 AdcChannelConfig objects
const int num_adc_channels = 7;
AdcChannelConfig my_adc_config[num_adc_channels];
//Initialize the knobs
my_adc_config[0].InitSingle(hw.GetPin(15));
my_adc_config[1].InitSingle(hw.GetPin(16));
my_adc_config[2].InitSingle(hw.GetPin(17));
my_adc_config[3].InitSingle(hw.GetPin(18));
my_adc_config[4].InitSingle(hw.GetPin(19));
my_adc_config[5].InitSingle(hw.GetPin(20));
my_adc_config[6].InitSingle(hw.GetPin(21));
//Initialize the buttons
button1.Init(hw.GetPin(13), sample_rate / 48.f);
button2.Init(hw.GetPin(12), sample_rate / 48.f);
button3.Init(hw.GetPin(11), sample_rate / 48.f);
button4.Init(hw.GetPin(10), sample_rate / 48.f);
button5.Init(hw.GetPin(9), sample_rate / 48.f);
button6.Init(hw.GetPin(8), sample_rate / 48.f);
button7.Init(hw.GetPin(7), sample_rate / 48.f);
//Set the ADC to use our configuration
hw.adc.Init(my_adc_config, num_adc_channels);
//Set up oscillators
osc1.Init(sample_rate);
osc1.SetWaveform(osc1.WAVE_TRI);
osc1.SetAmp(0.22f);
osc1.SetFreq(1000);
osc2.Init(sample_rate);
osc2.SetWaveform(osc2.WAVE_TRI);
osc2.SetAmp(0.22f);
osc2.SetFreq(1000);
osc3.Init(sample_rate);
osc3.SetWaveform(osc3.WAVE_TRI);
osc3.SetAmp(0.22f);
osc3.SetFreq(1000);
osc4.Init(sample_rate);
osc4.SetWaveform(osc4.WAVE_TRI);
osc4.SetAmp(0.22f);
osc4.SetFreq(1000);
osc5.Init(sample_rate);
osc5.SetWaveform(osc5.WAVE_TRI);
osc5.SetAmp(0.22f);
osc5.SetFreq(1000);
osc6.Init(sample_rate);
osc6.SetWaveform(osc6.WAVE_TRI);
osc6.SetAmp(0.22f);
osc6.SetFreq(1000);
osc7.Init(sample_rate);
osc7.SetWaveform(osc7.WAVE_TRI);
osc7.SetAmp(0.22f);
osc7.SetFreq(1000);
//Set up volume envelopes
env1.Init(sample_rate);
//Envelope attack and decay times
env1.SetTime(ADENV_SEG_ATTACK, .11);
env1.SetTime(ADENV_SEG_DECAY, .44);
//minimum and maximum envelope values
env1.SetMin(0.0);
env1.SetMax(1.0f);
env1.SetCurve(1); // linear
env2.Init(sample_rate);
env2.SetTime(ADENV_SEG_ATTACK, .11);
env2.SetTime(ADENV_SEG_DECAY, .44);
env2.SetMin(0.0);
env2.SetMax(1.0f);
env2.SetCurve(1);
env3.Init(sample_rate);
env3.SetTime(ADENV_SEG_ATTACK, .11);
env3.SetTime(ADENV_SEG_DECAY, .44);
env3.SetMin(0.0);
env3.SetMax(1.0f);
env3.SetCurve(1);
env4.Init(sample_rate);
env4.SetTime(ADENV_SEG_ATTACK, .11);
env4.SetTime(ADENV_SEG_DECAY, .44);
env4.SetMin(0.0);
env4.SetMax(1.0f);
env4.SetCurve(1);
env5.Init(sample_rate);
env5.SetTime(ADENV_SEG_ATTACK, .11);
env5.SetTime(ADENV_SEG_DECAY, .44);
env5.SetMin(0.0);
env5.SetMax(1.0f);
env5.SetCurve(1);
env6.Init(sample_rate);
env6.SetTime(ADENV_SEG_ATTACK, .11);
env6.SetTime(ADENV_SEG_DECAY, .44);
env6.SetMin(0.0);
env6.SetMax(1.0f);
env6.SetCurve(1);
env7.Init(sample_rate);
env7.SetTime(ADENV_SEG_ATTACK, .11);
env7.SetTime(ADENV_SEG_DECAY, .44);
env7.SetMin(0.0);
env7.SetMax(1.0f);
env7.SetCurve(1);
//Start the adc
hw.adc.Start();
//Start calling the audio callback
hw.StartAudio(AudioCallback);
// Loop forever
while(1) {
}
}
EDIT: So far this code works great… I just need the 7 segment display and encoder to change the scale of the buttons!