Added DaisySP

This commit is contained in:
2026-04-24 14:46:05 +02:00
parent 82190216c3
commit dd63b3aed4
96 changed files with 10613 additions and 0 deletions
+59
View File
@@ -0,0 +1,59 @@
#include <random>
#include "dsp.h"
#include "clockednoise.h"
using namespace daisysp;
void ClockedNoise::Init(float sample_rate)
{
sample_rate_ = sample_rate;
phase_ = 0.0f;
sample_ = 0.0f;
next_sample_ = 0.0f;
frequency_ = 0.001f;
}
float ClockedNoise::Process()
{
float next_sample = next_sample_;
float sample = sample_;
float this_sample = next_sample;
next_sample = 0.0f;
const float raw_sample = rand() * kRandFrac * 2.0f - 1.0f;
float raw_amount = 4.0f * (frequency_ - 0.25f);
raw_amount = fclamp(raw_amount, 0.0f, 1.0f);
phase_ += frequency_;
if(phase_ >= 1.0f)
{
phase_ -= 1.0f;
float t = phase_ / frequency_;
float new_sample = raw_sample;
float discontinuity = new_sample - sample;
this_sample += discontinuity * ThisBlepSample(t);
next_sample += discontinuity * NextBlepSample(t);
sample = new_sample;
}
next_sample += sample;
next_sample_ = next_sample;
sample_ = sample;
return this_sample + raw_amount * (raw_sample - this_sample);
}
void ClockedNoise::SetFreq(float freq)
{
freq = freq / sample_rate_;
freq = fclamp(freq, 0.0f, 1.0f);
frequency_ = freq;
}
void ClockedNoise::Sync()
{
phase_ = 1.0f;
}
+66
View File
@@ -0,0 +1,66 @@
/*
Copyright (c) 2020 Electrosmith, Corp, Emilie Gillet
Use of this source code is governed by an MIT-style
license that can be found in the LICENSE file or at
https://opensource.org/licenses/MIT.
*/
#pragma once
#ifndef DSY_CLOCKEDNOISE_H
#define DSY_CLOCKEDNOISE_H
#include <stdint.h>
#ifdef __cplusplus
/** @file clockednoise.h */
namespace daisysp
{
/**
@brief Clocked Noise Module
@author Ported by Ben Sergentanis
@date Jan 2021
Noise processed by a sample and hold running at a target frequency. \n \n
Ported from pichenettes/eurorack/plaits/dsp/noise/clocked_noise.h \n
to an independent module. \n
Original code written by Emilie Gillet in 2016. \n
*/
class ClockedNoise
{
public:
ClockedNoise() {}
~ClockedNoise() {}
/** Initialize module
\param sample_rate Audio engine sample rate
*/
void Init(float sample_rate);
/** Get the next floating point sample */
float Process();
/** Set the frequency at which the next sample is generated.
\param freq Frequency in Hz
*/
void SetFreq(float freq);
/** Calling this forces another random float to be generated */
void Sync();
private:
// Oscillator state.
float phase_;
float sample_;
float next_sample_;
// For interpolation of parameters.
float frequency_;
float sample_rate_;
static constexpr float kRandFrac = 1.f / (float)RAND_MAX;
};
} // namespace daisysp
#endif
#endif
+62
View File
@@ -0,0 +1,62 @@
/*
Copyright (c) 2020 Electrosmith, Corp, Emilie Gillet
Use of this source code is governed by an MIT-style
license that can be found in the LICENSE file or at
https://opensource.org/licenses/MIT.
*/
#pragma once
#ifndef DSY_DUST_H
#define DSY_DUST_H
#include <cstdlib>
#include <random>
#include "Utility/dsp.h"
#ifdef __cplusplus
/** @file dust.h */
namespace daisysp
{
/**
@brief Dust Module
@author Ported by Ben Sergentanis
@date Jan 2021
Randomly Clocked Samples \n \n
Ported from pichenettes/eurorack/plaits/dsp/noise/dust.h \n
to an independent module. \n
Original code written by Emilie Gillet in 2016. \n
*/
class Dust
{
public:
Dust() {}
~Dust() {}
void Init() { SetDensity(.5f); }
float Process()
{
float inv_density = 1.0f / density_;
float u = rand() * kRandFrac;
if(u < density_)
{
return u * inv_density;
}
return 0.0f;
}
void SetDensity(float density)
{
density_ = fclamp(density, 0.f, 1.f);
density_ = density_ * .3f;
}
private:
float density_;
static constexpr float kRandFrac = 1.f / (float)RAND_MAX;
};
} // namespace daisysp
#endif
#endif
+90
View File
@@ -0,0 +1,90 @@
/*
Copyright (c) 2020 Electrosmith, Corp, Emilie Gillet
Use of this source code is governed by an MIT-style
license that can be found in the LICENSE file or at
https://opensource.org/licenses/MIT.
*/
#pragma once
#ifndef DSY_FRACTAL_H
#define DSY_FRACTAL_H
#include <stdint.h>
#ifdef __cplusplus
/** @file fractal_noise.h */
namespace daisysp
{
/**
@brief Fractal Noise, stacks octaves of a noise source.
@author Ported by Ben Sergentanis
@date Jan 2021
T is the noise source to use. T must have SetFreq() and Init(sample_rate) functions. \n
Order is the number of noise sources to stack. \n \n
Ported from pichenettes/eurorack/plaits/dsp/noise/fractal_random_generator.h \n
to an independent module. \n
Original code written by Emilie Gillet in 2016. \n
*/
template <typename T, int order>
class FractalRandomGenerator
{
public:
FractalRandomGenerator() {}
~FractalRandomGenerator() {}
/** Initialize the module
\param sample_rate Audio engine sample rate.
*/
void Init(float sample_rate)
{
sample_rate_ = sample_rate;
SetColor(.5f);
SetFreq(440.f);
for(int i = 0; i < order; ++i)
{
generator_[i].Init(sample_rate_);
}
}
/** Get the next sample. */
float Process()
{
float gain = 0.5f;
float sum = 0.0f;
float frequency = frequency_;
for(int i = 0; i < order; ++i)
{
generator_[i].SetFreq(frequency);
sum += generator_[i].Process() * gain;
gain *= decay_;
frequency *= 2.0f;
}
return sum;
}
/** Set the lowest noise frequency.
\param freq Frequency of the lowest noise source in Hz.
*/
void SetFreq(float freq) { frequency_ = fclamp(freq, 0.f, sample_rate_); }
/** Sets the amount of high frequency noise.
\** Works 0-1. 1 is the brightest, and 0 is the darkest.
*/
void SetColor(float color) { decay_ = fclamp(color, 0.f, 1.f); }
private:
float sample_rate_;
float frequency_;
float decay_;
T generator_[order];
};
} // namespace daisysp
#endif
#endif
+146
View File
@@ -0,0 +1,146 @@
#include "dsp.h"
#include "grainlet.h"
#include <math.h>
using namespace daisysp;
void GrainletOscillator::Init(float sample_rate)
{
sample_rate_ = sample_rate;
carrier_phase_ = 0.0f;
formant_phase_ = 0.0f;
next_sample_ = 0.0f;
carrier_shape_ = 0.f;
carrier_bleed_ = 0.f;
SetFreq(440.f);
SetFormantFreq(220.f);
SetShape(.5f);
SetBleed(.5f);
}
float GrainletOscillator::Process()
{
float this_sample = next_sample_;
float next_sample = 0.0f;
carrier_phase_ += carrier_frequency_;
if(carrier_phase_ >= 1.0f)
{
carrier_phase_ -= 1.0f;
float reset_time = carrier_phase_ / carrier_frequency_;
float shape_inc = new_carrier_shape_ - carrier_shape_;
float bleed_inc = new_carrier_bleed_ - carrier_bleed_;
float before = Grainlet(
1.0f,
formant_phase_ + (1.0f - reset_time) * formant_frequency_,
new_carrier_shape_ + shape_inc * (1.0f - reset_time),
new_carrier_bleed_ + bleed_inc * (1.0f - reset_time));
float after
= Grainlet(0.0f, 0.0f, new_carrier_shape_, new_carrier_bleed_);
float discontinuity = after - before;
this_sample += discontinuity * ThisBlepSample(reset_time);
next_sample += discontinuity * NextBlepSample(reset_time);
formant_phase_ = reset_time * formant_frequency_;
}
else
{
formant_phase_ += formant_frequency_;
if(formant_phase_ >= 1.0f)
{
formant_phase_ -= 1.0f;
}
}
carrier_bleed_ = new_carrier_bleed_;
carrier_shape_ = new_carrier_shape_;
next_sample += Grainlet(
carrier_phase_, formant_phase_, carrier_shape_, carrier_bleed_);
next_sample_ = next_sample;
return this_sample;
}
void GrainletOscillator::SetFreq(float freq)
{
carrier_frequency_ = freq / sample_rate_;
carrier_frequency_ = carrier_frequency_ > 0.5f ? 0.5f : carrier_frequency_;
}
void GrainletOscillator::SetFormantFreq(float freq)
{
formant_frequency_ = freq / sample_rate_;
formant_frequency_ = formant_frequency_ > 0.5f ? 0.5f : formant_frequency_;
}
void GrainletOscillator::SetShape(float shape)
{
new_carrier_shape_ = shape;
}
void GrainletOscillator::SetBleed(float bleed)
{
new_carrier_bleed_ = bleed;
}
float GrainletOscillator::Sine(float phase)
{
return sinf(phase * TWOPI_F);
}
float GrainletOscillator::Carrier(float phase, float shape)
{
shape *= 3.0f;
int shape_integral = static_cast<int>(shape);
float shape_fractional = shape - static_cast<float>(shape_integral);
float t = 1.0f - shape_fractional;
if(shape_integral == 0)
{
phase = phase * (1.0f + t * t * t * 15.0f);
if(phase >= 1.0f)
{
phase = 1.0f;
}
phase += 0.75f;
}
else if(shape_integral == 1)
{
float breakpoint = 0.001f + 0.499f * t * t * t;
if(phase < breakpoint)
{
phase *= (0.5f / breakpoint);
}
else
{
phase = 0.5f + (phase - breakpoint) * 0.5f / (1.0f - breakpoint);
}
phase += 0.75f;
}
else
{
t = 1.0f - t;
phase = 0.25f + phase * (0.5f + t * t * t * 14.5f);
if(phase >= 0.75f)
phase = 0.75f;
}
return (Sine(phase) + 1.0f) * 0.25f;
}
float GrainletOscillator::Grainlet(float carrier_phase,
float formant_phase,
float shape,
float bleed)
{
float carrier = Carrier(carrier_phase, shape);
float formant = Sine(formant_phase);
return carrier * (formant + bleed) / (1.0f + bleed);
}
+92
View File
@@ -0,0 +1,92 @@
/*
Copyright (c) 2020 Electrosmith, Corp, Emilie Gillet
Use of this source code is governed by an MIT-style
license that can be found in the LICENSE file or at
https://opensource.org/licenses/MIT.
*/
#pragma once
#ifndef DSY_GRAINLET_H
#define DSY_GRAINLET_H
#include <stdint.h>
#ifdef __cplusplus
/** @file grainlet.h */
namespace daisysp
{
/**
@brief Granular Oscillator Module.
@author Ben Sergentanis
@date Dec 2020
A phase-distorted single cycle sine * another continuously running sine, \n
the whole thing synced to a main oscillator. \n \n
Ported from pichenettes/eurorack/plaits/dsp/oscillator/grainlet_oscillator.h \n
to an independent module. \n
Original code written by Emilie Gillet in 2016. \n
*/
class GrainletOscillator
{
public:
GrainletOscillator() {}
~GrainletOscillator() {}
/** Initialize the oscillator
\param sample_rate Sample rate of audio engine
*/
void Init(float sample_rate);
/** Get the next sample */
float Process();
/** Sets the carrier frequency
\param freq Frequency in Hz
*/
void SetFreq(float freq);
/** Sets the formant frequency
\param freq Frequency in Hz
*/
void SetFormantFreq(float freq);
/** Waveshaping
\param shape Shapes differently from 0-1, 1-2, and > 2.
*/
void SetShape(float shape);
/** Sets the amount of formant to bleed through
\param bleed Works best 0-1
*/
void SetBleed(float bleed);
private:
float Sine(float phase);
float Carrier(float phase, float shape);
float Grainlet(float carrier_phase,
float formant_phase,
float shape,
float bleed);
// Oscillator state.
float carrier_phase_;
float formant_phase_;
float next_sample_;
// For interpolation of parameters.
float carrier_frequency_;
float formant_frequency_;
float carrier_shape_;
float carrier_bleed_;
float new_carrier_shape_;
float new_carrier_bleed_;
float sample_rate_;
};
} // namespace daisysp
#endif
#endif
+95
View File
@@ -0,0 +1,95 @@
#include "dsp.h"
#include "particle.h"
#include <math.h>
using namespace daisysp;
void Particle::Init(float sample_rate)
{
sample_rate_ = sample_rate;
sync_ = false;
aux_ = 0.f;
SetFreq(440.f);
resonance_ = .9f;
density_ = .5f;
gain_ = 1.f;
spread_ = 1.f;
SetRandomFreq(sample_rate_ / 48.f); //48 is the default block size
rand_phase_ = 0.f;
pre_gain_ = 0.0f;
filter_.Init(sample_rate_);
filter_.SetDrive(.7f);
}
float Particle::Process()
{
float u = rand() * kRandFrac;
float s = 0.0f;
if(u <= density_ || sync_)
{
s = u <= density_ ? u * gain_ : s;
rand_phase_ += rand_freq_;
if(rand_phase_ >= 1.f || sync_)
{
rand_phase_ = rand_phase_ >= 1.f ? rand_phase_ - 1.f : rand_phase_;
const float u = 2.0f * rand() * kRandFrac - 1.0f;
const float f
= fmin(powf(2.f, kRatioFrac * spread_ * u) * frequency_, .25f);
pre_gain_ = 0.5f / sqrtf(resonance_ * f * sqrtf(density_));
filter_.SetFreq(f * sample_rate_);
filter_.SetRes(resonance_);
}
}
aux_ = s;
filter_.Process(pre_gain_ * s);
return filter_.Band();
}
float Particle::GetNoise()
{
return aux_;
}
void Particle::SetFreq(float freq)
{
freq /= sample_rate_;
frequency_ = fclamp(freq, 0.f, 1.f);
}
void Particle::SetResonance(float resonance)
{
resonance_ = fclamp(resonance, 0.f, 1.f);
}
void Particle::SetRandomFreq(float freq)
{
freq /= sample_rate_;
rand_freq_ = fclamp(freq, 0.f, 1.f);
}
void Particle::SetDensity(float density)
{
density_ = fclamp(density * .3f, 0.f, 1.f);
}
void Particle::SetGain(float gain)
{
gain_ = fclamp(gain, 0.f, 1.f);
}
void Particle::SetSpread(float spread)
{
spread_ = spread < 0.f ? 0.f : spread;
}
void Particle::SetSync(bool sync)
{
sync_ = sync;
}
+92
View File
@@ -0,0 +1,92 @@
#pragma once
#ifndef DSY_PARTICLE_H
#define DSY_PARTICLE_H
#include "Filters/svf.h"
#include <stdint.h>
#include <cstdlib>
#ifdef __cplusplus
/** @file particle.h */
namespace daisysp
{
/**
@brief Random impulse train processed by a resonant filter.
@author Ported by Ben Sergentanis
@date Jan 2021
Noise processed by a sample and hold running at a target frequency. \n \n
Ported from pichenettes/eurorack/plaits/dsp/noise/particle.h \n
to an independent module. \n
Original code written by Emilie Gillet in 2016. \n
*/
class Particle
{
public:
Particle() {}
~Particle() {}
/** Initialize the module
\param sample_rate Audio engine sample rate.
*/
void Init(float sample_rate);
/** Get the next sample */
float Process();
/** Get the raw noise output. Must call Process() first. */
float GetNoise();
/** Set the resonant filter frequency
\param freq Frequency in Hz
*/
void SetFreq(float frequency);
/** Set the filter resonance
\param resonance Works 0-1
*/
void SetResonance(float resonance);
/** How often to randomize filter frequency
\param freq Frequency in Hz.
*/
void SetRandomFreq(float freq);
/** Noise density
\param Works 0-1.
*/
void SetDensity(float density);
/** Overall module gain
\param Works 0-1.
*/
void SetGain(float gain);
/** How much to randomize the set filter frequency.
\param spread Works over positive numbers.
*/
void SetSpread(float spread);
/** Force randomize the frequency.
\param sync True to randomize freq.
*/
void SetSync(bool sync);
private:
static constexpr float kRandFrac = 1.f / (float)RAND_MAX;
static constexpr float kRatioFrac = 1.f / 12.f;
float sample_rate_;
float aux_, frequency_, density_, gain_, spread_, resonance_;
bool sync_;
float rand_phase_;
float rand_freq_;
float pre_gain_;
Svf filter_;
};
} // namespace daisysp
#endif
#endif
+54
View File
@@ -0,0 +1,54 @@
/*
Copyright (c) 2020 Electrosmith, Corp
Use of this source code is governed by an MIT-style
license that can be found in the LICENSE file or at
https://opensource.org/licenses/MIT.
*/
#pragma once
#ifndef DSY_WHITENOISE_H
#define DSY_WHITENOISE_H
#include <stdint.h>
#ifdef __cplusplus
namespace daisysp
{
/** fast white noise generator
I think this came from musicdsp.org at some point
*/
class WhiteNoise
{
public:
WhiteNoise() {}
~WhiteNoise() {}
/** Initializes the WhiteNoise object
*/
void Init()
{
amp_ = 1.0f;
randseed_ = 1;
}
/** sets the amplitude of the noise output
*/
inline void SetAmp(float a) { amp_ = a; }
/** returns a new sample of noise in the range of -amp_ to amp_
*/
inline float Process()
{
randseed_ *= 16807;
return (randseed_ * coeff_) * amp_;
}
/** sets the seed (and corrects a seed of 0 to 1) */
inline void SetSeed(int32_t s) { randseed_ = s == 0 ? 1 : s; }
private:
static constexpr float coeff_ = 4.6566129e-010f;
float amp_;
int32_t randseed_;
};
} // namespace daisysp
#endif
#endif