Skip to content

Commit

Permalink
Add Faust modules
Browse files Browse the repository at this point in the history
  • Loading branch information
beserge committed Dec 21, 2023
1 parent 847e31a commit 829535a
Show file tree
Hide file tree
Showing 8 changed files with 1,041 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ project(DaisySP_LGPL VERSION 0.0.1)
add_library(DaisySP_LGPL STATIC
Source/Control/line.cpp
Source/Dynamics/balance.cpp
Source/Dynamics/compressor.cpp
Source/Effects/bitcrush.cpp
Source/Effects/fold.cpp
Source/Effects/reverbsc.cpp
Expand All @@ -17,6 +18,7 @@ Source/Filters/moogladder.cpp
Source/Filters/nlfilt.cpp
Source/Filters/tone.cpp
Source/PhysicalModeling/pluck.cpp
Source/Synthesis/blosc.cpp
Source/Utility/jitter.cpp
Source/Utility/port.cpp
)
Expand All @@ -39,5 +41,6 @@ target_include_directories(DaisySP_LGPL PUBLIC
"Source/Effects"
"Source/Filters"
"Source/PhysicalModeling"
"Source/Synthesis"
"Source/Utility"
)
521 changes: 521 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ PHYSICAL_MODELING_MOD_DIR = PhysicalModeling
PHYSICAL_MODELING_MODULES = \
pluck \

SYNTHESIS_MOD_DIR = Synthesis
SYNTHESIS_MODULES = \
blosc

