Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
* compiling

* allpass

* freq conversion

* crunch bug

* still broke

* add phaser to make and daisysp.h, remove phaser include paths

* formatting

* change phaser.h delayline include to relative path

* fix phaser SetFreq clipping bug

* move hz to deltime conversion to last second

* add fonepole to mitigate lfo crunch around -1

* style to appease the robots

* fixed init and replaced MAX POLES macro with internal static constexpr

Co-authored-by: stephenhensley <stephen.p.hensley@gmail.com>
  • Loading branch information
beserge and stephenhensley authored Mar 2, 2021
1 parent 3ca6b0a commit b41b775
Show file tree
Hide file tree
Showing 4 changed files with 271 additions and 0 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ decimator \
flanger \
fold \
overdrive \
phaser \
reverbsc \
sampleratereducer \
tremolo
Expand Down
138 changes: 138 additions & 0 deletions Source/Effects/phaser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#include "dsp.h"
#include "phaser.h"
#include <math.h>

using namespace daisysp;

//PhaserEngine stuff
void PhaserEngine::Init(float sample_rate)
{
sample_rate_ = sample_rate;

del_.Init();
lfo_amp_ = 0.f;
feedback_ = .2f;
SetFreq(200.f);

del_.SetDelay(0.f);

os_ = 30.f; //30 hertz frequency offset, lower than this introduces crunch
deltime_ = 0.f;

last_sample_ = 0.f;
lfo_phase_ = 0.f;
SetLfoFreq(.3);
SetLfoDepth(.9);
}

float PhaserEngine::Process(float in)
{
float lfo_sig = ProcessLfo();
fonepole(deltime_, sample_rate_ / (lfo_sig + ap_freq_ + os_), .0001f);

last_sample_ = del_.Allpass(in + feedback_ * last_sample_, deltime_, .3f);

return (in + last_sample_) * .5f; //equal mix
}

void PhaserEngine::SetLfoDepth(float depth)
{
lfo_amp_ = fclamp(depth, 0.f, 1.f);
}

void PhaserEngine::SetLfoFreq(float lfo_freq)
{
lfo_freq = 4.f * lfo_freq / sample_rate_;
lfo_freq *= lfo_freq_ < 0.f ? -1.f : 1.f; //if we're headed down, keep going
lfo_freq_ = fclamp(lfo_freq, -.25f, .25f); //clip at +/- .125 * sr
}

void PhaserEngine::SetFreq(float ap_freq)
{
ap_freq_ = fclamp(ap_freq, 0.f, 20000.f); //0 - 20kHz
}

void PhaserEngine::SetFeedback(float feedback)
{
feedback_ = fclamp(feedback, 0.f, .75f);
}

float PhaserEngine::ProcessLfo()
{
lfo_phase_ += lfo_freq_;

//wrap around and flip direction
if(lfo_phase_ > 1.f)
{
lfo_phase_ = 1.f - (lfo_phase_ - 1.f);
lfo_freq_ *= -1.f;
}
else if(lfo_phase_ < -1.f)
{
lfo_phase_ = -1.f - (lfo_phase_ + 1.f);
lfo_freq_ *= -1.f;
}

return lfo_phase_ * lfo_amp_ * ap_freq_;
}

//Phaser Stuff
void Phaser::Init(float sample_rate)
{
for(size_t i = 0; i < kMaxPoles; i++)
{
engines_[i].Init(sample_rate);
}

poles_ = 4;
gain_frac_ = .5f;
}

float Phaser::Process(float in)
{
float sig = 0.f;

for(int i = 0; i < poles_; i++)
{
sig += engines_[i].Process(in);
}

return sig;
}

void Phaser::SetPoles(int poles)
{
poles_ = DSY_CLAMP(poles, 1, 8);
}

void Phaser::SetLfoDepth(float depth)
{
for(int i = 0; i < kMaxPoles; i++)
{
engines_[i].SetLfoDepth(depth);
}
}

void Phaser::SetLfoFreq(float lfo_freq)
{
for(int i = 0; i < kMaxPoles; i++)
{
engines_[i].SetLfoFreq(lfo_freq);
}
}

void Phaser::SetFreq(float ap_freq)
{
for(int i = 0; i < kMaxPoles; i++)
{
engines_[i].SetFreq(ap_freq);
}
}

void Phaser::SetFeedback(float feedback)
{
for(int i = 0; i < kMaxPoles; i++)
{
engines_[i].SetFeedback(feedback);
}
}
131 changes: 131 additions & 0 deletions Source/Effects/phaser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#pragma once
#ifndef DSY_PHASER_H
#define DSY_PHASER_H
#ifdef __cplusplus

#include <stdint.h>
#include "Utility/delayline.h"

/** @file phaser.h */

namespace daisysp
{
/**
@brief Single Phaser engine. Used in Phaser.
@author Ben Sergentanis
*/
class PhaserEngine
{
public:
PhaserEngine() {}
~PhaserEngine() {}

/** Initialize the module
\param sample_rate Audio engine sample rate.
*/
void Init(float sample_rate);

/** Get the next sample
\param in Sample to process
*/
float Process(float in);

/** How much to modulate the allpass filter by.
\param depth Works 0-1.
*/
void SetLfoDepth(float depth);

/** Set lfo frequency.
\param lfo_freq Frequency in Hz
*/
void SetLfoFreq(float lfo_freq);

/** Set the allpass frequency
\param ap_freq Frequency in Hz.
*/
void SetFreq(float ap_freq);

/** Set the feedback amount.
\param feedback Amount from 0-1.
*/
void SetFeedback(float feedback);

private:
float sample_rate_;
static constexpr int32_t kDelayLength
= 2400; // 50 ms at 48kHz = .05 * 48000

//triangle lfo
float lfo_phase_;
float lfo_freq_;
float lfo_amp_;

float os_;

float feedback_;
float ap_freq_;

float deltime_;
float last_sample_;

DelayLine<float, kDelayLength> del_;

float ProcessLfo();
};

//wraps up all of the phaser engines
/**
@brief Phaser Effect.
@author Ben Sergentanis
@date Jan 2021
*/
class Phaser
{
public:
Phaser() {}
~Phaser() {}

/** Initialize the module
\param sample_rate Audio engine sample rate
*/
void Init(float sample_rate);

/** Get the next floating point sample.
\param in Sample to process
*/
float Process(float in);

/** Number of allpass stages.
\param poles Works 1 to 8.
*/
void SetPoles(int poles);

/** Set all lfo depths
\param depth Works 0-1.
*/
void SetLfoDepth(float depth);

/** Set all lfo frequencies.
\param lfo_freq Lfo freq in Hz.
*/
void SetLfoFreq(float lfo_freq);

/** Set all channel allpass freq in Hz.
\param ap_freq Frequency in Hz.
*/
void SetFreq(float ap_freq);

/** Set all channels feedback.
\param feedback Works 0-1.
*/
void SetFeedback(float feedback);

private:
static constexpr int kMaxPoles = 8;
PhaserEngine engines_[kMaxPoles];
float gain_frac_;
int poles_;
};
} //namespace daisysp
#endif
#endif
1 change: 1 addition & 0 deletions Source/daisysp.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "Effects/fold.h"
#include "Effects/overdrive.h"
#include "Effects/reverbsc.h"
#include "Effects/phaser.h"
#include "Effects/pitchshifter.h"
#include "Effects/sampleratereducer.h"
#include "Effects/tremolo.h"
Expand Down

0 comments on commit b41b775

Please sign in to comment.