Skip to content

Commit

Permalink
Merge pull request electro-smith#49 from beserge/samplehold
Browse files Browse the repository at this point in the history
Added sample and hold module
  • Loading branch information
stephenhensley authored Jun 30, 2020
2 parents fdfd826 + 86e3903 commit 45378f2
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 0 deletions.
1 change: 1 addition & 0 deletions daisysp.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include "modules/PolyPluck.h"
#include "modules/pluck.h"
#include "modules/reverbsc.h"
#include "modules/samplehold.h"
#include "modules/svf.h"
#include "modules/tone.h"
#include "modules/whitenoise.h"
Expand Down
14 changes: 14 additions & 0 deletions examples/samplehold/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Project Name
TARGET = ex_samplehold

# Sources
CPP_SOURCES = ex_samplehold.cpp

# Library Locations
LIBDAISY_DIR ?= ../../../libdaisy
DAISYSP_DIR ?= ../../../DaisySP

# Core location, and generic Makefile.
SYSTEM_FILES_DIR = $(LIBDAISY_DIR)/core
include $(SYSTEM_FILES_DIR)/Makefile

77 changes: 77 additions & 0 deletions examples/samplehold/ex_samplehold.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#include "daisysp.h"
#include "daisy_seed.h"

// Interleaved audio definitions
#define LEFT (i)
#define RIGHT (i + 1)

using namespace daisysp;
using namespace daisy;

static DaisySeed seed;
static Oscillator osc;
static Metro tick;
static WhiteNoise noise;
static AdEnv env;
static SampleHold sh;

float osc_out = 0;

static void AudioCallback(float *in, float *out, size_t size)
{
float osc_out, env_out;
for(size_t i = 0; i < size; i += 2)
{
uint8_t trig = tick.Process();
float newsample = sh.Process(
trig, noise.Process() * 500 + 500, sh.MODE_SAMPLE_HOLD);

// When the metro ticks, trigger the envelope to start.
if(trig)
{
env.Trigger();
tick.SetFreq(newsample / 100 + 1);
osc.SetFreq(newsample);
}

// Use envelope to control the amplitude of the oscillator.
env_out = env.Process();
osc.SetAmp(env_out);
osc_out = osc.Process();

out[LEFT] = osc_out;
out[RIGHT] = osc_out;
}
}

int main(void)
{
// initialize seed hardware and daisysp modules
float sample_rate;
seed.Configure();
seed.Init();
sample_rate = seed.AudioSampleRate();
env.Init(sample_rate);
osc.Init(sample_rate);
tick.Init(1, sample_rate);

// set adenv parameters
env.SetTime(ADENV_SEG_ATTACK, 0.01);
env.SetTime(ADENV_SEG_DECAY, 0.1);
env.SetMin(0.0);
env.SetMax(0.25);
env.SetCurve(0.5);

// Set parameters for oscillator
osc.SetWaveform(osc.WAVE_TRI);
osc.SetFreq(220);
osc.SetAmp(0.25);

noise.Init();

// start callback
seed.StartAudio(AudioCallback);


while(1) {}
}
61 changes: 61 additions & 0 deletions modules/samplehold.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#pragma once
#ifndef DSY_SAMPLEHOLD_H
#define DSY_SAMPLEHOLD_H

#include <stdint.h>
#ifdef __cplusplus

namespace daisysp
{
/** Dual track and hold / Sample and hold module. \n
Ported from soundpipe by Ben Sergentanis, June 2020.
@author Paul Batchelor
@date 2015
*/
class SampleHold
{
public:
SampleHold() {}
~SampleHold() {}

enum Mode
{
MODE_SAMPLE_HOLD,
MODE_TRACK_HOLD,
MODE_LAST,
};

/** Process the next sample. Both sample and track and hold are run in parallel
\param trigger Trigger the sample/track and hold
\param input Signal to be sampled/tracked and held
\param mode Whether to output the tracked or sampled values.
*/
inline float
Process(bool trigger, float input, Mode mode = MODE_SAMPLE_HOLD)
{
Update(trigger, input);
return mode == MODE_SAMPLE_HOLD ? sample_ : track_;
}

private:
float track_ = 0;
float sample_ = 0;
bool previous_ = false;


inline void Update(bool trigger, float input)
{
if(trigger)
{
if(!previous_)
{
sample_ = input;
}
track_ = input;
}
previous_ = trigger;
}
};
} // namespace daisysp
#endif
#endif

0 comments on commit 45378f2

Please sign in to comment.