UTILITY_MOD_DIR = Utility
UTILITY_MODULES = \
jitter \
Expand All @@ -49,6 +53,7 @@ CPP_SOURCES += $(addsuffix .cpp, $(MODULE_DIR)/$(DYNAMICS_MOD_DIR)/$(DYNAMICS_MO
CPP_SOURCES += $(addsuffix .cpp, $(MODULE_DIR)/$(EFFECTS_MOD_DIR)/$(EFFECTS_MODULES))
CPP_SOURCES += $(addsuffix .cpp, $(MODULE_DIR)/$(FILTER_MOD_DIR)/$(FILTER_MODULES))
CPP_SOURCES += $(addsuffix .cpp, $(MODULE_DIR)/$(PHYSICAL_MODELING_MOD_DIR)/$(PHYSICAL_MODELING_MODULES))
CPP_SOURCES += $(addsuffix .cpp, $(MODULE_DIR)/$(SYNTHESIS_MOD_DIR)/$(SYNTHESIS_MODULES))
CPP_SOURCES += $(addsuffix .cpp, $(MODULE_DIR)/$(UTILITY_MOD_DIR)/$(UTILITY_MODULES))

######################################
Expand Down Expand Up @@ -130,6 +135,7 @@ C_INCLUDES = \
-I$(MODULE_DIR)/$(EFFECTS_MOD_DIR) \
-I$(MODULE_DIR)/$(FILTER_MOD_DIR) \
-I$(MODULE_DIR)/$(SAMPLING_MOD_DIR) \
-I$(MODULE_DIR)/$(SYNTHESIS_MOD_DIR) \
-I$(MODULE_DIR)/$(UTILITY_MOD_DIR)

# compile gcc flags
Expand Down
76 changes: 76 additions & 0 deletions Source/Dynamics/compressor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// # compressor
//
// Author: shensley, AvAars
//

#include <cmath>
#include <stdlib.h>
#include <stdint.h>
#include "compressor.h"

using namespace daisysp;

#ifndef max
#define max(a, b) ((a < b) ? b : a)
#endif

#ifndef min
#define min(a, b) ((a < b) ? a : b)
#endif

void Compressor::Init(float sample_rate)
{
sample_rate_ = min(192000, max(1, sample_rate));
sample_rate_inv_ = 1.0f / (float)sample_rate_;
sample_rate_inv2_ = 2.0f / (float)sample_rate_;

// Initializing the params in this order to avoid dividing by zero

SetRatio(2.0f);
SetAttack(0.1f);
SetRelease(0.1f);
SetThreshold(-12.0f);
AutoMakeup(true);

gain_rec_ = 0.1f;
slope_rec_ = 0.1f;
}

float Compressor::Process(float in)
{
float inAbs = fabsf(in);
float cur_slo = ((slope_rec_ > inAbs) ? rel_slo_ : atk_slo_);
slope_rec_ = ((slope_rec_ * cur_slo) + ((1.0f - cur_slo) * inAbs));
gain_rec_ = ((atk_slo2_ * gain_rec_)
+ (ratio_mul_
* fmax(((20.f * fastlog10f(slope_rec_)) - thresh_), 0.f)));
gain_ = pow10f(0.05f * (gain_rec_ + makeup_gain_));

return gain_ * in;
}

void Compressor::ProcessBlock(float *in, float *out, float *key, size_t size)
{
for(size_t i = 0; i < size; i++)
{
Process(key[i]);
out[i] = Apply(in[i]);
}
}

// Multi-channel block processing
void Compressor::ProcessBlock(float **in,
float **out,
float * key,
size_t channels,
size_t size)
{
for(size_t i = 0; i < size; i++)
{
Process(key[i]);
for(size_t c = 0; c < channels; c++)
{
out[c][i] = Apply(in[c][i]);
}
}
}
207 changes: 207 additions & 0 deletions Source/Dynamics/compressor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
/*
Copyright (c) 2023 Electrosmith, Corp, GRAME, Centre National de Creation Musicale.
Use of this source code is governed by the LGPL V2.1
license that can be found in the LICENSE file or at
https://opensource.org/license/lgpl-2-1/
*/

#pragma once
#ifndef DSY_COMPRESSOR_H
#define DSY_COMPRESSOR_H

#include "Utility/dsp.h"

namespace daisysp
{
/** dynamics compressor
influenced by compressor in soundpipe (from faust).
Modifications made to do:
- Less calculations during each process loop (coefficients recalculated on parameter change).
- C++-ified
- added sidechain support
- pulled gain apart for monitoring and multichannel support
- improved readability
- improved makeup-gain calculations
- changing controls now costs a lot less
- a lot less expensive
by: shensley, improved upon by AvAars
\todo Add soft/hard knee settings
*/
class Compressor
{
public:
Compressor() {}
~Compressor() {}
/** Initializes compressor
\param sample_rate rate at which samples will be produced by the audio engine.
*/
void Init(float sample_rate);

/** Compress the audio input signal, saves the calculated gain
\param in audio input signal
*/
float Process(float in);

/** Compresses the audio input signal, keyed by a secondary input.
\param in audio input signal (to be compressed)
\param key audio input that will be used to side-chain the compressor
*/
float Process(float in, float key)
{
Process(key);
return Apply(in);
}

/** Apply compression to the audio signal, based on the previously calculated gain
\param in audio input signal
*/
float Apply(float in) { return gain_ * in; }

/** Compresses a block of audio
\param in audio input signal
\param out audio output signal
\param size the size of the block
*/
void ProcessBlock(float *in, float *out, size_t size)
{
ProcessBlock(in, out, in, size);
}

/** Compresses a block of audio, keyed by a secondary input
\param in audio input signal (to be compressed)
\param out audio output signal
\param key audio input that will be used to side-chain the compressor
\param size the size of the block
*/
void ProcessBlock(float *in, float *out, float *key, size_t size);

/** Compresses a block of multiple channels of audio, keyed by a secondary input
\param in audio input signals (to be compressed)
\param out audio output signals
\param key audio input that will be used to side-chain the compressor
\param channels the number of audio channels
\param size the size of the block
*/
void ProcessBlock(float **in,
float **out,
float * key,
size_t channels,
size_t size);

/** Gets the amount of gain reduction */
float GetRatio() { return ratio_; }

/** Sets the amount of gain reduction applied to compressed signals
\param ratio Expects 1.0 -> 40. (untested with values < 1.0)
*/
void SetRatio(float ratio)
{
ratio_ = ratio;
RecalculateRatio();
}

/** Gets the threshold in dB */
float GetThreshold() { return thresh_; }

/** Sets the threshold in dB at which compression will be applied
\param threshold Expects 0.0 -> -80.
*/
void SetThreshold(float threshold)
{
thresh_ = threshold;
RecalculateMakeup();
}

/** Gets the envelope time for onset of compression */
float GetAttack() { return atk_; }

/** Sets the envelope time for onset of compression for signals above the threshold.
\param attack Expects 0.001 -> 10
*/
void SetAttack(float attack)
{
atk_ = attack;
RecalculateAttack();
}

/** Gets the envelope time for release of compression */
float GetRelease() { return rel_; }

/** Sets the envelope time for release of compression as input signal falls below threshold.
\param release Expects 0.001 -> 10
*/
void SetRelease(float release)
{
rel_ = release;
RecalculateRelease();
}

/** Gets the additional gain to make up for the compression */
float GetMakeup() { return makeup_gain_; }

/** Manually sets the additional gain to make up for the compression
\param gain Expects 0.0 -> 80
*/
void SetMakeup(float gain) { makeup_gain_ = gain; }

/** Enables or disables the automatic makeup gain. Disabling sets the makeup gain to 0.0
\param enable true to enable, false to disable
*/
void AutoMakeup(bool enable)
{
makeup_auto_ = enable;
makeup_gain_ = 0.0f;
RecalculateMakeup();
}

/** Gets the gain reduction in dB
*/
float GetGain() { return fastlog10f(gain_) * 20.0f; }

private:
float ratio_, thresh_, atk_, rel_;
float makeup_gain_;
float gain_;

// Recorded slope and gain, used in next sample
float slope_rec_, gain_rec_;

// Internals from faust
float atk_slo2_, ratio_mul_, atk_slo_, rel_slo_;

int sample_rate_;
float sample_rate_inv2_, sample_rate_inv_;

// Auto makeup gain enable
bool makeup_auto_;

// Methods for recalculating internals
void RecalculateRatio()
{
ratio_mul_ = ((1.0f - atk_slo2_) * ((1.0f / ratio_) - 1.0f));
}

void RecalculateAttack()
{
atk_slo_ = expf(-(sample_rate_inv_ / atk_));
atk_slo2_ = expf(-(sample_rate_inv2_ / atk_));

RecalculateRatio();
}

void RecalculateRelease() { rel_slo_ = expf((-(sample_rate_inv_ / rel_))); }

void RecalculateMakeup()
{
if(makeup_auto_)
makeup_gain_ = fabsf(thresh_ - thresh_ / ratio_) * 0.5f;
}
};

} // namespace daisysp

#endif // DSY_COMPRESSOR_H
Loading

0 comments on commit 829535a

Please sign in to comment.