initcommit osclsk prototype
This commit is contained in:
commit
4ade3a5f00
19 changed files with 1780 additions and 0 deletions
202
daisy/scope/scope.cpp
Normal file
202
daisy/scope/scope.cpp
Normal file
|
@ -0,0 +1,202 @@
|
|||
#include "daisy_seed.h"
|
||||
#include "daisysp.h"
|
||||
|
||||
#include "scope.hpp"
|
||||
#include "osclsk.hpp"
|
||||
|
||||
using namespace daisy;
|
||||
using namespace daisysp;
|
||||
|
||||
#define DMA_AREA_SIZE (3*(1 << 16))
|
||||
#define SCOPE_RING_BUF_SIZE 1024
|
||||
#define AUDIO_BLOCK_SIZE 2
|
||||
|
||||
|
||||
/* declarations */
|
||||
DaisySeed daisy_hw;
|
||||
CpuLoadMeter load_meter;
|
||||
|
||||
osclsk_scope scope;
|
||||
|
||||
uint8_t DMA_BUFFER_MEM_SECTION dma_area[DMA_AREA_SIZE];
|
||||
|
||||
static void audio_cb(AudioHandle::InputBuffer in,
|
||||
AudioHandle::OutputBuffer out, size_t sz);
|
||||
|
||||
Oscillator osc;
|
||||
WhiteNoise noise;
|
||||
|
||||
AdEnv kickVolEnv, kickPitchEnv, snareEnv;
|
||||
|
||||
Switch kick, snare;
|
||||
|
||||
RingBuffer<float, SCOPE_RING_BUF_SIZE> scope_in;
|
||||
|
||||
static void
|
||||
audio_cb(AudioHandle::InputBuffer in,
|
||||
AudioHandle::OutputBuffer out, size_t sz)
|
||||
{
|
||||
float osc_out, noise_out, snr_env_out, kck_env_out;
|
||||
float sig[AUDIO_BLOCK_SIZE];
|
||||
|
||||
load_meter.OnBlockStart();
|
||||
//Get rid of any bouncing
|
||||
snare.Debounce();
|
||||
kick.Debounce();
|
||||
|
||||
//If you press the kick button...
|
||||
if(kick.RisingEdge())
|
||||
{
|
||||
//Trigger both envelopes!
|
||||
kickVolEnv.Trigger();
|
||||
kickPitchEnv.Trigger();
|
||||
}
|
||||
|
||||
//If press the snare button trigger its envelope
|
||||
if(snare.RisingEdge())
|
||||
{
|
||||
snareEnv.Trigger();
|
||||
}
|
||||
|
||||
//Prepare the audio block
|
||||
for(size_t i = 0; i < sz; i++)
|
||||
{
|
||||
//Get the next volume samples
|
||||
snr_env_out = snareEnv.Process();
|
||||
kck_env_out = kickVolEnv.Process();
|
||||
|
||||
//Apply the pitch envelope to the kick
|
||||
osc.SetFreq(kickPitchEnv.Process());
|
||||
//Set the kick volume to the envelope's output
|
||||
osc.SetAmp(kck_env_out);
|
||||
//Process the next oscillator sample
|
||||
osc_out = osc.Process();
|
||||
|
||||
//Get the next snare sample
|
||||
noise_out = noise.Process();
|
||||
//Set the sample to the correct volume
|
||||
noise_out *= snr_env_out;
|
||||
|
||||
//Mix the two signals at half volume
|
||||
sig[i] = .5 * noise_out + .5 * osc_out;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sz; i++) {
|
||||
out[0][i] = sig[i];
|
||||
out[1][i] = sig[i];
|
||||
|
||||
}
|
||||
|
||||
scope_in.Overwrite(sig, sz);
|
||||
|
||||
load_meter.OnBlockEnd();
|
||||
}
|
||||
|
||||
static void
|
||||
setup_drums(void)
|
||||
{
|
||||
float samplerate;
|
||||
|
||||
/* kick n snare */
|
||||
samplerate = daisy_hw.AudioSampleRate();
|
||||
|
||||
//Initialize oscillator for kickdrum
|
||||
osc.Init(samplerate);
|
||||
osc.SetWaveform(Oscillator::WAVE_TRI);
|
||||
osc.SetAmp(1);
|
||||
|
||||
//Initialize noise
|
||||
noise.Init();
|
||||
|
||||
//Initialize envelopes, this one's for the snare amplitude
|
||||
snareEnv.Init(samplerate);
|
||||
snareEnv.SetTime(ADENV_SEG_ATTACK, .01);
|
||||
snareEnv.SetTime(ADENV_SEG_DECAY, .2);
|
||||
snareEnv.SetMax(1);
|
||||
snareEnv.SetMin(0);
|
||||
|
||||
//This envelope will control the kick oscillator's pitch
|
||||
//Note that this envelope is much faster than the volume
|
||||
kickPitchEnv.Init(samplerate);
|
||||
kickPitchEnv.SetTime(ADENV_SEG_ATTACK, .01);
|
||||
kickPitchEnv.SetTime(ADENV_SEG_DECAY, .05);
|
||||
kickPitchEnv.SetMax(400);
|
||||
kickPitchEnv.SetMin(50);
|
||||
|
||||
//This one will control the kick's volume
|
||||
kickVolEnv.Init(samplerate);
|
||||
kickVolEnv.SetTime(ADENV_SEG_ATTACK, .01);
|
||||
kickVolEnv.SetTime(ADENV_SEG_DECAY, 1);
|
||||
kickVolEnv.SetMax(1);
|
||||
kickVolEnv.SetMin(0);
|
||||
|
||||
//Initialize the kick and snare buttons on pins 27 and 28
|
||||
//The callback rate is samplerate / blocksize (48)
|
||||
snare.Init(daisy_hw.GetPin(27), samplerate / (float)AUDIO_BLOCK_SIZE);
|
||||
kick.Init(daisy_hw.GetPin(28), samplerate / (float)AUDIO_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
|
||||
#define LOAD_METER_TICKS (1 << 16)
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
size_t read;
|
||||
float s[AUDIO_BLOCK_SIZE];
|
||||
int load_tick;
|
||||
daisy_hw.Configure();
|
||||
daisy_hw.Init();
|
||||
daisy_hw.StartLog(false); /* true = wait for usb connection */
|
||||
daisy_hw.SetAudioBlockSize(AUDIO_BLOCK_SIZE);
|
||||
|
||||
load_meter.Init(daisy_hw.AudioSampleRate(), daisy_hw.AudioBlockSize());
|
||||
load_tick = LOAD_METER_TICKS;
|
||||
|
||||
if (scope.init(dma_area, sizeof(dma_area)) == -1)
|
||||
daisy_hw.PrintLine("scope.init failed");
|
||||
|
||||
scope_in.Init();
|
||||
|
||||
setup_drums();
|
||||
|
||||
daisy_hw.StartAudio(audio_cb);
|
||||
|
||||
while (true) {
|
||||
|
||||
read = scope_in.readable();
|
||||
read = (read <= sizeof(s)/sizeof(*s)) ? read :
|
||||
sizeof(s)/sizeof(*s);
|
||||
|
||||
scope_in.ImmediateRead(s, read);
|
||||
|
||||
scope.sample(s, read);
|
||||
|
||||
switch (scope.state()) {
|
||||
case osclsk_scope::osc_state::SAMPLE_DONE:
|
||||
scope.render_block();
|
||||
break;
|
||||
case osclsk_scope::osc_state::RENDER_DONE:
|
||||
scope.prep();
|
||||
break;
|
||||
case osclsk_scope::osc_state::READY:
|
||||
scope.trig();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (--load_tick == 0) {
|
||||
load_tick = LOAD_METER_TICKS;
|
||||
// get the current load (smoothed value and peak values)
|
||||
const float avgLoad = load_meter.GetAvgCpuLoad();
|
||||
const float maxLoad = load_meter.GetMaxCpuLoad();
|
||||
const float minLoad = load_meter.GetMinCpuLoad();
|
||||
// print it to the serial connection (as percentages)
|
||||
daisy_hw.PrintLine("Processing Load %:");
|
||||
daisy_hw.PrintLine("Max: " FLT_FMT3, FLT_VAR3(maxLoad * 100.0f));
|
||||
daisy_hw.PrintLine("Avg: " FLT_FMT3, FLT_VAR3(avgLoad * 100.0f));
|
||||
daisy_hw.PrintLine("Min: " FLT_FMT3, FLT_VAR3(minLoad * 100.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue