ref: a53b433420d35a54180c76421b082031a8b35204
parent: f42ea7f0f61c638d45eaa92782798c69f0d7b86c
author: Matthew Wang <Matthew@nat-oitwireless-inside-vapornet100-10-8-1-203.princeton.edu>
date: Mon Dec 2 10:56:59 EST 2019
updated all object with new internal structure so that everything goes in the mempool
binary files a/.DS_Store b/.DS_Store differ
binary files a/LEAF/.DS_Store b/LEAF/.DS_Store differ
--- a/LEAF/Externals/atkdetect.c
+++ /dev/null
@@ -1,130 +1,0 @@
-#include "atkdetect.h"
-
-#include <stdlib.h>
-
-/********Private function prototypes**********/
-static void atkDetect_init(t_atkDetect *a, int blocksize, int atk, int rel);
-static void atkDetect_envelope(t_atkDetect *a, t_float *in);
-
-/********Constructor/Destructor***************/
-
-t_atkDetect *atkDetect_new(int blocksize)
-{
- t_atkDetect *a = NULL;
- a = (t_atkDetect*)malloc(sizeof(t_atkDetect));
-
- atkDetect_init(a, blocksize, DEFATTACK, DEFRELEASE);
- return (a);
-
-}
-
-t_atkDetect *atkDetect_new_expanded(int blocksize, int atk, int rel)
-{
- t_atkDetect *a = NULL;
- a = (t_atkDetect*)malloc(sizeof(t_atkDetect));
-
- atkDetect_init(a, blocksize, atk, rel);
- return (a);
-
-}
-
-void atkDetect_free(t_atkDetect *a)
-{
- free(a);
-}
-
-/*******Public Functions***********/
-
-
-void atkDetect_set_blocksize(t_atkDetect *a, int size)
-{
-
- if(!((size==64)|(size==128)|(size==256)|(size==512)|(size==1024)|(size==2048)))
- size = DEFBLOCKSIZE;
- a->blocksize = size;
-
- return;
-
-}
-
-void atkDetect_set_samplerate(t_atkDetect *a, int inRate)
-{
- a->samplerate = inRate;
-
- //Reset atk and rel to recalculate coeff
- atkDetect_set_atk(a, a->atk);
- atkDetect_set_rel(a, a->rel);
-
- return;
-}
-
-void atkDetect_set_threshold(t_atkDetect *a, t_float thres)
-{
- a->threshold = thres;
- return;
-}
-
-void atkDetect_set_atk(t_atkDetect *a, int inAtk)
-{
- a->atk = inAtk;
- a->atk_coeff = pow(0.01, 1.0/(a->atk * a->samplerate * 0.001));
-
- return;
-}
-
-void atkDetect_set_rel(t_atkDetect *a, int inRel)
-{
- a->rel = inRel;
- a->rel_coeff = pow(0.01, 1.0/(a->rel * a->samplerate * 0.001));
-
- return;
-}
-
-
-int atkDetect_detect(t_atkDetect *a, t_float *in)
-{
- int result;
-
- atkDetect_envelope(a, in);
-
- if(a->env >= a->prevAmp*2) //2 times greater = 6dB increase
- result = 1;
- else
- result = 0;
-
- a->prevAmp = a->env;
-
- return result;
-
-}
-
-/*******Private Functions**********/
-
-static void atkDetect_init(t_atkDetect *a, int blocksize, int atk, int rel)
-{
- a->env = 0;
- a->blocksize = blocksize;
- a->threshold = DEFTHRESHOLD;
- a->samplerate = DEFSAMPLERATE;
- a->prevAmp = 0;
-
- a->env = 0;
-
- atkDetect_set_atk(a, atk);
- atkDetect_set_rel(a, rel);
-}
-
-static void atkDetect_envelope(t_atkDetect *a, t_float *in)
-{
- int i = 0;
- t_float tmp;
- for(i = 0; i < a->blocksize; ++i){
- tmp = fastabs(in[i]);
-
- if(tmp > a->env)
- a->env = a->atk_coeff * (a->env - tmp) + tmp;
- else
- a->env = a->rel_coeff * (a->env - tmp) + tmp;
- }
-
-}
--- a/LEAF/Externals/atkdetect.h
+++ /dev/null
@@ -1,107 +1,0 @@
-#ifndef atkdetect_h
-#define atkdetect_h
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*************************************
-
-atkdetect lib written for DSP2G project
-Original author: Kenny Carlsen (kcarlsen@umich.edu)
-
-Source: http://www.musicdsp.org/showArchiveComment.php?ArchiveID=136
-
-Implements a simple attack detector using envelope detection
-Designed to be fed into the solad library used in DPS2G for
-the purpose of reducing latency while time domain pitch shifting.
-
-Function atkDetect_new() is a constructor. It returns a pointer which is
-needed in all other external calls to lib atkdetect functions
-
-Function atkDetect_free() is a destructor. This function should be called
-to deallocate all memory used by atkDetect instance.
-
-Function atkDetect_set_blocksize() changes the analysis block size. Valid sizes are 128,
-256, 512, 1024, and 2048. Default size is 1024.
-
-Function atkDetect_set_samplerate() changes the sample rate of the attack detector and thus
-the attack and release coefficients of the envelope detector. Default rate is 44100
-
-Function atkDetect_set_threshold() sets the RMS level a frame must exceed (over the previous frame)
-to be detected as an attack (example: frame 2 is an 'attack' if RMS(frame2) > RMS(frame1)*2)
-Default value is 6dB RMS (or a doubling of the amplitude)
-
-Functions atkDetect_set_atk/rel() set the attack/release values in msec and calculate the atk/rel coefficients
-for the envelope detector. Default value is 10 msec.
-
-Function atkDetect_detect() evaluates the RMS level of the input signal and determines if an attack
-exists in the given frame
-
-****************************************
-version 0.2 June 2017
-
-***************************************/
-
-#include <string.h>
-#include <math.h>
-
-#define DEFSAMPLERATE 44100
-#define DEFBLOCKSIZE 1024
-#define DEFTHRESHOLD 6
-#define DEFATTACK 10
-#define DEFRELEASE 10
-
-#define t_float float
-
-
-typedef struct t_atkDetect
-{
- t_float env;
-
- //Attack & Release times in msec
- int atk;
- int rel;
-
- //Attack & Release coefficients based on times
- t_float atk_coeff;
- t_float rel_coeff;
-
- int blocksize;
- int samplerate;
-
- //RMS amplitude of previous block - used to decide if attack is present
- t_float prevAmp;
-
- t_float threshold;
-}t_atkDetect;
-
-t_atkDetect *atkDetect_new(int blocksize);
-
-t_atkDetect *atkDetect_new_expanded(int blocksize, int atk, int rel);
-
-void atkDetect_free(t_atkDetect *a);
-
-// set expected input blocksize
-void atkDetect_set_blocksize(t_atkDetect *a, int size);
-
-// change atkDetector sample rate
-void atkDetect_set_samplerate(t_atkDetect *a, int inRate);
-
-// set attack time and coeff
-void atkDetect_set_atk(t_atkDetect *a, int inAtk);
-
-// set release time and coeff
-void atkDetect_set_rel(t_atkDetect *a, int inRel);
-
-// set level above which values are identified as attacks
-void atkDetect_set_threshold(t_atkDetect *a, t_float thres);
-
-// find largest transient in input block, return index of attack
-int atkDetect_detect(t_atkDetect *a, t_float *in);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
--- a/LEAF/Externals/d_fft_mayer.c
+++ b/LEAF/Externals/d_fft_mayer.c
@@ -398,7 +398,7 @@
void mayer_realfft(int n, REAL *real)
{
- REAL a,b,c,d;
+ REAL a,b;
int i,j,k;
mayer_fht(real,n);
for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
@@ -411,7 +411,7 @@
void mayer_realifft(int n, REAL *real)
{
- REAL a,b,c,d;
+ REAL a,b;
int i,j,k;
for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
a = real[i];
--- a/LEAF/Inc/leaf-analysis.h
+++ b/LEAF/Inc/leaf-analysis.h
@@ -13,163 +13,173 @@
extern "C" {
#endif
-//==============================================================================
+ //==============================================================================
#include "leaf-global.h"
#include "leaf-mempool.h"
#include "leaf-math.h"
#include "leaf-filters.h"
-
-//==============================================================================
-
-/* Envelope Follower */
-typedef struct _tEnvelopeFollower
-{
- float y;
- float a_thresh;
- float d_coeff;
-} tEnvelopeFollower;
-
-void tEnvelopeFollower_init (tEnvelopeFollower* const, float attackThreshold, float decayCoeff);
-void tEnvelopeFollower_free (tEnvelopeFollower* const);
-
-float tEnvelopeFollower_tick (tEnvelopeFollower* const, float x);
-int tEnvelopeFollower_decayCoeff (tEnvelopeFollower* const, float decayCoeff);
-int tEnvelopeFollower_attackThresh (tEnvelopeFollower* const, float attackThresh);
+ //==============================================================================
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-
-/* PowerEnvelopeFollower */
-typedef struct _tPowerFollower {
- float factor, oneminusfactor;
- float curr;
+ /* Envelope Follower */
+ typedef struct _tEnvelopeFollower
+ {
+ float y;
+ float a_thresh;
+ float d_coeff;
+
+ } _tEnvelopeFollower;
-} tPowerFollower;
-
-void tPowerFollower_init (tPowerFollower* const, float factor);
-void tPowerFollower_free (tPowerFollower* const);
-float tPowerFollower_tick (tPowerFollower* const, float input);
-float tPowerFollower_sample (tPowerFollower* const);
-int tPowerFollower_setFactor (tPowerFollower* const, float factor);
-
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-
-// ENV~ from PD, modified for LEAF
+ typedef _tEnvelopeFollower* tEnvelopeFollower;
+
+ void tEnvelopeFollower_init (tEnvelopeFollower* const, float attackThreshold, float decayCoeff);
+ void tEnvelopeFollower_free (tEnvelopeFollower* const);
+
+ float tEnvelopeFollower_tick (tEnvelopeFollower* const, float x);
+ int tEnvelopeFollower_decayCoeff (tEnvelopeFollower* const, float decayCoeff);
+ int tEnvelopeFollower_attackThresh (tEnvelopeFollower* const, float attackThresh);
+
+ // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
+ /* PowerEnvelopeFollower */
+ typedef struct _tPowerFollower {
+ float factor, oneminusfactor;
+ float curr;
+
+ } _tPowerFollower;
+
+ typedef _tPowerFollower* tPowerFollower;
+
+ void tPowerFollower_init (tPowerFollower* const, float factor);
+ void tPowerFollower_free (tPowerFollower* const);
+ float tPowerFollower_tick (tPowerFollower* const, float input);
+ float tPowerFollower_sample (tPowerFollower* const);
+ int tPowerFollower_setFactor (tPowerFollower* const, float factor);
+
+ // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
+ // ENV~ from PD, modified for LEAF
#define MAXOVERLAP 32
#define INITVSTAKEN 64
#define ENV_WINDOW_SIZE 1024
#define ENV_HOP_SIZE 256
-
-typedef struct _tEnvPD
-{
- float buf[ENV_WINDOW_SIZE + INITVSTAKEN];
- uint16_t x_phase; /* number of points since last output */
- uint16_t x_period; /* requested period of output */
- uint16_t x_realperiod; /* period rounded up to vecsize multiple */
- uint16_t x_npoints; /* analysis window size in samples */
- float x_result; /* result to output */
- float x_sumbuf[MAXOVERLAP]; /* summing buffer */
- float x_f;
- uint16_t windowSize, hopSize, blockSize;
- uint16_t x_allocforvs; /* extra buffer for DSP vector size */
-} tEnvPD;
-
-void tEnvPD_init (tEnvPD* const, int windowSize, int hopSize, int blockSize);
-void tEnvPD_free (tEnvPD* const);
-float tEnvPD_tick (tEnvPD* const);
-void tEnvPD_processBlock (tEnvPD* const, float* in);
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-
-/* tAttackDetection */
+ typedef struct _tEnvPD
+ {
+ float buf[ENV_WINDOW_SIZE + INITVSTAKEN];
+ uint16_t x_phase; /* number of points since last output */
+ uint16_t x_period; /* requested period of output */
+ uint16_t x_realperiod; /* period rounded up to vecsize multiple */
+ uint16_t x_npoints; /* analysis window size in samples */
+ float x_result; /* result to output */
+ float x_sumbuf[MAXOVERLAP]; /* summing buffer */
+ float x_f;
+ uint16_t windowSize, hopSize, blockSize;
+ uint16_t x_allocforvs; /* extra buffer for DSP vector size */
+ } _tEnvPD;
+
+ typedef _tEnvPD* tEnvPD;
+
+ void tEnvPD_init (tEnvPD* const, int windowSize, int hopSize, int blockSize);
+ void tEnvPD_free (tEnvPD* const);
+ float tEnvPD_tick (tEnvPD* const);
+ void tEnvPD_processBlock (tEnvPD* const, float* in);
+
+ // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
+ /* tAttackDetection */
#define DEFBLOCKSIZE 1024
#define DEFTHRESHOLD 6
#define DEFATTACK 10
#define DEFRELEASE 10
-
-typedef struct _tAttackDetection
-{
- float env;
- //Attack & Release times in msec
- int atk;
- int rel;
+ typedef struct _tAttackDetection
+ {
+ float env;
+
+ //Attack & Release times in msec
+ int atk;
+ int rel;
+
+ //Attack & Release coefficients based on times
+ float atk_coeff;
+ float rel_coeff;
+
+ int blocksize;
+ int samplerate;
+
+ //RMS amplitude of previous block - used to decide if attack is present
+ float prevAmp;
+
+ float threshold;
+ } _tAttackDetection;
- //Attack & Release coefficients based on times
- float atk_coeff;
- float rel_coeff;
+ typedef _tAttackDetection* tAttackDetection;
- int blocksize;
- int samplerate;
+ void tAttackDetection_init (tAttackDetection* const, int blocksize);
+ void tAttackDetection_init_expanded (tAttackDetection* const, int blocksize, int atk, int rel);
+ void tAttackDetection_free (tAttackDetection* const);
- //RMS amplitude of previous block - used to decide if attack is present
- float prevAmp;
+ // set expected input blocksize
+ void tAttackDetection_setBlocksize (tAttackDetection* const, int size);
- float threshold;
-} tAttackDetection;
-
-void tAttackDetection_init (tAttackDetection* const, int blocksize);
-void tAttackDetection_init_expanded (tAttackDetection* const, int blocksize, int atk, int rel);
-void tAttackDetection_free (tAttackDetection* const);
-
-// set expected input blocksize
-void tAttackDetection_setBlocksize (tAttackDetection* const, int size);
-
-// change atkDetector sample rate
-void tAttackDetection_setSamplerate (tAttackDetection* const, int inRate);
-
-// set attack time and coeff
-void tAttackDetection_setAtk (tAttackDetection* const, int inAtk);
-
-// set release time and coeff
-void tAttackDetection_setRel (tAttackDetection* const, int inRel);
-
-// set level above which values are identified as attacks
-void tAttackDetection_setThreshold (tAttackDetection* const, float thres);
-
-// find largest transient in input block, return index of attack
-int tAttackDetection_detect (tAttackDetection* const, float *in);
-
-//==============================================================================
-
-// tSNAC: period detector
+ // change atkDetector sample rate
+ void tAttackDetection_setSamplerate (tAttackDetection* const, int inRate);
+
+ // set attack time and coeff
+ void tAttackDetection_setAtk (tAttackDetection* const, int inAtk);
+
+ // set release time and coeff
+ void tAttackDetection_setRel (tAttackDetection* const, int inRel);
+
+ // set level above which values are identified as attacks
+ void tAttackDetection_setThreshold (tAttackDetection* const, float thres);
+
+ // find largest transient in input block, return index of attack
+ int tAttackDetection_detect (tAttackDetection* const, float *in);
+
+ //==============================================================================
+
+ // tSNAC: period detector
#define SNAC_FRAME_SIZE 1024 // default analysis framesize // should be the same as (or smaller than?) PS_FRAME_SIZE
#define DEFOVERLAP 1 // default overlap
#define DEFBIAS 0.2f // default bias
#define DEFMINRMS 0.003f // default minimum RMS
#define SEEK 0.85f // seek-length as ratio of framesize
-
-typedef struct _tSNAC
-{
- float* inputbuf;
- float* processbuf;
- float* spectrumbuf;
- float* biasbuf;
- uint16_t timeindex;
- uint16_t framesize;
- uint16_t overlap;
- uint16_t periodindex;
- float periodlength;
- float fidelity;
- float biasfactor;
- float minrms;
+ typedef struct _tSNAC
+ {
+ float* inputbuf;
+ float* processbuf;
+ float* spectrumbuf;
+ float* biasbuf;
+ uint16_t timeindex;
+ uint16_t framesize;
+ uint16_t overlap;
+ uint16_t periodindex;
+
+ float periodlength;
+ float fidelity;
+ float biasfactor;
+ float minrms;
+
+ } _tSNAC;
-} tSNAC;
-
-void tSNAC_init (tSNAC* const, int overlaparg); // constructor
-void tSNAC_free (tSNAC* const); // destructor
-
-void tSNAC_ioSamples (tSNAC *s, float *in, float *out, int size);
-void tSNAC_setOverlap (tSNAC *s, int lap);
-void tSNAC_setBias (tSNAC *s, float bias);
-void tSNAC_setMinRMS (tSNAC *s, float rms);
-
-/*To get freq, perform SAMPLE_RATE/snac_getperiod() */
-float tSNAC_getPeriod (tSNAC *s);
-float tSNAC_getfidelity (tSNAC *s);
+ typedef _tSNAC* tSNAC;
+ void tSNAC_init (tSNAC* const, int overlaparg); // constructor
+ void tSNAC_free (tSNAC* const); // destructor
+
+ void tSNAC_ioSamples (tSNAC *s, float *in, float *out, int size);
+ void tSNAC_setOverlap (tSNAC *s, int lap);
+ void tSNAC_setBias (tSNAC *s, float bias);
+ void tSNAC_setMinRMS (tSNAC *s, float rms);
+
+ /*To get freq, perform SAMPLE_RATE/snac_getperiod() */
+ float tSNAC_getPeriod (tSNAC *s);
+ float tSNAC_getfidelity (tSNAC *s);
+
#define DEFPITCHRATIO 2.0f
#define DEFTIMECONSTANT 100.0f
#define DEFHOPSIZE 64
@@ -177,46 +187,48 @@
#define FBA 20
#define HPFREQ 40.0f
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-// Period detection
-typedef struct _tPeriodDetection
-{
- tEnvPD env;
- tSNAC snac;
- float* inBuffer;
- float* outBuffer;
- int frameSize;
- int bufSize;
- int framesPerBuffer;
- int curBlock;
- int lastBlock;
- int i;
- int indexstore;
- int iLast;
- int index;
- float period;
+ // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+ // Period detection
+ typedef struct _tPeriodDetection
+ {
+ tEnvPD env;
+ tSNAC snac;
+ float* inBuffer;
+ float* outBuffer;
+ int frameSize;
+ int bufSize;
+ int framesPerBuffer;
+ int curBlock;
+ int lastBlock;
+ int i;
+ int indexstore;
+ int iLast;
+ int index;
+ float period;
+
+ uint16_t hopSize;
+ uint16_t windowSize;
+ uint8_t fba;
+
+ float timeConstant;
+ float radius;
+ float max;
+ float lastmax;
+ float deltamax;
+
+ } _tPeriodDetection;
- uint16_t hopSize;
- uint16_t windowSize;
- uint8_t fba;
+ typedef _tPeriodDetection* tPeriodDetection;
- float timeConstant;
- float radius;
- float max;
- float lastmax;
- float deltamax;
+ void tPeriodDetection_init (tPeriodDetection* const, float* in, float* out, int bufSize, int frameSize);
+ void tPeriodDetection_free (tPeriodDetection* const);
-}tPeriodDetection;
-
-void tPeriodDetection_init (tPeriodDetection* const, float* in, float* out, int bufSize, int frameSize);
-void tPeriodDetection_free (tPeriodDetection* const);
-
-float tPeriodDetection_findPeriod (tPeriodDetection* const, float sample);
-void tPeriodDetection_setHopSize (tPeriodDetection* p, int hs);
-void tPeriodDetection_setWindowSize (tPeriodDetection* p, int ws);
-
-//==============================================================================
+ float tPeriodDetection_findPeriod (tPeriodDetection* const, float sample);
+ void tPeriodDetection_setHopSize (tPeriodDetection* p, int hs);
+ void tPeriodDetection_setWindowSize (tPeriodDetection* p, int ws);
+ //==============================================================================
+
#ifdef __cplusplus
}
#endif
@@ -224,3 +236,4 @@
#endif // LEAF_ANALYSIS_H_INCLUDED
//==============================================================================
+
--- a/LEAF/Inc/leaf-delay.h
+++ b/LEAF/Inc/leaf-delay.h
@@ -1,11 +1,11 @@
/*==============================================================================
+
+ leaf-delay.h
+ Created: 20 Jan 2017 12:01:24pm
+ Author: Michael R Mulshine
+
+ ==============================================================================*/
- leaf-delay.h
- Created: 20 Jan 2017 12:01:24pm
- Author: Michael R Mulshine
-
-==============================================================================*/
-
#ifndef LEAF_DELAY_H_INCLUDED
#define LEAF_DELAY_H_INCLUDED
@@ -12,141 +12,149 @@
#ifdef __cplusplus
extern "C" {
#endif
-
-//==============================================================================
+ //==============================================================================
+
#include "leaf-math.h"
-
-//==============================================================================
-/* Non-interpolating delay, reimplemented from STK (Cook and Scavone). */
-typedef struct _tDelay
-{
- float gain;
- float* buff;
+ //==============================================================================
- float lastOut, lastIn;
+ /* Non-interpolating delay, reimplemented from STK (Cook and Scavone). */
+ typedef struct _tDelay
+ {
+ float gain;
+ float* buff;
+
+ float lastOut, lastIn;
+
+ uint32_t inPoint, outPoint;
+
+ uint32_t delay, maxDelay;
+
+ } _tDelay;
- uint32_t inPoint, outPoint;
+ typedef _tDelay* tDelay;
- uint32_t delay, maxDelay;
+ void tDelay_init (tDelay* const, uint32_t delay, uint32_t maxDelay);
+ void tDelay_free (tDelay* const);
-} tDelay;
-
-void tDelay_init (tDelay* const, uint32_t delay, uint32_t maxDelay);
-void tDelay_free (tDelay* const);
-
-int tDelay_setDelay (tDelay* const, uint32_t delay);
-uint32_t tDelay_getDelay (tDelay* const);
-void tDelay_tapIn (tDelay* const, float in, uint32_t tapDelay);
-float tDelay_tapOut (tDelay* const, uint32_t tapDelay);
-float tDelay_addTo (tDelay* const, float value, uint32_t tapDelay);
-float tDelay_tick (tDelay* const, float sample);
-float tDelay_getLastOut (tDelay* const);
-float tDelay_getLastIn (tDelay* const);
-
-//==============================================================================
+ int tDelay_setDelay (tDelay* const, uint32_t delay);
+ uint32_t tDelay_getDelay (tDelay* const);
+ void tDelay_tapIn (tDelay* const, float in, uint32_t tapDelay);
+ float tDelay_tapOut (tDelay* const, uint32_t tapDelay);
+ float tDelay_addTo (tDelay* const, float value, uint32_t tapDelay);
+ float tDelay_tick (tDelay* const, float sample);
+ float tDelay_getLastOut (tDelay* const);
+ float tDelay_getLastIn (tDelay* const);
-/* Linearly-interpolating delay, reimplemented from STK (Cook and Scavone). */
-typedef struct _tLinearDelay
-{
- float gain;
- float* buff;
+ //==============================================================================
- float lastOut, lastIn;
+ /* Linearly-interpolating delay, reimplemented from STK (Cook and Scavone). */
+ typedef struct _tLinearDelay
+ {
+ float gain;
+ float* buff;
+
+ float lastOut, lastIn;
+
+ uint32_t inPoint, outPoint;
+
+ uint32_t maxDelay;
+
+ float delay;
+
+ float alpha, omAlpha;
+
+ } _tLinearDelay;
- uint32_t inPoint, outPoint;
+ typedef _tLinearDelay* tLinearDelay;
- uint32_t maxDelay;
+ void tLinearDelay_init (tLinearDelay* const, float delay, uint32_t maxDelay);
+ void tLinearDelay_free (tLinearDelay* const);
- float delay;
+ int tLinearDelay_setDelay (tLinearDelay* const, float delay);
+ float tLinearDelay_getDelay (tLinearDelay* const);
+ void tLinearDelay_tapIn (tLinearDelay* const, float in, uint32_t tapDelay);
+ float tLinearDelay_tapOut (tLinearDelay* const, float tapDelay);
+ float tLinearDelay_addTo (tLinearDelay* const, float value, uint32_t tapDelay);
+ float tLinearDelay_tick (tLinearDelay* const, float sample);
+ void tLinearDelay_tickIn (tLinearDelay* const, float input);
+ float tLinearDelay_tickOut (tLinearDelay* const);
+ float tLinearDelay_getLastOut (tLinearDelay* const);
+ float tLinearDelay_getLastIn (tLinearDelay* const);
- float alpha, omAlpha;
+ //==============================================================================
-} tLinearDelay;
-
-void tLinearDelay_init (tLinearDelay* const, float delay, uint32_t maxDelay);
-void tLinearDelay_free (tLinearDelay* const);
-
-int tLinearDelay_setDelay (tLinearDelay* const, float delay);
-float tLinearDelay_getDelay (tLinearDelay* const);
-void tLinearDelay_tapIn (tLinearDelay* const, float in, uint32_t tapDelay);
-float tLinearDelay_tapOut (tLinearDelay* const, float tapDelay);
-float tLinearDelay_addTo (tLinearDelay* const, float value, uint32_t tapDelay);
-float tLinearDelay_tick (tLinearDelay* const, float sample);
-void tLinearDelay_tickIn (tLinearDelay* const d, float input);
-float tLinearDelay_tickOut (tLinearDelay* const d);
-float tLinearDelay_getLastOut (tLinearDelay* const);
-float tLinearDelay_getLastIn (tLinearDelay* const);
-
-//==============================================================================
+ /* Allpass-interpolating delay, reimplemented from STK (Cook and Scavone). */
+ typedef struct _tAllpassDelay
+ {
+ float gain;
+ float* buff;
+
+ float lastOut, lastIn;
+
+ uint32_t inPoint, outPoint;
+
+ uint32_t maxDelay;
+
+ float delay;
+
+ float alpha, omAlpha, coeff;
+
+ float apInput;
+
+ } _tAllpassDelay;
-/* Allpass-interpolating delay, reimplemented from STK (Cook and Scavone). */
-typedef struct _tAllpassDelay
-{
- float gain;
- float* buff;
+ typedef _tAllpassDelay* tAllpassDelay;
- float lastOut, lastIn;
+ void tAllpassDelay_init (tAllpassDelay* const, float delay, uint32_t maxDelay);
+ void tAllpassDelay_free (tAllpassDelay* const);
- uint32_t inPoint, outPoint;
+ int tAllpassDelay_setDelay (tAllpassDelay* const, float delay);
+ float tAllpassDelay_getDelay (tAllpassDelay* const);
+ void tAllpassDelay_tapIn (tAllpassDelay* const, float in, uint32_t tapDelay);
+ float tAllpassDelay_tapOut (tAllpassDelay* const, uint32_t tapDelay);
+ float tAllpassDelay_addTo (tAllpassDelay* const, float value, uint32_t tapDelay);
+ float tAllpassDelay_tick (tAllpassDelay* const, float sample);
+ float tAllpassDelay_getLastOut (tAllpassDelay* const);
+ float tAllpassDelay_getLastIn (tAllpassDelay* const);
- uint32_t maxDelay;
+ //==============================================================================
- float delay;
+ /* Linear interpolating delay with fixed read and write pointers, variable rate. */
+ typedef struct _tTapeDelay
+ {
+ float gain;
+ float* buff;
+
+ float lastOut, lastIn;
+
+ uint32_t inPoint;
+
+ uint32_t maxDelay;
+
+ float delay, inc, idx;
+
+ float apInput;
+
+ } _tTapeDelay;
- float alpha, omAlpha, coeff;
+ typedef _tTapeDelay* tTapeDelay;
- float apInput;
+ void tTapeDelay_init (tTapeDelay* const, float delay, uint32_t maxDelay);
+ void tTapeDelay_free (tTapeDelay* const);
-} tAllpassDelay;
-
-void tAllpassDelay_init (tAllpassDelay* const, float delay, uint32_t maxDelay);
-void tAllpassDelay_free (tAllpassDelay* const);
-
-int tAllpassDelay_setDelay (tAllpassDelay* const, float delay);
-float tAllpassDelay_getDelay (tAllpassDelay* const);
-void tAllpassDelay_tapIn (tAllpassDelay* const, float in, uint32_t tapDelay);
-float tAllpassDelay_tapOut (tAllpassDelay* const, uint32_t tapDelay);
-float tAllpassDelay_addTo (tAllpassDelay* const, float value, uint32_t tapDelay);
-float tAllpassDelay_tick (tAllpassDelay* const, float sample);
-float tAllpassDelay_getLastOut (tAllpassDelay* const);
-float tAllpassDelay_getLastIn (tAllpassDelay* const);
-
-//==============================================================================
+ void tTapeDelay_setDelay (tTapeDelay* const, float delay);
+ float tTapeDelay_getDelay (tTapeDelay* const);
+ void tTapeDelay_tapIn (tTapeDelay* const, float in, uint32_t tapDelay);
+ float tTapeDelay_tapOut (tTapeDelay* const d, float tapDelay);
+ float tTapeDelay_addTo (tTapeDelay* const, float value, uint32_t tapDelay);
+ float tTapeDelay_tick (tTapeDelay* const, float sample);
+ float tTapeDelay_getLastOut (tTapeDelay* const);
+ float tTapeDelay_getLastIn (tTapeDelay* const);
-/* Linear interpolating delay with fixed read and write pointers, variable rate. */
-typedef struct _tTapeDelay
-{
- float gain;
- float* buff;
+ //==============================================================================
- float lastOut, lastIn;
-
- uint32_t inPoint;
-
- uint32_t maxDelay;
-
- float delay, inc, idx;
-
- float apInput;
-
-} tTapeDelay;
-
-void tTapeDelay_init (tTapeDelay* const, float delay, uint32_t maxDelay);
-void tTapeDelay_free (tTapeDelay* const);
-
-int tTapeDelay_setDelay (tTapeDelay* const, float delay);
-float tTapeDelay_getDelay (tTapeDelay* const);
-void tTapeDelay_tapIn (tTapeDelay* const, float in, uint32_t tapDelay);
-float tTapeDelay_tapOut (tTapeDelay* const d, float tapDelay);
-float tTapeDelay_addTo (tTapeDelay* const, float value, uint32_t tapDelay);
-float tTapeDelay_tick (tTapeDelay* const, float sample);
-float tTapeDelay_getLastOut (tTapeDelay* const);
-float tTapeDelay_getLastIn (tTapeDelay* const);
-
-//==============================================================================
-
#ifdef __cplusplus
}
#endif
@@ -154,3 +162,4 @@
#endif // LEAF_DELAY_H_INCLUDED
//==============================================================================
+
--- a/LEAF/Inc/leaf-distortion.h
+++ b/LEAF/Inc/leaf-distortion.h
@@ -1,11 +1,11 @@
/*==============================================================================
+
+ leaf-distortion.h
+ Created: 25 Oct 2019 10:23:28am
+ Author: Matthew Wang
+
+ ==============================================================================*/
- leaf-distortion.h
- Created: 25 Oct 2019 10:23:28am
- Author: Matthew Wang
-
-==============================================================================*/
-
#ifndef LEAF_DISTORTION_H_INCLUDED
#define LEAF_DISTORTION_H_INCLUDED
@@ -12,83 +12,88 @@
#ifdef __cplusplus
extern "C" {
#endif
-
-//==============================================================================
+ //==============================================================================
+
#include "leaf-global.h"
#include "leaf-mempool.h"
#include "leaf-math.h"
-
-//==============================================================================
-/* tLockhartWavefolder */
-
-typedef struct _tLockhartWavefolder
-{
- double Ln1;
- double Fn1;
- float xn1;
+ //==============================================================================
-} tLockhartWavefolder;
-
-void tLockhartWavefolder_init (tLockhartWavefolder* const);
-void tLockhartWavefolder_free (tLockhartWavefolder* const);
-
-float tLockhartWavefolder_tick (tLockhartWavefolder* const, float samp);
-
-//==============================================================================
+ /* tLockhartWavefolder */
-typedef struct _tCrusher
-{
- float srr;
- float mult, div;
- float rnd;
+ typedef struct _tLockhartWavefolder
+ {
+ double Ln1;
+ double Fn1;
+ float xn1;
+
+ } _tLockhartWavefolder;
- uint32_t op; //which bitwise operation (0-7)
+ typedef _tLockhartWavefolder* tLockhartWavefolder;
- float gain;
+ void tLockhartWavefolder_init (tLockhartWavefolder* const);
+ void tLockhartWavefolder_free (tLockhartWavefolder* const);
-} tCrusher;
-
-
-void tCrusher_init (tCrusher* const);
-void tCrusher_free (tCrusher* const);
-
-float tCrusher_tick (tCrusher* const, float input);
-
-// 0.0 - 1.0
-void tCrusher_setOperation (tCrusher* const, float op);
-
-// 0.0 - 1.0
-void tCrusher_setQuality (tCrusher* const, float val);
-
-// what division to round to
-void tCrusher_setRound (tCrusher* const, float rnd);
-
-// sampling ratio
-void tCrusher_setSamplingRatio (tCrusher* const, float ratio);
+ float tLockhartWavefolder_tick (tLockhartWavefolder* const, float samp);
-//==============================================================================
+ //==============================================================================
-typedef struct _tOversampler
-{
- int ratio;
- float* pCoeffs;
- float* upState;
- float* downState;
- int numTaps;
- int phaseLength;
-} tOversampler;
-
-void tOversampler_init(tOversampler* const, int order, oBool extraQuality);
-void tOversampler_free(tOversampler* const);
-void tOversampler_upsample(tOversampler* const, float input, float* output);
-float tOversampler_downsample(tOversampler *const os, float* input);
-float tOversampler_tick(tOversampler* const, float input, float (*effectTick)(float));
-int tOversampler_getLatency(tOversampler* const os);
-
-//==============================================================================
+ typedef struct _tCrusher
+ {
+ float srr;
+ float mult, div;
+ float rnd;
+
+ uint32_t op; //which bitwise operation (0-7)
+
+ float gain;
+
+ } _tCrusher;
+ typedef _tCrusher* tCrusher;
+
+ void tCrusher_init (tCrusher* const);
+ void tCrusher_free (tCrusher* const);
+
+ float tCrusher_tick (tCrusher* const, float input);
+
+ // 0.0 - 1.0
+ void tCrusher_setOperation (tCrusher* const, float op);
+
+ // 0.0 - 1.0
+ void tCrusher_setQuality (tCrusher* const, float val);
+
+ // what division to round to
+ void tCrusher_setRound (tCrusher* const, float rnd);
+
+ // sampling ratio
+ void tCrusher_setSamplingRatio (tCrusher* const, float ratio);
+
+ //==============================================================================
+
+ typedef struct _tOversampler
+ {
+ int ratio;
+ float* pCoeffs;
+ float* upState;
+ float* downState;
+ int numTaps;
+ int phaseLength;
+ } _tOversampler;
+
+ typedef _tOversampler* tOversampler;
+
+ void tOversampler_init(tOversampler* const, int order, oBool extraQuality);
+ void tOversampler_free(tOversampler* const);
+ void tOversampler_upsample(tOversampler* const, float input, float* output);
+ float tOversampler_downsample(tOversampler* const os, float* input);
+ float tOversampler_tick(tOversampler* const, float input, float (*effectTick)(float));
+ int tOversampler_getLatency(tOversampler* const os);
+
+ //==============================================================================
+
#ifdef __cplusplus
}
#endif
@@ -96,4 +101,5 @@
#endif // LEAF_DISTORTION_H_INCLUDED
//==============================================================================
+
--- a/LEAF/Inc/leaf-dynamics.h
+++ b/LEAF/Inc/leaf-dynamics.h
@@ -1,11 +1,11 @@
/*==============================================================================
+
+ leaf-dynamics.h
+ Created: 30 Nov 2018 11:57:05am
+ Author: airship
+
+ ==============================================================================*/
- leaf-dynamics.h
- Created: 30 Nov 2018 11:57:05am
- Author: airship
-
-==============================================================================*/
-
#ifndef LEAF_DYNAMICS_H_INCLUDED
#define LEAF_DYNAMICS_H_INCLUDED
@@ -13,63 +13,67 @@
#ifdef __cplusplus
extern "C" {
#endif
-
-//==============================================================================
-
+
+ //==============================================================================
+
#include "leaf-global.h"
#include "leaf-math.h"
#include "leaf-analysis.h"
-
-//==============================================================================
-
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-
-/* Compressor */
-typedef struct _tCompressor
-{
- float tauAttack, tauRelease;
- float T, R, W, M; // Threshold, compression Ratio, decibel Width of knee transition, decibel Make-up gain
- float x_G[2], y_G[2], x_T[2], y_T[2];
+ //==============================================================================
- oBool isActive;
+ // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-}tCompressor;
-
-void tCompressor_init (tCompressor* const);
-void tCompressor_free (tCompressor* const);
-float tCompressor_tick (tCompressor* const, float input);
+ /* Compressor */
+ typedef struct _tCompressor
+ {
+ float tauAttack, tauRelease;
+ float T, R, W, M; // Threshold, compression Ratio, decibel Width of knee transition, decibel Make-up gain
+
+ float x_G[2], y_G[2], x_T[2], y_T[2];
+
+ oBool isActive;
+
+ } _tCompressor;
-///
-/* Feedback leveller */
-// An auto VCA that you put into a feedback circuit to make it stay at the same level.
-// It can enforce level bidirectionally (amplifying and attenuating as needed) or
-// just attenutating. The former option allows for infinite sustain strings, for example, while
-// The latter option allows for decaying strings, which can never exceed
-// a specific level.
-
-typedef struct _tFeedbackLeveler {
- float targetLevel; // target power level
- float strength; // how strongly level difference affects the VCA
- int mode; // 0 for upwards limiting only, 1 for biderctional limiting
- float curr;
- tPowerFollower pwrFlw; // internal power follower needed for level tracking
+ typedef _tCompressor* tCompressor;
-} tFeedbackLeveler;
-
-void tFeedbackLeveler_init (tFeedbackLeveler* const, float targetLevel, float factor, float strength, int mode);
-void tFeedbackLeveler_free (tFeedbackLeveler* const);
-
-float tFeedbackLeveler_tick (tFeedbackLeveler* const, float input);
-float tFeedbackLeveler_sample (tFeedbackLeveler* const);
-void tFeedbackLeveler_setTargetLevel (tFeedbackLeveler* const, float TargetLevel);
-void tFeedbackLeveler_setFactor (tFeedbackLeveler* const, float factor);
-void tFeedbackLeveler_setMode (tFeedbackLeveler* const, int mode); // 0 for upwards limiting only, 1 for biderctional limiting
-void tFeedbackLeveler_setStrength (tFeedbackLeveler* const, float strength);
-
+ void tCompressor_init (tCompressor* const);
+ void tCompressor_free (tCompressor* const);
+ float tCompressor_tick (tCompressor* const, float input);
-//==============================================================================
+ ///
+ /* Feedback leveller */
+ // An auto VCA that you put into a feedback circuit to make it stay at the same level.
+ // It can enforce level bidirectionally (amplifying and attenuating as needed) or
+ // just attenutating. The former option allows for infinite sustain strings, for example, while
+ // The latter option allows for decaying strings, which can never exceed
+ // a specific level.
+ typedef struct _tFeedbackLeveler {
+ float targetLevel; // target power level
+ float strength; // how strongly level difference affects the VCA
+ int mode; // 0 for upwards limiting only, 1 for biderctional limiting
+ float curr;
+ tPowerFollower pwrFlw; // internal power follower needed for level tracking
+
+ } _tFeedbackLeveler;
+
+ typedef _tFeedbackLeveler* tFeedbackLeveler;
+
+ void tFeedbackLeveler_init (tFeedbackLeveler* const, float targetLevel, float factor, float strength, int mode);
+ void tFeedbackLeveler_free (tFeedbackLeveler* const);
+
+ float tFeedbackLeveler_tick (tFeedbackLeveler* const, float input);
+ float tFeedbackLeveler_sample (tFeedbackLeveler* const);
+ void tFeedbackLeveler_setTargetLevel (tFeedbackLeveler* const, float TargetLevel);
+ void tFeedbackLeveler_setFactor (tFeedbackLeveler* const, float factor);
+ void tFeedbackLeveler_setMode (tFeedbackLeveler* const, int mode); // 0 for upwards limiting only, 1 for biderctional limiting
+ void tFeedbackLeveler_setStrength (tFeedbackLeveler* const, float strength);
+
+
+ //==============================================================================
+
#ifdef __cplusplus
}
#endif
@@ -77,3 +81,4 @@
#endif // LEAF_DYNAMICS_H_INCLUDED
//==============================================================================
+
--- a/LEAF/Inc/leaf-effects.h
+++ b/LEAF/Inc/leaf-effects.h
@@ -1,11 +1,11 @@
/*==============================================================================
+
+ leaf-effects.h
+ Created: 20 Jan 2017 12:01:54pm
+ Author: Michael R Mulshine
+
+ ==============================================================================*/
- leaf-effects.h
- Created: 20 Jan 2017 12:01:54pm
- Author: Michael R Mulshine
-
-==============================================================================*/
-
#ifndef LEAF_EFFECTS_H_INCLUDED
#define LEAF_EFFECTS_H_INCLUDED
@@ -12,81 +12,85 @@
#ifdef __cplusplus
extern "C" {
#endif
-
-//==============================================================================
-
+
+ //==============================================================================
+
#include "leaf-global.h"
#include "leaf-math.h"
#include "leaf-analysis.h"
-
-//==============================================================================
-
-/* tTalkbox */
+
+ //==============================================================================
+
+ /* tTalkbox */
#define NUM_TALKBOX_PARAM 4
-
-typedef struct _tTalkbox
-{
- float param[NUM_TALKBOX_PARAM];
- int bufsize;
- float* car0;
- float* car1;
- float* window;
- float* buf0;
- float* buf1;
+ typedef struct _tTalkbox
+ {
+ float param[NUM_TALKBOX_PARAM];
+
+ int bufsize;
+ float* car0;
+ float* car1;
+ float* window;
+ float* buf0;
+ float* buf1;
+
+ float emphasis;
+ int32_t K, N, O, pos;
+ float wet, dry, FX;
+ float d0, d1, d2, d3, d4;
+ float u0, u1, u2, u3, u4;
+
+ } _tTalkbox;
- float emphasis;
- int32_t K, N, O, pos;
- float wet, dry, FX;
- float d0, d1, d2, d3, d4;
- float u0, u1, u2, u3, u4;
+ typedef _tTalkbox* tTalkbox;
-} tTalkbox;
-
-void tTalkbox_init (tTalkbox* const, int bufsize);
-void tTalkbox_free (tTalkbox* const);
-float tTalkbox_tick (tTalkbox* const, float synth, float voice);
-void tTalkbox_update (tTalkbox* const);
-void tTalkbox_suspend (tTalkbox* const);
-void tTalkbox_lpcDurbin (float *r, int p, float *k, float *g);
-void tTalkbox_lpc (float *buf, float *car, int32_t n, int32_t o);
-void tTalkbox_setQuality (tTalkbox* const, float quality);
-
-//==============================================================================
-
-/* tVocoder */
+ void tTalkbox_init (tTalkbox* const, int bufsize);
+ void tTalkbox_free (tTalkbox* const);
+ float tTalkbox_tick (tTalkbox* const, float synth, float voice);
+ void tTalkbox_update (tTalkbox* const);
+ void tTalkbox_suspend (tTalkbox* const);
+ void tTalkbox_lpcDurbin (float *r, int p, float *k, float *g);
+ void tTalkbox_lpc (float *buf, float *car, int32_t n, int32_t o);
+ void tTalkbox_setQuality (tTalkbox* const, float quality);
+
+ //==============================================================================
+
+ /* tVocoder */
#define NUM_VOCODER_PARAM 8
#define NBANDS 16
-
-typedef struct _tVocoder
-{
- float param[NUM_VOCODER_PARAM];
- float gain; //output level
- float thru, high; //hf thru
- float kout; //downsampled output
- int32_t kval; //downsample counter
- int32_t nbnd; //number of bands
+ typedef struct _tVocoder
+ {
+ float param[NUM_VOCODER_PARAM];
+
+ float gain; //output level
+ float thru, high; //hf thru
+ float kout; //downsampled output
+ int32_t kval; //downsample counter
+ int32_t nbnd; //number of bands
+
+ //filter coeffs and buffers - seems it's faster to leave this global than make local copy
+ float f[NBANDS][13]; //[0-8][0 1 2 | 0 1 2 3 | 0 1 2 3 | val rate]
+
+ } _tVocoder;
- //filter coeffs and buffers - seems it's faster to leave this global than make local copy
- float f[NBANDS][13]; //[0-8][0 1 2 | 0 1 2 3 | 0 1 2 3 | val rate]
+ typedef _tVocoder* tVocoder;
-} tVocoder;
-
-void tVocoder_init (tVocoder* const);
-void tVocoder_free (tVocoder* const);
-float tVocoder_tick (tVocoder* const, float synth, float voice);
-void tVocoder_update (tVocoder* const);
-void tVocoder_suspend (tVocoder* const);
+ void tVocoder_init (tVocoder* const);
+ void tVocoder_free (tVocoder* const);
+ float tVocoder_tick (tVocoder* const, float synth, float voice);
+ void tVocoder_update (tVocoder* const);
+ void tVocoder_suspend (tVocoder* const);
-//==============================================================================
-
-
-//==============================================================================
-
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-
-/* tSOLAD : pitch shifting algorithm that underlies tRetune etc */
+ //==============================================================================
+
+
+ //==============================================================================
+
+ // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
+ /* tSOLAD : pitch shifting algorithm that underlies tRetune etc */
#define LOOPSIZE (2048*2) // (4096*2) // loop size must be power of two
#define LOOPMASK (LOOPSIZE - 1)
#define PITCHFACTORDEFAULT 1.0f
@@ -93,183 +97,193 @@
#define INITPERIOD 64.0f
#define MAXPERIOD (float)((LOOPSIZE - w->blocksize) * 0.8f)
#define MINPERIOD 8.0f
-
-typedef struct _tSOLAD
-{
- uint16_t timeindex; // current reference time, write index
- uint16_t blocksize; // signal input / output block size
- float pitchfactor; // pitch factor between 0.25 and 4
- float readlag; // read pointer's lag behind write pointer
- float period; // period length in input signal
- float jump; // read pointer jump length and direction
- float xfadelength; // crossfade length expressed at input sample rate
- float xfadevalue; // crossfade phase and value
+
+ typedef struct _tSOLAD
+ {
+ uint16_t timeindex; // current reference time, write index
+ uint16_t blocksize; // signal input / output block size
+ float pitchfactor; // pitch factor between 0.25 and 4
+ float readlag; // read pointer's lag behind write pointer
+ float period; // period length in input signal
+ float jump; // read pointer jump length and direction
+ float xfadelength; // crossfade length expressed at input sample rate
+ float xfadevalue; // crossfade phase and value
+
+ float* delaybuf;
+
+ } _tSOLAD;
- float* delaybuf;
+ typedef _tSOLAD* tSOLAD;
-} tSOLAD;
-
-void tSOLAD_init (tSOLAD* const);
-void tSOLAD_free (tSOLAD* const);
-// send one block of input samples, receive one block of output samples
-void tSOLAD_ioSamples (tSOLAD *w, float* in, float* out, int blocksize);
-// set periodicity analysis data
-void tSOLAD_setPeriod (tSOLAD *w, float period);
-// set pitch factor between 0.25 and 4
-void tSOLAD_setPitchFactor (tSOLAD *w, float pitchfactor);
-// force readpointer lag
-void tSOLAD_setReadLag (tSOLAD *w, float readlag);
-// reset state variables
-void tSOLAD_resetState (tSOLAD *w);
+ void tSOLAD_init (tSOLAD* const);
+ void tSOLAD_free (tSOLAD* const);
+ // send one block of input samples, receive one block of output samples
+ void tSOLAD_ioSamples (tSOLAD *w, float* in, float* out, int blocksize);
+ // set periodicity analysis data
+ void tSOLAD_setPeriod (tSOLAD *w, float period);
+ // set pitch factor between 0.25 and 4
+ void tSOLAD_setPitchFactor (tSOLAD *w, float pitchfactor);
+ // force readpointer lag
+ void tSOLAD_setReadLag (tSOLAD *w, float readlag);
+ // reset state variables
+ void tSOLAD_resetState (tSOLAD *w);
-// Pitch shift
-typedef struct _tPitchShift
-{
- tSOLAD sola;
- tHighpass hp;
- tPeriodDetection* p;
+ // Pitch shift
+ typedef struct _tPitchShift
+ {
+ tSOLAD sola;
+ tHighpass hp;
+ tPeriodDetection* p;
+
+ float* outBuffer;
+ int frameSize;
+ int bufSize;
+
+ int framesPerBuffer;
+ int curBlock;
+ int lastBlock;
+ int index;
+
+ float pitchFactor;
+ float timeConstant;
+ float radius;
+ } _tPitchShift;
- float* outBuffer;
- int frameSize;
- int bufSize;
+ typedef _tPitchShift* tPitchShift;
- int framesPerBuffer;
- int curBlock;
- int lastBlock;
- int index;
+ void tPitchShift_init (tPitchShift* const, tPeriodDetection* const, float* out, int bufSize);
+ void tPitchShift_free (tPitchShift* const);
+ float tPitchShift_shift (tPitchShift* const);
+ float tPitchShift_shiftToFunc (tPitchShift* const, float (*fun)(float));
+ float tPitchShift_shiftToFreq (tPitchShift* const, float freq);
+ void tPitchShift_setPitchFactor (tPitchShift* const, float pf);
- float pitchFactor;
- float timeConstant;
- float radius;
-} tPitchShift;
-
-void tPitchShift_init (tPitchShift* const, tPeriodDetection* const, float* out, int bufSize);
-void tPitchShift_free (tPitchShift* const);
-float tPitchShift_shift (tPitchShift* const);
-float tPitchShift_shiftToFunc (tPitchShift* const, float (*fun)(float));
-float tPitchShift_shiftToFreq (tPitchShift* const, float freq);
-void tPitchShift_setPitchFactor (tPitchShift* const, float pf);
+ // Retune
+ typedef struct _tRetune
+ {
+ tPeriodDetection pd;
+ tPitchShift* ps;
+
+ float* inBuffer;
+ float** outBuffers;
+ float* tickOutput;
+ int frameSize;
+ int bufSize;
+
+ uint16_t hopSize;
+ uint16_t windowSize;
+ uint8_t fba;
+
+ float* pitchFactor;
+ float timeConstant;
+ float radius;
+
+ float inputPeriod;
+
+ int numVoices;
+ } _tRetune;
-// Retune
-typedef struct _tRetune
-{
- tPeriodDetection pd;
- tPitchShift* ps;
+ typedef _tRetune* tRetune;
- float* inBuffer;
- float** outBuffers;
- float* tickOutput;
- int frameSize;
- int bufSize;
+ void tRetune_init (tRetune* const, int numVoices, int bufSize, int frameSize);
+ void tRetune_free (tRetune* const);
- uint16_t hopSize;
- uint16_t windowSize;
- uint8_t fba;
+ float* tRetune_tick (tRetune* const, float sample);
+ void tRetune_setNumVoices (tRetune* const, int numVoices);
+ void tRetune_setPitchFactors (tRetune* const, float pf);
+ void tRetune_setPitchFactor (tRetune* const, float pf, int voice);
+ void tRetune_setTimeConstant (tRetune* const, float tc);
+ void tRetune_setHopSize (tRetune* const, int hs);
+ void tRetune_setWindowSize (tRetune* const, int ws);
+ float tRetune_getInputPeriod (tRetune* const);
+ float tRetune_getInputFreq (tRetune* const);
- float* pitchFactor;
- float timeConstant;
- float radius;
+ // Autotune
+ typedef struct _tAutotune
+ {
+ tPeriodDetection pd;
+ tPitchShift* ps;
+
+ float* inBuffer;
+ float** outBuffers;
+ float* tickOutput;
+ int frameSize;
+ int bufSize;
+
+ uint16_t hopSize;
+ uint16_t windowSize;
+ uint8_t fba;
+
+ float* freq;
+ float timeConstant;
+ float radius;
+
+ float inputPeriod;
+
+ int numVoices;
+ } _tAutotune;
- float inputPeriod;
+ typedef _tAutotune* tAutotune;
- int numVoices;
-} tRetune;
-
-void tRetune_init (tRetune* const, int numVoices, int bufSize, int frameSize);
-void tRetune_free (tRetune* const);
-
-float* tRetune_tick (tRetune* const, float sample);
-void tRetune_setNumVoices (tRetune* const, int numVoices);
-void tRetune_setPitchFactors (tRetune* const, float pf);
-void tRetune_setPitchFactor (tRetune* const, float pf, int voice);
-void tRetune_setTimeConstant (tRetune* const, float tc);
-void tRetune_setHopSize (tRetune* const, int hs);
-void tRetune_setWindowSize (tRetune* const, int ws);
-float tRetune_getInputPeriod (tRetune* const);
-float tRetune_getInputFreq (tRetune* const);
+ void tAutotune_init (tAutotune* const, int numVoices, int bufSize, int frameSize);
+ void tAutotune_free (tAutotune* const);
-// Autotune
-typedef struct _tAutotune
-{
- tPeriodDetection pd;
- tPitchShift* ps;
+ float* tAutotune_tick (tAutotune* const, float sample);
+ void tAutotune_setNumVoices (tAutotune* const, int numVoices);
+ void tAutotune_setFreqs (tAutotune* const, float f);
+ void tAutotune_setFreq (tAutotune* const, float f, int voice);
+ void tAutotune_setTimeConstant (tAutotune* const, float tc);
+ void tAutotune_setHopSize (tAutotune* const, int hs);
+ void tAutotune_setWindowSize (tAutotune* const, int ws);
+ float tAutotune_getInputPeriod (tAutotune* const);
+ float tAutotune_getInputFreq (tAutotune* const);
- float* inBuffer;
- float** outBuffers;
- float* tickOutput;
- int frameSize;
- int bufSize;
+ //==============================================================================
- uint16_t hopSize;
- uint16_t windowSize;
- uint8_t fba;
- float* freq;
- float timeConstant;
- float radius;
+#define FORD 7
+#define FORMANT_BUFFER_SIZE 2048
- float inputPeriod;
+ typedef struct _tFormantShifter
+ {
+ int ford;
+ int bufsize;
+ float falph;
+ float flamb;
+ float* fk;
+ float* fb;
+ float* fc;
+ float* frb;
+ float* frc;
+ float* fsig;
+ float* fsmooth;
+ float fhp;
+ float flp;
+ float flpa;
+ float** fbuff;
+ float* ftvec;
+ float fmute;
+ float fmutealph;
+ unsigned int cbi;
+
+ } _tFormantShifter;
- int numVoices;
-} tAutotune;
-
-void tAutotune_init (tAutotune* const, int numVoices, int bufSize, int frameSize);
-void tAutotune_free (tAutotune* const);
-
-float* tAutotune_tick (tAutotune* const, float sample);
-void tAutotune_setNumVoices (tAutotune* const, int numVoices);
-void tAutotune_setFreqs (tAutotune* const, float f);
-void tAutotune_setFreq (tAutotune* const, float f, int voice);
-void tAutotune_setTimeConstant (tAutotune* const, float tc);
-void tAutotune_setHopSize (tAutotune* const, int hs);
-void tAutotune_setWindowSize (tAutotune* const, int ws);
-float tAutotune_getInputPeriod (tAutotune* const);
-float tAutotune_getInputFreq (tAutotune* const);
-
-//==============================================================================
+ typedef _tFormantShifter* tFormantShifter;
-
-#define FORD 7
-#define FORMANT_BUFFER_SIZE 2048
-
-typedef struct _tFormantShifter
-{
- int ford;
- int bufsize;
- float falph;
- float flamb;
- float* fk;
- float* fb;
- float* fc;
- float* frb;
- float* frc;
- float* fsig;
- float* fsmooth;
- float fhp;
- float flp;
- float flpa;
- float** fbuff;
- float* ftvec;
- float fmute;
- float fmutealph;
- unsigned int cbi;
+ void tFormantShifter_init (tFormantShifter* const, int bufsize, int order);
+ void tFormantShifter_free (tFormantShifter* const);
-} tFormantShifter;
-
-void tFormantShifter_init (tFormantShifter* const, int bufsize, int order);
-void tFormantShifter_free (tFormantShifter* const);
-
-float tFormantShifter_tick (tFormantShifter* const, float input, float fwarp);
-float tFormantShifter_remove (tFormantShifter* const, float input);
-float tFormantShifter_add (tFormantShifter* const, float input, float fwarp);
-void tFormantShifter_ioSamples (tFormantShifter* const, float* in, float* out, int size, float fwarp);
-
-//==============================================================================
+ float tFormantShifter_tick (tFormantShifter* const, float input, float fwarp);
+ float tFormantShifter_remove (tFormantShifter* const, float input);
+ float tFormantShifter_add (tFormantShifter* const, float input, float fwarp);
+ void tFormantShifter_ioSamples (tFormantShifter* const, float* in, float* out, int size, float fwarp);
+ //==============================================================================
+
#ifdef __cplusplus
}
#endif
-
+
#endif // LEAF_EFFECTS_H_INCLUDED
//==============================================================================
--- a/LEAF/Inc/leaf-electrical.h
+++ b/LEAF/Inc/leaf-electrical.h
@@ -11,79 +11,81 @@
#ifdef __cplusplus
extern "C" {
#endif
-
-//==============================================================================
-
+
+ //==============================================================================
+
#include "leaf-global.h"
#include "leaf-math.h"
-
-//==============================================================================
-
-typedef enum WDFComponentType
-{
- SeriesAdaptor = 0,
- ParallelAdaptor,
- Resistor,
- Capacitor,
- Inductor,
- Inverter,
- ResistiveSource,
- IdealSource,
- Diode,
- DiodePair,
- RootNil,
- WDFComponentNil
-} WDFComponentType;
-
-typedef struct _tWDF tWDF; // needed to allow tWDF pointers in struct
-struct _tWDF
-{
- WDFComponentType type;
- float port_resistance_up;
- float port_resistance_left;
- float port_resistance_right;
- float port_conductance_up;
- float port_conductance_left;
- float port_conductance_right;
- float incident_wave_up;
- float incident_wave_left;
- float incident_wave_right;
- float reflected_wave_up;
- float reflected_wave_left;
- float reflected_wave_right;
- float gamma_zero;
- float sample_rate;
- float value;
- tWDF* child_left;
- tWDF* child_right;
- float (*get_port_resistance)(tWDF* const);
- float (*get_reflected_wave_up)(tWDF* const, float);
- float (*get_reflected_wave_down)(tWDF* const, float, float);
- void (*set_incident_wave)(tWDF* const, float, float);
-};
-
-//WDF Linear Components
-void tWDF_init(tWDF* const r, WDFComponentType type, float value, tWDF* const rL, tWDF* const rR);
-void tWDF_free(tWDF* const r);
-float tWDF_tick(tWDF* const r, float sample, tWDF* const outputPoint, uint8_t paramsChanged);
-
-void tWDF_setValue(tWDF* const r, float value);
-void tWDF_setSampleRate(tWDF* const r, float sample_rate);
-uint8_t tWDF_isLeaf(tWDF* const r);
-
-float tWDF_getPortResistance(tWDF* const r);
-float tWDF_getReflectedWaveUp(tWDF* const r, float input); //for tree, only uses input for resistive source
-float tWDF_getReflectedWaveDown(tWDF* const r, float input, float incident_wave); //for roots
-void tWDF_setIncidentWave(tWDF* const r, float incident_wave, float input);
-
-float tWDF_getVoltage(tWDF* const r);
-float tWDF_getCurrent(tWDF* const r);
+
+ //==============================================================================
+
+ typedef enum WDFComponentType
+ {
+ SeriesAdaptor = 0,
+ ParallelAdaptor,
+ Resistor,
+ Capacitor,
+ Inductor,
+ Inverter,
+ ResistiveSource,
+ IdealSource,
+ Diode,
+ DiodePair,
+ RootNil,
+ WDFComponentNil
+ } WDFComponentType;
+
+ typedef struct _tWDF _tWDF; // needed to allow tWDF pointers in struct
+ typedef _tWDF* tWDF;
+ struct _tWDF
+ {
+ WDFComponentType type;
+ float port_resistance_up;
+ float port_resistance_left;
+ float port_resistance_right;
+ float port_conductance_up;
+ float port_conductance_left;
+ float port_conductance_right;
+ float incident_wave_up;
+ float incident_wave_left;
+ float incident_wave_right;
+ float reflected_wave_up;
+ float reflected_wave_left;
+ float reflected_wave_right;
+ float gamma_zero;
+ float sample_rate;
+ float value;
+ tWDF* child_left;
+ tWDF* child_right;
+ float (*get_port_resistance)(tWDF* const);
+ float (*get_reflected_wave_up)(tWDF* const, float);
+ float (*get_reflected_wave_down)(tWDF* const, float, float);
+ void (*set_incident_wave)(tWDF* const, float, float);
+ };
+
+ //WDF Linear Components
+ void tWDF_init(tWDF* const r, WDFComponentType type, float value, tWDF* const rL, tWDF* const rR);
+ void tWDF_free(tWDF* const r);
+ float tWDF_tick(tWDF* const r, float sample, tWDF* const outputPoint, uint8_t paramsChanged);
-
-//==============================================================================
+ void tWDF_setValue(tWDF* const r, float value);
+ void tWDF_setSampleRate(tWDF* const r, float sample_rate);
+ uint8_t tWDF_isLeaf(tWDF* const r);
+ float tWDF_getPortResistance(tWDF* const r);
+ float tWDF_getReflectedWaveUp(tWDF* const r, float input); //for tree, only uses input for resistive source
+ float tWDF_getReflectedWaveDown(tWDF* const r, float input, float incident_wave); //for roots
+ void tWDF_setIncidentWave(tWDF* const r, float incident_wave, float input);
+
+ float tWDF_getVoltage(tWDF* const r);
+ float tWDF_getCurrent(tWDF* const r);
+
+
+ //==============================================================================
+
#ifdef __cplusplus
}
#endif
#endif /* LEAF_INC_LEAF_ELECTRICAL_H_ */
+
--- a/LEAF/Inc/leaf-envelopes.h
+++ b/LEAF/Inc/leaf-envelopes.h
@@ -1,13 +1,13 @@
/*
- ==============================================================================
+ ==============================================================================
+
+ leaf-envelopes.h
+ Created: 20 Jan 2017 12:02:17pm
+ Author: Michael R Mulshine
+
+ ==============================================================================
+ */
- leaf-envelopes.h
- Created: 20 Jan 2017 12:02:17pm
- Author: Michael R Mulshine
-
- ==============================================================================
-*/
-
#ifndef LEAF_ENVELOPES_H_INCLUDED
#define LEAF_ENVELOPES_H_INCLUDED
@@ -14,123 +14,132 @@
#ifdef __cplusplus
extern "C" {
#endif
-
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-
+
+ // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
#include "leaf-math.h"
#include "leaf-filters.h"
#include "leaf-delay.h"
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-
-/* Attack-Decay envelope */
-typedef struct _tEnvelope {
+ // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
- const float *exp_buff;
- const float *inc_buff;
- uint32_t buff_size;
+ /* Attack-Decay envelope */
+ typedef struct _tEnvelope {
+
+ const float *exp_buff;
+ const float *inc_buff;
+ uint32_t buff_size;
+
+ float next;
+
+ float attackInc, decayInc, rampInc;
+
+ oBool inAttack, inDecay, inRamp;
+
+ oBool loop;
+
+ float gain, rampPeak;
+
+ float attackPhase, decayPhase, rampPhase;
+
+ } _tEnvelope;
- float next;
+ typedef _tEnvelope* tEnvelope;
- float attackInc, decayInc, rampInc;
+ void tEnvelope_init (tEnvelope* const, float attack, float decay, oBool loop);
+ void tEnvelope_free (tEnvelope* const);
- oBool inAttack, inDecay, inRamp;
+ float tEnvelope_tick (tEnvelope* const);
+ void tEnvelope_setAttack (tEnvelope* const, float attack);
+ void tEnvelope_setDecay (tEnvelope* const, float decay);
+ void tEnvelope_loop (tEnvelope* const, oBool loop);
+ void tEnvelope_on (tEnvelope* const, float velocity);
- oBool loop;
+ // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
- float gain, rampPeak;
+ /* ADSR */
+ typedef struct _tADSR
+ {
+ const float *exp_buff;
+ const float *inc_buff;
+ uint32_t buff_size;
+
+ float next;
+
+ float attackInc, decayInc, releaseInc, rampInc;
+
+ oBool inAttack, inDecay, inSustain, inRelease, inRamp;
+
+ float sustain, gain, rampPeak, releasePeak;
+
+ float attackPhase, decayPhase, releasePhase, rampPhase;
+
+ } _tADSR;
- float attackPhase, decayPhase, rampPhase;
+ typedef _tADSR* tADSR;
-} tEnvelope;
-
-void tEnvelope_init (tEnvelope* const, float attack, float decay, oBool loop);
-void tEnvelope_free (tEnvelope* const);
-
-float tEnvelope_tick (tEnvelope* const);
-int tEnvelope_setAttack (tEnvelope* const, float attack);
-int tEnvelope_setDecay (tEnvelope* const, float decay);
-int tEnvelope_loop (tEnvelope* const, oBool loop);
-int tEnvelope_on (tEnvelope* const, float velocity);
-
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-
-/* ADSR */
-typedef struct _tADSR
-{
- const float *exp_buff;
- const float *inc_buff;
- uint32_t buff_size;
+ void tADSR_init (tADSR* const, float attack, float decay, float sustain, float release);
+ void tADSR_free (tADSR* const);
- float next;
+ float tADSR_tick (tADSR* const);
+ void tADSR_setAttack (tADSR* const, float attack);
+ void tADSR_setDecay (tADSR* const, float decay);
+ void tADSR_setSustain(tADSR* const, float sustain);
+ void tADSR_setRelease(tADSR* const, float release);
+ void tADSR_on (tADSR* const, float velocity);
+ void tADSR_off (tADSR* const);
- float attackInc, decayInc, releaseInc, rampInc;
+ // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
- oBool inAttack, inDecay, inSustain, inRelease, inRamp;
+ // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
- float sustain, gain, rampPeak, releasePeak;
+ /* Ramp */
+ typedef struct _tRamp {
+ float inc;
+ float inv_sr_ms;
+ float minimum_time;
+ float curr,dest;
+ float time;
+ int samples_per_tick;
+
+ } _tRamp;
- float attackPhase, decayPhase, releasePhase, rampPhase;
+ typedef _tRamp* tRamp;
-} tADSR;
-
-void tADSR_init (tADSR* const, float attack, float decay, float sustain, float release);
-void tADSR_free (tADSR* const);
-
-float tADSR_tick (tADSR* const);
-int tADSR_setAttack (tADSR* const, float attack);
-int tADSR_setDecay (tADSR* const, float decay);
-int tADSR_setSustain(tADSR* const, float sustain);
-int tADSR_setRelease(tADSR* const, float release);
-int tADSR_on (tADSR* const, float velocity);
-int tADSR_off (tADSR* const);
-
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-
-/* Ramp */
-typedef struct _tRamp {
- float inc;
- float inv_sr_ms;
- float minimum_time;
- float curr,dest;
- float time;
- int samples_per_tick;
+ void tRamp_init (tRamp* const, float time, int samplesPerTick);
+ void tRamp_free (tRamp* const);
-} tRamp;
-
-void tRamp_init (tRamp* const, float time, int samplesPerTick);
-void tRamp_free (tRamp* const);
-
-float tRamp_tick (tRamp* const);
-float tRamp_sample (tRamp* const);
-int tRamp_setTime (tRamp* const, float time);
-int tRamp_setDest (tRamp* const, float dest);
-int tRamp_setVal (tRamp* const, float val);
-
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-
-/* Exponential Smoother */
-typedef struct _tExpSmooth {
- float factor, oneminusfactor;
- float curr,dest;
-
-} tExpSmooth;
-
-void tExpSmooth_init (tExpSmooth* const, float val, float factor);
-void tExpSmooth_free (tExpSmooth* const);
-
-float tExpSmooth_tick (tExpSmooth* const);
-float tExpSmooth_sample (tExpSmooth* const);
-int tExpSmooth_setFactor (tExpSmooth* const, float factor);
-int tExpSmooth_setDest (tExpSmooth* const, float dest);
-int tExpSmooth_setVal (tExpSmooth* const, float val);
+ float tRamp_tick (tRamp* const);
+ float tRamp_sample (tRamp* const);
+ void tRamp_setTime (tRamp* const, float time);
+ void tRamp_setDest (tRamp* const, float dest);
+ void tRamp_setVal (tRamp* const, float val);
+ // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
+ /* Exponential Smoother */
+ typedef struct _tExpSmooth {
+ float factor, oneminusfactor;
+ float curr,dest;
+
+ } _tExpSmooth;
+
+ typedef _tExpSmooth* tExpSmooth;
+
+ void tExpSmooth_init (tExpSmooth* const, float val, float factor);
+ void tExpSmooth_free (tExpSmooth* const);
+
+ float tExpSmooth_tick (tExpSmooth* const);
+ float tExpSmooth_sample (tExpSmooth* const);
+ void tExpSmooth_setFactor (tExpSmooth* const, float factor);
+ void tExpSmooth_setDest (tExpSmooth* const, float dest);
+ void tExpSmooth_setVal (tExpSmooth* const, float val);
+
#ifdef __cplusplus
}
#endif
#endif // LEAF_ENVELOPES_H_INCLUDED
+
--- a/LEAF/Inc/leaf-filters.h
+++ b/LEAF/Inc/leaf-filters.h
@@ -1,11 +1,11 @@
/*==============================================================================
+
+ leaf-filters.h
+ Created: 20 Jan 2017 12:01:10pm
+ Author: Michael R Mulshine
+
+ ==============================================================================*/
- leaf-filters.h
- Created: 20 Jan 2017 12:01:10pm
- Author: Michael R Mulshine
-
-==============================================================================*/
-
#ifndef LEAF_FILTERS_H_INCLUDED
#define LEAF_FILTERS_H_INCLUDED
@@ -12,297 +12,321 @@
#ifdef __cplusplus
extern "C" {
#endif
-
-//==============================================================================
+ //==============================================================================
+
#include "leaf-math.h"
#include "leaf-delay.h"
#include "leaf-tables.h"
-
-//==============================================================================
-/* tAllpass: Schroeder allpass. Comb-filter with feedforward and feedback. */
-typedef struct _tAllpass
-{
- float gain;
+ //==============================================================================
- tLinearDelay delay;
+ /* tAllpass: Schroeder allpass. Comb-filter with feedforward and feedback. */
+ typedef struct _tAllpass
+ {
+ float gain;
+
+ tLinearDelay delay;
+
+ float lastOut;
+
+ } _tAllpass;
- float lastOut;
+ typedef _tAllpass* tAllpass;
-} tAllpass;
-
-void tAllpass_init (tAllpass* const, float initDelay, uint32_t maxDelay);
-void tAllpass_free (tAllpass* const);
-
-float tAllpass_tick (tAllpass* const, float input);
-void tAllpass_setGain (tAllpass* const, float gain);
-void tAllpass_setDelay (tAllpass* const f, float delay);
-
-
-//==============================================================================
+ void tAllpass_init (tAllpass* const, float initDelay, uint32_t maxDelay);
+ void tAllpass_free (tAllpass* const);
-/* tOnePole: OnePole filter, reimplemented from STK (Cook and Scavone). */
-typedef struct _tOnePole
-{
- float gain;
- float a0,a1;
- float b0,b1;
+ float tAllpass_tick (tAllpass* const, float input);
+ void tAllpass_setGain (tAllpass* const, float gain);
+ void tAllpass_setDelay (tAllpass* const f, float delay);
- float coef;
- float freq;
+ //==============================================================================
- float lastIn, lastOut;
+ /* tOnePole: OnePole filter, reimplemented from STK (Cook and Scavone). */
+ typedef struct _tOnePole
+ {
+ float gain;
+ float a0,a1;
+ float b0,b1;
+
+ float coef;
+
+ float freq;
+
+ float lastIn, lastOut;
+
+ } _tOnePole;
-} tOnePole;
-
-void tOnePole_init (tOnePole* const, float thePole);
-void tOnePole_free (tOnePole* const);
-
-float tOnePole_tick (tOnePole* const, float input);
-void tOnePole_setB0 (tOnePole* const, float b0);
-void tOnePole_setA1 (tOnePole* const, float a1);
-void tOnePole_setPole (tOnePole* const, float thePole);
-void tOnePole_setFreq (tOnePole* const, float freq);
-void tOnePole_setCoefficients(tOnePole* const, float b0, float a1);
-void tOnePole_setGain (tOnePole* const, float gain);
-
-//==============================================================================
+ typedef _tOnePole* tOnePole;
-/* TwoPole filter, reimplemented from STK (Cook and Scavone). */
-typedef struct _tTwoPole
-{
- float gain;
- float a0, a1, a2;
- float b0;
+ void tOnePole_init (tOnePole* const, float thePole);
+ void tOnePole_free (tOnePole* const);
- float radius, frequency;
- oBool normalize;
+ float tOnePole_tick (tOnePole* const, float input);
+ void tOnePole_setB0 (tOnePole* const, float b0);
+ void tOnePole_setA1 (tOnePole* const, float a1);
+ void tOnePole_setPole (tOnePole* const, float thePole);
+ void tOnePole_setFreq (tOnePole* const, float freq);
+ void tOnePole_setCoefficients(tOnePole* const, float b0, float a1);
+ void tOnePole_setGain (tOnePole* const, float gain);
- float lastOut[2];
+ //==============================================================================
-} tTwoPole;
-
-void tTwoPole_init (tTwoPole* const);
-void tTwoPole_free (tTwoPole* const);
-
-float tTwoPole_tick (tTwoPole* const, float input);
-void tTwoPole_setB0 (tTwoPole* const, float b0);
-void tTwoPole_setA1 (tTwoPole* const, float a1);
-void tTwoPole_setA2 (tTwoPole* const, float a2);
-void tTwoPole_setResonance (tTwoPole* const, float freq, float radius, oBool normalize);
-void tTwoPole_setCoefficients(tTwoPole* const, float b0, float a1, float a2);
-void tTwoPole_setGain (tTwoPole* const, float gain);
-
-//==============================================================================
+ /* TwoPole filter, reimplemented from STK (Cook and Scavone). */
+ typedef struct _tTwoPole
+ {
+ float gain;
+ float a0, a1, a2;
+ float b0;
+
+ float radius, frequency;
+ oBool normalize;
+
+ float lastOut[2];
+
+ } _tTwoPole;
-/* OneZero filter, reimplemented from STK (Cook and Scavone). */
-typedef struct _tOneZero
-{
- float gain;
- float b0,b1;
- float lastIn, lastOut, frequency;
+ typedef _tTwoPole* tTwoPole;
-} tOneZero;
-
-void tOneZero_init (tOneZero* const, float theZero);
-void tOneZero_free (tOneZero* const);
-float tOneZero_tick (tOneZero* const, float input);
-void tOneZero_setB0 (tOneZero* const, float b0);
-void tOneZero_setB1 (tOneZero* const, float b1);
-void tOneZero_setZero (tOneZero* const, float theZero);
-void tOneZero_setCoefficients(tOneZero* const, float b0, float b1);
-void tOneZero_setGain (tOneZero* const, float gain);
-float tOneZero_getPhaseDelay(tOneZero *f, float frequency );
-
-//==============================================================================
+ void tTwoPole_init (tTwoPole* const);
+ void tTwoPole_free (tTwoPole* const);
-/* TwoZero filter, reimplemented from STK (Cook and Scavone). */
-typedef struct _tTwoZero
-{
- float gain;
- float b0, b1, b2;
+ float tTwoPole_tick (tTwoPole* const, float input);
+ void tTwoPole_setB0 (tTwoPole* const, float b0);
+ void tTwoPole_setA1 (tTwoPole* const, float a1);
+ void tTwoPole_setA2 (tTwoPole* const, float a2);
+ void tTwoPole_setResonance (tTwoPole* const, float freq, float radius, oBool normalize);
+ void tTwoPole_setCoefficients(tTwoPole* const, float b0, float a1, float a2);
+ void tTwoPole_setGain (tTwoPole* const, float gain);
- float frequency, radius;
+ //==============================================================================
- float lastIn[2];
+ /* OneZero filter, reimplemented from STK (Cook and Scavone). */
+ typedef struct _tOneZero
+ {
+ float gain;
+ float b0,b1;
+ float lastIn, lastOut, frequency;
+
+ } _tOneZero;
-} tTwoZero;
-
-void tTwoZero_init (tTwoZero* const);
-void tTwoZero_free (tTwoZero* const);
-
-float tTwoZero_tick (tTwoZero* const, float input);
-void tTwoZero_setB0 (tTwoZero* const, float b0);
-void tTwoZero_setB1 (tTwoZero* const, float b1);
-void tTwoZero_setB2 (tTwoZero* const, float b2);
-void tTwoZero_setNotch (tTwoZero* const, float frequency, float radius);
-void tTwoZero_setCoefficients(tTwoZero* const, float b0, float b1, float b2);
-void tTwoZero_setGain (tTwoZero* const, float gain);
-
-//==============================================================================
+ typedef _tOneZero* tOneZero;
-/* PoleZero filter, reimplemented from STK (Cook and Scavone). */
-typedef struct _tPoleZero
-{
- float gain;
- float a0,a1;
- float b0,b1;
+ void tOneZero_init (tOneZero* const, float theZero);
+ void tOneZero_free (tOneZero* const);
+ float tOneZero_tick (tOneZero* const, float input);
+ void tOneZero_setB0 (tOneZero* const, float b0);
+ void tOneZero_setB1 (tOneZero* const, float b1);
+ void tOneZero_setZero (tOneZero* const, float theZero);
+ void tOneZero_setCoefficients(tOneZero* const, float b0, float b1);
+ void tOneZero_setGain (tOneZero* const, float gain);
+ float tOneZero_getPhaseDelay(tOneZero *f, float frequency );
- float lastIn, lastOut;
+ //==============================================================================
-} tPoleZero;
-
-void tPoleZero_init (tPoleZero* const);
-void tPoleZero_free (tPoleZero* const);
-
-float tPoleZero_tick (tPoleZero* const, float input);
-void tPoleZero_setB0 (tPoleZero* const, float b0);
-void tPoleZero_setB1 (tPoleZero* const, float b1);
-void tPoleZero_setA1 (tPoleZero* const, float a1);
-void tPoleZero_setCoefficients (tPoleZero* const, float b0, float b1, float a1);
-void tPoleZero_setAllpass (tPoleZero* const, float coeff);
-void tPoleZero_setBlockZero (tPoleZero* const, float thePole);
-void tPoleZero_setGain (tPoleZero* const, float gain);
-
-//==============================================================================
+ /* TwoZero filter, reimplemented from STK (Cook and Scavone). */
+ typedef struct _tTwoZero
+ {
+ float gain;
+ float b0, b1, b2;
+
+ float frequency, radius;
+
+ float lastIn[2];
+
+ } _tTwoZero;
-/* BiQuad filter, reimplemented from STK (Cook and Scavone). */
-typedef struct _tBiQuad
-{
- float gain;
- float a0, a1, a2;
- float b0, b1, b2;
+ typedef _tTwoZero* tTwoZero;
- float lastIn[2];
- float lastOut[2];
+ void tTwoZero_init (tTwoZero* const);
+ void tTwoZero_free (tTwoZero* const);
- float frequency, radius;
- oBool normalize;
-} tBiQuad;
-
-void tBiQuad_init (tBiQuad* const);
-void tBiQuad_free (tBiQuad* const);
-
-float tBiQuad_tick (tBiQuad* const, float input);
-void tBiQuad_setB0 (tBiQuad* const, float b0);
-void tBiQuad_setB1 (tBiQuad* const, float b1);
-void tBiQuad_setB2 (tBiQuad* const, float b2);
-void tBiQuad_setA1 (tBiQuad* const, float a1);
-void tBiQuad_setA2 (tBiQuad* const, float a2);
-void tBiQuad_setNotch (tBiQuad* const, float freq, float radius);
-void tBiQuad_setResonance (tBiQuad* const, float freq, float radius, oBool normalize);
-void tBiQuad_setCoefficients(tBiQuad* const, float b0, float b1, float b2, float a1, float a2);
-void tBiQuad_setGain (tBiQuad* const, float gain);
-
-//==============================================================================
+ float tTwoZero_tick (tTwoZero* const, float input);
+ void tTwoZero_setB0 (tTwoZero* const, float b0);
+ void tTwoZero_setB1 (tTwoZero* const, float b1);
+ void tTwoZero_setB2 (tTwoZero* const, float b2);
+ void tTwoZero_setNotch (tTwoZero* const, float frequency, float radius);
+ void tTwoZero_setCoefficients(tTwoZero* const, float b0, float b1, float b2);
+ void tTwoZero_setGain (tTwoZero* const, float gain);
-/* State Variable Filter, algorithm from Andy Simper. */
-typedef enum SVFType
-{
- SVFTypeHighpass = 0,
- SVFTypeLowpass,
- SVFTypeBandpass,
- SVFTypeNotch,
- SVFTypePeak,
-} SVFType;
-
-typedef struct _tSVF
-{
- SVFType type;
- float cutoff, Q;
- float ic1eq,ic2eq;
- float g,k,a1,a2,a3;
+ //==============================================================================
-} tSVF;
-
-void tSVF_init (tSVF* const, SVFType type, float freq, float Q);
-void tSVF_free (tSVF* const);
-
-float tSVF_tick (tSVF* const, float v0);
-int tSVF_setFreq (tSVF* const, float freq);
-int tSVF_setQ (tSVF* const, float Q);
-
-//==============================================================================
+ /* PoleZero filter, reimplemented from STK (Cook and Scavone). */
+ typedef struct _tPoleZero
+ {
+ float gain;
+ float a0,a1;
+ float b0,b1;
+
+ float lastIn, lastOut;
+
+ } _tPoleZero;
-/* Efficient State Variable Filter for 14-bit control input, [0, 4096). */
-typedef struct _tEfficientSVF
-{
- SVFType type;
- float cutoff, Q;
- float ic1eq,ic2eq;
- float g,k,a1,a2,a3;
+ typedef _tPoleZero* tPoleZero;
-} tEfficientSVF;
-
-void tEfficientSVF_init (tEfficientSVF* const, SVFType type, uint16_t controlFreq, float Q);
-void tEfficientSVF_free (tEfficientSVF* const);
-
-float tEfficientSVF_tick (tEfficientSVF* const, float v0);
-int tEfficientSVF_setFreq (tEfficientSVF* const, uint16_t controlFreq);
-int tEfficientSVF_setQ (tEfficientSVF* const, float Q);
-
-//==============================================================================
+ void tPoleZero_init (tPoleZero* const);
+ void tPoleZero_free (tPoleZero* const);
-/* Simple Highpass filter. */
-typedef struct _tHighpass
-{
- float xs, ys, R;
- float frequency;
+ float tPoleZero_tick (tPoleZero* const, float input);
+ void tPoleZero_setB0 (tPoleZero* const, float b0);
+ void tPoleZero_setB1 (tPoleZero* const, float b1);
+ void tPoleZero_setA1 (tPoleZero* const, float a1);
+ void tPoleZero_setCoefficients (tPoleZero* const, float b0, float b1, float a1);
+ void tPoleZero_setAllpass (tPoleZero* const, float coeff);
+ void tPoleZero_setBlockZero (tPoleZero* const, float thePole);
+ void tPoleZero_setGain (tPoleZero* const, float gain);
-} tHighpass;
-
-void tHighpass_init (tHighpass* const, float freq);
-void tHighpass_free (tHighpass* const);
-
-float tHighpass_tick (tHighpass* const, float x);
-void tHighpass_setFreq (tHighpass* const, float freq);
-float tHighpass_getFreq (tHighpass* const);
-
-//==============================================================================
+ //==============================================================================
-// Butterworth Filter
+ /* BiQuad filter, reimplemented from STK (Cook and Scavone). */
+ typedef struct _tBiQuad
+ {
+ float gain;
+ float a0, a1, a2;
+ float b0, b1, b2;
+
+ float lastIn[2];
+ float lastOut[2];
+
+ float frequency, radius;
+ oBool normalize;
+ } _tBiQuad;
+
+ typedef _tBiQuad* tBiQuad;
+
+ void tBiQuad_init (tBiQuad* const);
+ void tBiQuad_free (tBiQuad* const);
+
+ float tBiQuad_tick (tBiQuad* const, float input);
+ void tBiQuad_setB0 (tBiQuad* const, float b0);
+ void tBiQuad_setB1 (tBiQuad* const, float b1);
+ void tBiQuad_setB2 (tBiQuad* const, float b2);
+ void tBiQuad_setA1 (tBiQuad* const, float a1);
+ void tBiQuad_setA2 (tBiQuad* const, float a2);
+ void tBiQuad_setNotch (tBiQuad* const, float freq, float radius);
+ void tBiQuad_setResonance (tBiQuad* const, float freq, float radius, oBool normalize);
+ void tBiQuad_setCoefficients(tBiQuad* const, float b0, float b1, float b2, float a1, float a2);
+ void tBiQuad_setGain (tBiQuad* const, float gain);
+
+ //==============================================================================
+
+ /* State Variable Filter, algorithm from Andy Simper. */
+ typedef enum SVFType
+ {
+ SVFTypeHighpass = 0,
+ SVFTypeLowpass,
+ SVFTypeBandpass,
+ SVFTypeNotch,
+ SVFTypePeak,
+ } SVFType;
+
+ typedef struct _tSVF
+ {
+ SVFType type;
+ float cutoff, Q;
+ float ic1eq,ic2eq;
+ float g,k,a1,a2,a3;
+
+ } _tSVF;
+
+ typedef _tSVF* tSVF;
+
+ void tSVF_init (tSVF* const, SVFType type, float freq, float Q);
+ void tSVF_free (tSVF* const);
+
+ float tSVF_tick (tSVF* const, float v0);
+ void tSVF_setFreq (tSVF* const, float freq);
+ void tSVF_setQ (tSVF* const, float Q);
+
+ //==============================================================================
+
+ /* Efficient State Variable Filter for 14-bit control input, [0, 4096). */
+ typedef struct _tEfficientSVF
+ {
+ SVFType type;
+ float cutoff, Q;
+ float ic1eq,ic2eq;
+ float g,k,a1,a2,a3;
+
+ } _tEfficientSVF;
+
+ typedef _tEfficientSVF* tEfficientSVF;
+
+ void tEfficientSVF_init (tEfficientSVF* const, SVFType type, uint16_t controlFreq, float Q);
+ void tEfficientSVF_free (tEfficientSVF* const);
+
+ float tEfficientSVF_tick (tEfficientSVF* const, float v0);
+ void tEfficientSVF_setFreq (tEfficientSVF* const, uint16_t controlFreq);
+ void tEfficientSVF_setQ (tEfficientSVF* const, float Q);
+
+ //==============================================================================
+
+ /* Simple Highpass filter. */
+ typedef struct _tHighpass
+ {
+ float xs, ys, R;
+ float frequency;
+
+ } _tHighpass;
+
+ typedef _tHighpass* tHighpass;
+
+ void tHighpass_init (tHighpass* const, float freq);
+ void tHighpass_free (tHighpass* const);
+
+ float tHighpass_tick (tHighpass* const, float x);
+ void tHighpass_setFreq (tHighpass* const, float freq);
+ float tHighpass_getFreq (tHighpass* const);
+
+ //==============================================================================
+
+ // Butterworth Filter
#define NUM_SVF_BW 16
-typedef struct _tButterworth
-{
- float gain;
+ typedef struct _tButterworth
+ {
+ float gain;
+
+ float N;
+
+ tSVF low[NUM_SVF_BW];
+ tSVF high[NUM_SVF_BW];
+
+ float f1,f2;
+
+ } _tButterworth;
- float N;
+ typedef _tButterworth* tButterworth;
- tSVF low[NUM_SVF_BW];
- tSVF high[NUM_SVF_BW];
+ void tButterworth_init (tButterworth* const, int N, float f1, float f2);
+ void tButterworth_free (tButterworth* const);
- float f1,f2;
+ float tButterworth_tick (tButterworth* const, float input);
+ void tButterworth_setF1 (tButterworth* const, float in);
+ void tButterworth_setF2 (tButterworth* const, float in);
+ void tButterworth_setFreqs (tButterworth* const, float f1, float f2);
-} tButterworth;
-
-void tButterworth_init (tButterworth* const, int N, float f1, float f2);
-void tButterworth_free (tButterworth* const);
-
-float tButterworth_tick (tButterworth* const, float input);
-void tButterworth_setF1 (tButterworth* const, float in);
-void tButterworth_setF2 (tButterworth* const, float in);
-void tButterworth_setFreqs (tButterworth* const, float f1, float f2);
-
-//==============================================================================
-
-typedef struct _tFIR
-{
- float* past;
- float* coeff;
- int numTaps;
-
-} tFIR;
-
-void tFIR_init (tFIR* const, float* coeffs, int numTaps);
-void tFIR_free (tFIR* const);
-
-float tFIR_tick (tFIR* const, float input);
-void tFIR_coeffs (tFIR* const, float in);
-
-//==============================================================================
-
+ //==============================================================================
+
+ typedef struct _tFIR
+ {
+ float* past;
+ float* coeff;
+ int numTaps;
+
+ } _tFIR;
+
+ typedef _tFIR* tFIR;
+
+ void tFIR_init (tFIR* const, float* coeffs, int numTaps);
+ void tFIR_free (tFIR* const);
+
+ float tFIR_tick (tFIR* const, float input);
+ void tFIR_coeffs (tFIR* const, float in);
+
+ //==============================================================================
+
#ifdef __cplusplus
}
#endif
@@ -310,3 +334,4 @@
#endif // LEAF_FILTERS_H_INCLUDED
//==============================================================================
+
--- a/LEAF/Inc/leaf-instruments.h
+++ b/LEAF/Inc/leaf-instruments.h
@@ -1,11 +1,11 @@
/*==============================================================================
+
+ leaf-instruments.h
+ Created: 30 Nov 2018 10:24:44am
+ Author: airship
+
+ ==============================================================================*/
- leaf-instruments.h
- Created: 30 Nov 2018 10:24:44am
- Author: airship
-
-==============================================================================*/
-
#ifndef LEAF_INSTRUMENTS_H_INCLUDED
#define LEAF_INSTRUMENTS_H_INCLUDED
@@ -12,167 +12,174 @@
#ifdef __cplusplus
extern "C" {
#endif
-
-//==============================================================================
+ //==============================================================================
+
#include "leaf-math.h"
+#include "leaf-mempool.h"
#include "leaf-oscillators.h"
#include "leaf-filters.h"
#include "leaf-envelopes.h"
-
-//==============================================================================
-// 808 Cowbell
-typedef struct _t808Cowbell {
+ //==============================================================================
- tSquare p[2];
- tNoise stick;
- tSVF bandpassOsc;
- tSVF bandpassStick;
- tEnvelope envGain;
- tEnvelope envStick;
- tEnvelope envFilter;
- tHighpass highpass;
- float oscMix;
- float filterCutoff;
- oBool useStick;
+ // 808 Cowbell
+ typedef struct _t808Cowbell {
+
+ tSquare p[2];
+ tNoise stick;
+ tSVF bandpassOsc;
+ tSVF bandpassStick;
+ tEnvelope envGain;
+ tEnvelope envStick;
+ tEnvelope envFilter;
+ tHighpass highpass;
+ float oscMix;
+ float filterCutoff;
+ oBool useStick;
+
+ } _t808Cowbell;
-} t808Cowbell;
-
-void t808Cowbell_init (t808Cowbell* const, int useStick);
-void t808Cowbell_free (t808Cowbell* const);
-float t808Cowbell_tick (t808Cowbell* const);
-void t808Cowbell_on (t808Cowbell* const, float vel);
-void t808Cowbell_setDecay (t808Cowbell* const, float decay);
-void t808Cowbell_setHighpassFreq (t808Cowbell* const, float freq);
-void t808Cowbell_setBandpassFreq (t808Cowbell* const, float freq);
-void t808Cowbell_setFreq (t808Cowbell* const, float freq);
-void t808Cowbell_setOscMix (t808Cowbell* const, float oscMix);
-void t808Cowbell_setStick (t808Cowbell* const, int useStick);
-
-//==============================================================================
+ typedef _t808Cowbell* t808Cowbell;
-// 808 Hihat
-typedef struct _t808Hihat {
+ void t808Cowbell_init (t808Cowbell* const, int useStick);
+ void t808Cowbell_free (t808Cowbell* const);
+ float t808Cowbell_tick (t808Cowbell* const);
+ void t808Cowbell_on (t808Cowbell* const, float vel);
+ void t808Cowbell_setDecay (t808Cowbell* const, float decay);
+ void t808Cowbell_setHighpassFreq (t808Cowbell* const, float freq);
+ void t808Cowbell_setBandpassFreq (t808Cowbell* const, float freq);
+ void t808Cowbell_setFreq (t808Cowbell* const, float freq);
+ void t808Cowbell_setOscMix (t808Cowbell* const, float oscMix);
+ void t808Cowbell_setStick (t808Cowbell* const, int useStick);
+
+ //==============================================================================
+
+ // 808 Hihat
+ typedef struct _t808Hihat {
+
+ // 6 Square waves
+ tSquare p[6];
+ tNoise n;
+ tSVF bandpassOsc;
+ tSVF bandpassStick;
+ tEnvelope envGain;
+ tEnvelope envStick;
+ tEnvelope noiseFMGain;
+ tHighpass highpass;
+ tNoise stick;
+
+ float freq;
+ float stretch;
+ float FM_amount;
+ float oscNoiseMix;
+
+ } _t808Hihat;
- // 6 Square waves
- tSquare p[6];
- tNoise n;
- tSVF bandpassOsc;
- tSVF bandpassStick;
- tEnvelope envGain;
- tEnvelope envStick;
- tEnvelope noiseFMGain;
- tHighpass highpass;
- tNoise stick;
-
- float freq;
- float stretch;
- float FM_amount;
- float oscNoiseMix;
+ typedef _t808Hihat* t808Hihat;
-} t808Hihat;
-
-void t808Hihat_init (t808Hihat* const);
-void t808Hihat_free (t808Hihat* const);
-
-float t808Hihat_tick (t808Hihat* const);
-void t808Hihat_on (t808Hihat* const, float vel);
-void t808Hihat_setOscNoiseMix (t808Hihat* const, float oscNoiseMix);
-void t808Hihat_setDecay (t808Hihat* const, float decay);
-void t808Hihat_setHighpassFreq (t808Hihat* const, float freq);
-void t808Hihat_setOscBandpassFreq (t808Hihat* const, float freq);
-void t808Hihat_setOscBandpassQ (t808Hihat* const hihat, float Q);
-void t808Hihat_setStickBandPassFreq (t808Hihat* const, float freq);
-void t808Hihat_setStickBandPassQ (t808Hihat* const hihat, float Q);
-void t808Hihat_setOscFreq (t808Hihat* const, float freq);
-void t808Hihat_setStretch (t808Hihat* const hihat, float stretch);
-void t808Hihat_setFM (t808Hihat* const hihat, float FM_amount);
-
-//==============================================================================
+ void t808Hihat_init (t808Hihat* const);
+ void t808Hihat_free (t808Hihat* const);
-// 808 Snare
-typedef struct _t808Snare {
+ float t808Hihat_tick (t808Hihat* const);
+ void t808Hihat_on (t808Hihat* const, float vel);
+ void t808Hihat_setOscNoiseMix (t808Hihat* const, float oscNoiseMix);
+ void t808Hihat_setDecay (t808Hihat* const, float decay);
+ void t808Hihat_setHighpassFreq (t808Hihat* const, float freq);
+ void t808Hihat_setOscBandpassFreq (t808Hihat* const, float freq);
+ void t808Hihat_setOscBandpassQ (t808Hihat* const hihat, float Q);
+ void t808Hihat_setStickBandPassFreq (t808Hihat* const, float freq);
+ void t808Hihat_setStickBandPassQ (t808Hihat* const hihat, float Q);
+ void t808Hihat_setOscFreq (t808Hihat* const, float freq);
+ void t808Hihat_setStretch (t808Hihat* const hihat, float stretch);
+ void t808Hihat_setFM (t808Hihat* const hihat, float FM_amount);
- // Tone 1, Tone 2, Noise
- tTriangle tone[2]; // Tri (not yet antialiased or wavetabled)
- tNoise noiseOsc;
- tSVF toneLowpass[2];
- tSVF noiseLowpass; // Lowpass from SVF filter
- tEnvelope toneEnvOsc[2];
- tEnvelope toneEnvGain[2];
- tEnvelope noiseEnvGain;
- tEnvelope toneEnvFilter[2];
- tEnvelope noiseEnvFilter;
+ //==============================================================================
- float toneGain[2];
- float noiseGain;
+ // 808 Snare
+ typedef struct _t808Snare {
+
+ // Tone 1, Tone 2, Noise
+ tTriangle tone[2]; // Tri (not yet antialiased or wavetabled)
+ tNoise noiseOsc;
+ tSVF toneLowpass[2];
+ tSVF noiseLowpass; // Lowpass from SVF filter
+ tEnvelope toneEnvOsc[2];
+ tEnvelope toneEnvGain[2];
+ tEnvelope noiseEnvGain;
+ tEnvelope toneEnvFilter[2];
+ tEnvelope noiseEnvFilter;
+
+ float toneGain[2];
+ float noiseGain;
+
+ float toneNoiseMix;
+
+ float tone1Freq, tone2Freq;
+
+ float noiseFilterFreq;
+
+ } _t808Snare;
- float toneNoiseMix;
+ typedef _t808Snare* t808Snare;
- float tone1Freq, tone2Freq;
+ void t808Snare_init (t808Snare* const);
+ void t808Snare_free (t808Snare* const);
- float noiseFilterFreq;
+ float t808Snare_tick (t808Snare* const);
+ void t808Snare_on (t808Snare* const, float vel);
+ void t808Snare_setTone1Freq (t808Snare* const, float freq);
+ void t808Snare_setTone2Freq (t808Snare* const, float freq);
+ void t808Snare_setTone1Decay (t808Snare* const, float decay);
+ void t808Snare_setTone2Decay (t808Snare* const, float decay);
+ void t808Snare_setNoiseDecay (t808Snare* const, float decay);
+ void t808Snare_setToneNoiseMix (t808Snare* const, float toneNoiseMix);
+ void t808Snare_setNoiseFilterFreq (t808Snare* const, float noiseFilterFreq);
+ void t808Snare_setNoiseFilterQ (t808Snare* const, float noiseFilterQ);
+ //==============================================================================
-} t808Snare;
-
-void t808Snare_init (t808Snare* const);
-void t808Snare_free (t808Snare* const);
-
-float t808Snare_tick (t808Snare* const);
-void t808Snare_on (t808Snare* const, float vel);
-void t808Snare_setTone1Freq (t808Snare* const, float freq);
-void t808Snare_setTone2Freq (t808Snare* const, float freq);
-void t808Snare_setTone1Decay (t808Snare* const, float decay);
-void t808Snare_setTone2Decay (t808Snare* const, float decay);
-void t808Snare_setNoiseDecay (t808Snare* const, float decay);
-void t808Snare_setToneNoiseMix (t808Snare* const, float toneNoiseMix);
-void t808Snare_setNoiseFilterFreq (t808Snare* const, float noiseFilterFreq);
-void t808Snare_setNoiseFilterQ (t808Snare* const, float noiseFilterQ);
-
-//==============================================================================
+ // 808 Kick
+ typedef struct _t808Kick {
+
+
+ tCycle tone; // Tri
+ tNoise noiseOsc;
+ tSVF toneLowpass;
+ tEnvelope toneEnvOscChirp;
+ tEnvelope toneEnvOscSigh;
+ tEnvelope toneEnvGain;
+ tEnvelope noiseEnvGain;
+ tEnvelope toneEnvFilter;
+
+ float toneGain;
+ float noiseGain;
+
+ float toneInitialFreq;
+ float sighAmountInHz;
+ float chirpRatioMinusOne;
+ float noiseFilterFreq;
+
+ } _t808Kick;
-// 808 Kick
-typedef struct _t808Kick {
-
-
- tCycle tone; // Tri
- tNoise noiseOsc;
- tSVF toneLowpass;
- tEnvelope toneEnvOscChirp;
- tEnvelope toneEnvOscSigh;
- tEnvelope toneEnvGain;
- tEnvelope noiseEnvGain;
- tEnvelope toneEnvFilter;
-
- float toneGain;
- float noiseGain;
-
- float toneInitialFreq;
- float sighAmountInHz;
- float chirpRatioMinusOne;
- float noiseFilterFreq;
-
-
-} t808Kick;
-
-void t808Kick_init (t808Kick* const);
-void t808Kick_free (t808Kick* const);
-
-float t808Kick_tick (t808Kick* const);
-void t808Kick_on (t808Kick* const, float vel);
-void t808Kick_setToneFreq (t808Kick* const, float freq);
-void t808Kick_setToneDecay (t808Kick* const, float decay);
-void t808Kick_setNoiseDecay (t808Kick* const, float decay);
-void t808Kick_setSighAmount (t808Kick* const, float sigh);
-void t808Kick_setChirpAmount (t808Kick* const, float chirp);
-void t808Kick_setToneNoiseMix (t808Kick* const, float toneNoiseMix);
-void t808Kick_setNoiseFilterFreq (t808Kick* const, float noiseFilterFreq);
-void t808Kick_setNoiseFilterQ (t808Kick* const, float noiseFilterQ);
+ typedef _t808Kick* t808Kick;
-//==============================================================================
+ void t808Kick_init (t808Kick* const);
+ void t808Kick_free (t808Kick* const);
+ float t808Kick_tick (t808Kick* const);
+ void t808Kick_on (t808Kick* const, float vel);
+ void t808Kick_setToneFreq (t808Kick* const, float freq);
+ void t808Kick_setToneDecay (t808Kick* const, float decay);
+ void t808Kick_setNoiseDecay (t808Kick* const, float decay);
+ void t808Kick_setSighAmount (t808Kick* const, float sigh);
+ void t808Kick_setChirpAmount (t808Kick* const, float chirp);
+ void t808Kick_setToneNoiseMix (t808Kick* const, float toneNoiseMix);
+ void t808Kick_setNoiseFilterFreq (t808Kick* const, float noiseFilterFreq);
+ void t808Kick_setNoiseFilterQ (t808Kick* const, float noiseFilterQ);
+
+ //==============================================================================
+
#ifdef __cplusplus
}
#endif
@@ -180,5 +187,6 @@
#endif // LEAF_INSTRUMENTS_H_INCLUDED
//==============================================================================
+
--- a/LEAF/Inc/leaf-midi.h
+++ b/LEAF/Inc/leaf-midi.h
@@ -1,11 +1,11 @@
/*==============================================================================
+
+ leaf-midi.h
+ Created: 30 Nov 2018 11:29:26am
+ Author: airship
+
+ ==============================================================================*/
- leaf-midi.h
- Created: 30 Nov 2018 11:29:26am
- Author: airship
-
-==============================================================================*/
-
#ifndef LEAF_MIDI_H_INCLUDED
#define LEAF_MIDI_H_INCLUDED
@@ -13,104 +13,108 @@
extern "C" {
#endif
-//==============================================================================
+ //==============================================================================
#include "leaf-global.h"
#include "leaf-mempool.h"
#include "leaf-math.h"
#include "leaf-envelopes.h"
-
-//==============================================================================
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-
-// STACK implementation (fixed size)
-#define STACK_SIZE 128
-typedef struct _tStack
-{
- int data[STACK_SIZE];
- uint16_t pos;
- uint16_t size;
- uint16_t capacity;
- oBool ordered;
+ //==============================================================================
-} tStack;
-
-void tStack_init (tStack* const);
-void tStack_free (tStack* const);
-
-void tStack_setCapacity (tStack* const, uint16_t cap);
-int tStack_addIfNotAlreadyThere (tStack* const, uint16_t item);
-void tStack_add (tStack* const, uint16_t item);
-int tStack_remove (tStack* const, uint16_t item);
-void tStack_clear (tStack* const);
-int tStack_first (tStack* const);
-int tStack_getSize (tStack* const);
-int tStack_contains (tStack* const, uint16_t item);
-int tStack_next (tStack* const);
-int tStack_get (tStack* const, int which);
+ // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-/* tPoly */
-typedef struct _tPoly
-{
- tStack stack;
- tStack orderStack;
+ // STACK implementation (fixed size)
+#define STACK_SIZE 128
+ typedef struct _tStack
+ {
+ int data[STACK_SIZE];
+ uint16_t pos;
+ uint16_t size;
+ uint16_t capacity;
+ oBool ordered;
+
+ } _tStack;
- tRamp* ramps;
- float* rampVals;
- oBool* firstReceived;
- float glideTime;
- oBool pitchGlideIsActive;
+ typedef _tStack* tStack;
- int numVoices;
- int maxNumVoices;
+ void tStack_init (tStack* const);
+ void tStack_free (tStack* const);
- //int voices[POLY_NUM_MAX_VOICES][2];
- int** voices;
+ void tStack_setCapacity (tStack* const, uint16_t cap);
+ int tStack_addIfNotAlreadyThere (tStack* const, uint16_t item);
+ void tStack_add (tStack* const, uint16_t item);
+ int tStack_remove (tStack* const, uint16_t item);
+ void tStack_clear (tStack* const);
+ int tStack_first (tStack* const);
+ int tStack_getSize (tStack* const);
+ int tStack_contains (tStack* const, uint16_t item);
+ int tStack_next (tStack* const);
+ int tStack_get (tStack* const, int which);
- int notes[128][2];
+ /* tPoly */
+ typedef struct _tPoly
+ {
+ tStack stack;
+ tStack orderStack;
+
+ tRamp* ramps;
+ float* rampVals;
+ oBool* firstReceived;
+ float glideTime;
+ oBool pitchGlideIsActive;
+
+ int numVoices;
+ int maxNumVoices;
+
+ //int voices[POLY_NUM_MAX_VOICES][2];
+ int** voices;
+
+ int notes[128][2];
+
+ int CCs[128];
+
+ uint8_t CCsRaw[128];
+
+ int lastVoiceToChange;
+
+ float pitchBend;
+ tRamp pitchBendRamp;
+
+ int currentNote;
+ int currentVoice;
+ int currentVelocity;
+ int maxLength;
+
+ } _tPoly;
- int CCs[128];
+ typedef _tPoly* tPoly;
- uint8_t CCsRaw[128];
+ /* MPoly*/
+ void tPoly_init(tPoly* const, int maxNumVoices);
+ void tPoly_free(tPoly* const);
- int lastVoiceToChange;
+ //ADDING A NOTE
+ int tPoly_noteOn(tPoly* const, int note, uint8_t vel);
+ int tPoly_noteOff(tPoly* const, uint8_t note);
+ void tPoly_orderedAddToStack(tPoly* const, uint8_t noteVal);
+ void tPoly_setNumVoices(tPoly* const, uint8_t numVoices);
- float pitchBend;
- tRamp pitchBendRamp;
+ void tPoly_setPitchBend(tPoly* const, float pitchBend);
+ void tPoly_setPitchGlideActive(tPoly* const, oBool isActive);
+ void tPoly_setPitchGlideTime(tPoly* const, float t);
+ void tPoly_tickPitch(tPoly* const);
+ void tPoly_tickPitchGlide(tPoly* const);
+ void tPoly_tickPitchBend(tPoly* const);
- int currentNote;
- int currentVoice;
- int currentVelocity;
- int maxLength;
+ int tPoly_getNumVoices(tPoly* const);
+ float tPoly_getPitch(tPoly* const, uint8_t voice);
+ int tPoly_getKey(tPoly* const, uint8_t voice);
+ int tPoly_getVelocity(tPoly* const, uint8_t voice);
+ int tPoly_isOn(tPoly* const, uint8_t voice);
-} tPoly;
-
-/* MPoly*/
-void tPoly_init(tPoly* const, int maxNumVoices);
-void tPoly_free(tPoly* const);
-
-//ADDING A NOTE
-int tPoly_noteOn(tPoly* const, int note, uint8_t vel);
-int tPoly_noteOff(tPoly* const, uint8_t note);
-void tPoly_orderedAddToStack(tPoly* const, uint8_t noteVal);
-void tPoly_setNumVoices(tPoly* const, uint8_t numVoices);
-
-void tPoly_setPitchBend(tPoly* const, float pitchBend);
-void tPoly_setPitchGlideActive(tPoly* const, oBool isActive);
-void tPoly_setPitchGlideTime(tPoly* const, float t);
-void tPoly_tickPitch(tPoly* const);
-void tPoly_tickPitchGlide(tPoly* const);
-void tPoly_tickPitchBend(tPoly* const);
+ //==============================================================================
-int tPoly_getNumVoices(tPoly* const);
-float tPoly_getPitch(tPoly* const, uint8_t voice);
-int tPoly_getKey(tPoly* const, uint8_t voice);
-int tPoly_getVelocity(tPoly* const, uint8_t voice);
-int tPoly_isOn(tPoly* const, uint8_t voice);
-
-//==============================================================================
-
#ifdef __cplusplus
}
#endif
@@ -118,4 +122,5 @@
#endif // LEAF_MIDI_H_INCLUDED
//==============================================================================
+
--- a/LEAF/Inc/leaf-oscillators.h
+++ b/LEAF/Inc/leaf-oscillators.h
@@ -1,11 +1,11 @@
/*==============================================================================
+
+ leaf-oscillators.h
+ Created: 20 Jan 2017 12:00:58pm
+ Author: Michael R Mulshine
+
+ ==============================================================================*/
- leaf-oscillators.h
- Created: 20 Jan 2017 12:00:58pm
- Author: Michael R Mulshine
-
-==============================================================================*/
-
#ifndef LEAF_OSCILLATORS_H_INCLUDED
#define LEAF_OSCILLATORS_H_INCLUDED
@@ -12,169 +12,184 @@
#ifdef __cplusplus
extern "C" {
#endif
-
-//==============================================================================
-
+
+ //==============================================================================
+
#include "leaf-math.h"
#include "leaf-filters.h"
-
-//==============================================================================
-
-/* tCycle: Cycle/Sine waveform. Wavetable synthesis.*/
-typedef struct _tCycle
-{
- // Underlying phasor
- float phase;
- float inc,freq;
-} tCycle;
-
-void tCycle_init (tCycle* const);
-void tCycle_free (tCycle* const);
-
-float tCycle_tick (tCycle* const);
-int tCycle_setFreq (tCycle* const, float freq);
-
-//==============================================================================
-
-/* tTriangle: Anti-aliased Triangle waveform using wavetable interpolation. Wavetables constructed from sine components. */
-typedef struct _tTriangle
-{
- // Underlying phasor
- float phase;
- float inc,freq;
+ //==============================================================================
-} tTriangle;
-
-void tTriangle_init (tTriangle* const);
-void tTriangle_free (tTriangle* const);
-
-float tTriangle_tick (tTriangle* const);
-int tTriangle_setFreq (tTriangle* const, float freq);
-
-//==============================================================================
-
-/* tSquare: Anti-aliased Square waveform using wavetable interpolation. Wavetables constructed from sine components. */
-typedef struct _tSquare
-{
- // Underlying phasor
- float phase;
- float inc,freq;
+ /* tCycle: Cycle/Sine waveform. Wavetable synthesis.*/
+ typedef struct _tCycle
+ {
+ // Underlying phasor
+ float phase;
+ float inc,freq;
+
+ } _tCycle;
-} tSquare;
-
-void tSquare_init (tSquare* const);
-void tSquare_free (tSquare* const);
-
-float tSquare_tick (tSquare* const);
-int tSquare_setFreq (tSquare* const, float freq);
+ typedef _tCycle* tCycle;
-//==============================================================================
-
-/* tSawtooth: Anti-aliased Sawtooth waveform using wavetable interpolation. Wavetables constructed from sine components. */
-typedef struct _tSawtooth
-{
- // Underlying phasor
- float phase;
- float inc,freq;
+ void tCycle_init (tCycle* const);
+ void tCycle_free (tCycle* const);
-} tSawtooth;
-
-void tSawtooth_init (tSawtooth* const);
-void tSawtooth_free (tSawtooth* const);
-
-float tSawtooth_tick (tSawtooth* const);
-int tSawtooth_setFreq (tSawtooth* const, float freq);
+ float tCycle_tick (tCycle* const);
+ void tCycle_setFreq (tCycle* const, float freq);
-//==============================================================================
-
-/* tPhasor: Aliasing phasor [0.0, 1.0) */
-typedef struct _tPhasor
-{
- float phase;
- float inc,freq;
+ //==============================================================================
-} tPhasor;
-
-void tPhasor_init (tPhasor* const);
-void tPhasor_free (tPhasor* const);
-
-float tPhasor_tick (tPhasor* const);
-int tPhasor_setFreq (tPhasor* const, float freq);
-
-//==============================================================================
-
-/* tNoise. WhiteNoise, PinkNoise. */
-typedef enum NoiseType
-{
- WhiteNoise=0,
- PinkNoise,
- NoiseTypeNil,
-} NoiseType;
-
-typedef struct _tNoise
-{
- NoiseType type;
- float pinkb0, pinkb1, pinkb2;
- float(*rand)(void);
+ /* tTriangle: Anti-aliased Triangle waveform using wavetable interpolation. Wavetables constructed from sine components. */
+ typedef struct _tTriangle
+ {
+ // Underlying phasor
+ float phase;
+ float inc,freq;
+
+ } _tTriangle;
-} tNoise;
-
-void tNoise_init (tNoise* const, NoiseType type);
-void tNoise_free (tNoise* const);
-
-float tNoise_tick (tNoise* const);
+ typedef _tTriangle* tTriangle;
-//==============================================================================
-
-/* tNeuron */
-typedef enum NeuronMode
-{
- NeuronNormal = 0,
- NeuronTanh,
- NeuronAaltoShaper,
- NeuronModeNil
-} NeuronMode;
-
-typedef struct _tNeuron
-{
- tPoleZero f;
+ void tTriangle_init (tTriangle* const);
+ void tTriangle_free (tTriangle* const);
- NeuronMode mode;
+ float tTriangle_tick (tTriangle* const);
+ int tTriangle_setFreq (tTriangle* const, float freq);
- float voltage, current;
- float timeStep;
+ //==============================================================================
- float alpha[3];
- float beta[3];
- float rate[3];
- float V[3];
- float P[3];
- float gK, gN, gL, C;
-} tNeuron;
-
-void tNeuron_init (tNeuron* const);
-void tNeuron_free (tNeuron* const);
-
-void tNeuron_reset (tNeuron* const);
-float tNeuron_Tick (tNeuron* const);
-void tNeuron_setMode (tNeuron* const, NeuronMode mode);
-void tNeuron_setCurrent (tNeuron* const, float current);
-void tNeuron_setK (tNeuron* const, float K);
-void tNeuron_setL (tNeuron* const, float L);
-void tNeuron_setN (tNeuron* const, float N);
-void tNeuron_setC (tNeuron* const, float C);
-void tNeuron_setV1 (tNeuron* const, float V1);
-void tNeuron_setV2 (tNeuron* const, float V2);
-void tNeuron_setV3 (tNeuron* const, float V3);
-void tNeuron_setTimeStep (tNeuron* const, float timestep);
-
-//==============================================================================
+ /* tSquare: Anti-aliased Square waveform using wavetable interpolation. Wavetables constructed from sine components. */
+ typedef struct _tSquare
+ {
+ // Underlying phasor
+ float phase;
+ float inc,freq;
+
+ } _tSquare;
+ typedef _tSquare* tSquare;
+
+ void tSquare_init (tSquare* const);
+ void tSquare_free (tSquare* const);
+
+ float tSquare_tick (tSquare* const);
+ int tSquare_setFreq (tSquare* const, float freq);
+
+ //==============================================================================
+
+ /* tSawtooth: Anti-aliased Sawtooth waveform using wavetable interpolation. Wavetables constructed from sine components. */
+ typedef struct _tSawtooth
+ {
+ // Underlying phasor
+ float phase;
+ float inc,freq;
+
+ } _tSawtooth;
+
+ typedef _tSawtooth* tSawtooth;
+
+ void tSawtooth_init (tSawtooth* const);
+ void tSawtooth_free (tSawtooth* const);
+
+ float tSawtooth_tick (tSawtooth* const);
+ int tSawtooth_setFreq (tSawtooth* const, float freq);
+
+ //==============================================================================
+
+ /* tPhasor: Aliasing phasor [0.0, 1.0) */
+ typedef struct _tPhasor
+ {
+ float phase;
+ float inc,freq;
+
+ } _tPhasor;
+
+ typedef _tPhasor* tPhasor;
+
+ void tPhasor_init (tPhasor* const);
+ void tPhasor_free (tPhasor* const);
+
+ float tPhasor_tick (tPhasor* const);
+ int tPhasor_setFreq (tPhasor* const, float freq);
+
+ //==============================================================================
+
+ /* tNoise. WhiteNoise, PinkNoise. */
+ typedef enum NoiseType
+ {
+ WhiteNoise=0,
+ PinkNoise,
+ NoiseTypeNil,
+ } NoiseType;
+
+ typedef struct _tNoise
+ {
+ NoiseType type;
+ float pinkb0, pinkb1, pinkb2;
+ float(*rand)(void);
+
+ } _tNoise;
+
+ typedef _tNoise* tNoise;
+
+ void tNoise_init (tNoise* const, NoiseType type);
+ void tNoise_free (tNoise* const);
+
+ float tNoise_tick (tNoise* const);
+
+ //==============================================================================
+
+ /* tNeuron */
+ typedef enum NeuronMode
+ {
+ NeuronNormal = 0,
+ NeuronTanh,
+ NeuronAaltoShaper,
+ NeuronModeNil
+ } NeuronMode;
+
+ typedef struct _tNeuron
+ {
+ tPoleZero f;
+
+ NeuronMode mode;
+
+ float voltage, current;
+ float timeStep;
+
+ float alpha[3];
+ float beta[3];
+ float rate[3];
+ float V[3];
+ float P[3];
+ float gK, gN, gL, C;
+ } _tNeuron;
+
+ typedef _tNeuron* tNeuron;
+
+ void tNeuron_init (tNeuron* const);
+ void tNeuron_free (tNeuron* const);
+
+ void tNeuron_reset (tNeuron* const);
+ float tNeuron_Tick (tNeuron* const);
+ void tNeuron_setMode (tNeuron* const, NeuronMode mode);
+ void tNeuron_setCurrent (tNeuron* const, float current);
+ void tNeuron_setK (tNeuron* const, float K);
+ void tNeuron_setL (tNeuron* const, float L);
+ void tNeuron_setN (tNeuron* const, float N);
+ void tNeuron_setC (tNeuron* const, float C);
+ void tNeuron_setV1 (tNeuron* const, float V1);
+ void tNeuron_setV2 (tNeuron* const, float V2);
+ void tNeuron_setV3 (tNeuron* const, float V3);
+ void tNeuron_setTimeStep (tNeuron* const, float timestep);
+
+ //==============================================================================
+
#ifdef __cplusplus
}
#endif
-
+
#endif // LEAF_OSCILLATORS_H_INCLUDED
//==============================================================================
+
--- a/LEAF/Inc/leaf-physical.h
+++ b/LEAF/Inc/leaf-physical.h
@@ -1,13 +1,13 @@
/*
- ==============================================================================
+ ==============================================================================
+
+ leaf-physical.h
+ Created: 30 Nov 2018 10:41:55am
+ Author: airship
+
+ ==============================================================================
+ */
- leaf-physical.h
- Created: 30 Nov 2018 10:41:55am
- Author: airship
-
- ==============================================================================
-*/
-
#ifndef LEAF_PHYSICAL_H_INCLUDED
#define LEAF_PHYSICAL_H_INCLUDED
@@ -15,8 +15,8 @@
extern "C" {
#endif
-//==============================================================================
-
+ //==============================================================================
+
#include "leaf-global.h"
#include "leaf-math.h"
#include "leaf-delay.h"
@@ -24,194 +24,202 @@
#include "leaf-oscillators.h"
#include "leaf-envelopes.h"
#include "leaf-dynamics.h"
-
-//==============================================================================
-
-/* Karplus Strong model */
-typedef struct _tPluck
-{
- tAllpassDelay delayLine; // Allpass or Linear?? big difference...
- tOneZero loopFilter;
- tOnePole pickFilter;
- tNoise noise;
- float lastOut;
- float loopGain;
- float lastFreq;
+ //==============================================================================
- float sr;
+ /* Karplus Strong model */
+ typedef struct _tPluck
+ {
+ tAllpassDelay delayLine; // Allpass or Linear?? big difference...
+ tOneZero loopFilter;
+ tOnePole pickFilter;
+ tNoise noise;
+
+ float lastOut;
+ float loopGain;
+ float lastFreq;
+
+ float sr;
+
+ } _tPluck;
-} tPluck;
-
-void tPluck_init (tPluck* const, float lowestFrequency); //float delayBuff[DELAY_LENGTH]);
-void tPluck_free (tPluck* const);
-
-float tPluck_tick (tPluck* const);
-
-// Pluck the string.
-void tPluck_pluck (tPluck* const, float amplitude);
-
-// Start a note with the given frequency and amplitude.;
-void tPluck_noteOn (tPluck* const, float frequency, float amplitude );
-
-// Stop a note with the given amplitude (speed of decay).
-void tPluck_noteOff (tPluck* const, float amplitude );
-
-// Set instrument parameters for a particular frequency.
-void tPluck_setFrequency (tPluck* const, float frequency );
-
-// Perform the control change specified by \e number and \e value (0.0 - 128.0).
-void tPluck_controlChange (tPluck* const, int number, float value);
-
-// tPluck Utilities.
-float tPluck_getLastOut (tPluck* const);
-
-//==============================================================================
+ typedef _tPluck* tPluck;
-/* Stif Karplus Strong model */
-typedef struct _tKarplusStrong
-{
- tAllpassDelay delayLine;
- tLinearDelay combDelay;
- tOneZero filter;
- tNoise noise;
- tBiQuad biquad[4];
+ void tPluck_init (tPluck* const, float lowestFrequency); //float delayBuff[DELAY_LENGTH]);
+ void tPluck_free (tPluck* const);
+ float tPluck_tick (tPluck* const);
+ // Pluck the string.
+ void tPluck_pluck (tPluck* const, float amplitude);
- uint32_t length;
- float loopGain;
- float baseLoopGain;
- float lastFrequency;
- float lastLength;
- float stretching;
- float pluckAmplitude;
- float pickupPosition;
+ // Start a note with the given frequency and amplitude.;
+ void tPluck_noteOn (tPluck* const, float frequency, float amplitude );
- float lastOut;
+ // Stop a note with the given amplitude (speed of decay).
+ void tPluck_noteOff (tPluck* const, float amplitude );
-} tKarplusStrong;
-
-typedef enum SKControlType
-{
- SKPickPosition = 0,
- SKStringDamping,
- SKDetune,
- SKControlTypeNil
-} SKControlType;
-
-void tKarplusStrong_init (tKarplusStrong* const, float lowestFrequency); // float delayBuff[2][DELAY_LENGTH]);
-void tKarplusStrong_free (tKarplusStrong* const);
-
-float tKarplusStrong_tick (tKarplusStrong* const);
-
-// Pluck the string.
-void tKarplusStrong_pluck (tKarplusStrong* const, float amplitude);
-
-// Start a note with the given frequency and amplitude.;
-void tKarplusStrong_noteOn (tKarplusStrong* const, float frequency, float amplitude );
-
-// Stop a note with the given amplitude (speed of decay).
-void tKarplusStrong_noteOff (tKarplusStrong* const, float amplitude );
-
-// Set instrument parameters for a particular frequency.
-void tKarplusStrong_setFrequency (tKarplusStrong* const, float frequency );
-
-// Perform the control change specified by \e number and \e value (0.0 - 128.0).
-// Use SKPickPosition, SKStringDamping, or SKDetune for type.
-void tKarplusStrong_controlChange (tKarplusStrong* const, SKControlType type, float value);
-
-// Set the stretch "factor" of the string (0.0 - 1.0).
-void tKarplusStrong_setStretch (tKarplusStrong* const, float stretch );
-
-// Set the pluck or "excitation" position along the string (0.0 - 1.0).
-void tKarplusStrong_setPickupPosition (tKarplusStrong* const, float position );
-
-// Set the base loop gain.
-void tKarplusStrong_setBaseLoopGain (tKarplusStrong* const, float aGain );
-
-// tKarplusStrong utilities.
-float tKarplusStrong_getLastOut (tKarplusStrong* const);
+ // Set instrument parameters for a particular frequency.
+ void tPluck_setFrequency (tPluck* const, float frequency );
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-
-/* Simple Living String */
-typedef struct _tSimpleLivingString {
- float freq, waveLengthInSamples; // the frequency of the string, determining delay length
- float dampFreq; // frequency for the bridge LP filter, in Hz
- float decay; // amplitude damping factor for the string (only active in mode 0)
- float levMode;
- float curr;
- tLinearDelay delayLine;
- tOnePole bridgeFilter;
- tHighpass DCblocker;
- tFeedbackLeveler fbLev;
- tExpSmooth wlSmooth;
-} tSimpleLivingString;
-
-void tSimpleLivingString_init (tSimpleLivingString* const, float freq, float dampFreq, float decay, float targetLev, float levSmoothFactor, float levStrength, int levMode);
-void tSimpleLivingString_free (tSimpleLivingString* const);
-float tSimpleLivingString_tick (tSimpleLivingString* const, float input);
-float tSimpleLivingString_sample (tSimpleLivingString* const);
-int tSimpleLivingString_setFreq (tSimpleLivingString* const, float freq);
-int tSimpleLivingString_setWaveLength (tSimpleLivingString* const, float waveLength); // in samples
-int tSimpleLivingString_setDampFreq (tSimpleLivingString* const, float dampFreq);
-int tSimpleLivingString_setDecay (tSimpleLivingString* const, float decay); // should be near 1.0
-int tSimpleLivingString_setTargetLev (tSimpleLivingString* const, float targetLev);
-int tSimpleLivingString_setLevSmoothFactor (tSimpleLivingString* const, float levSmoothFactor);
-int tSimpleLivingString_setLevStrength (tSimpleLivingString* const, float levStrength);
-int tSimpleLivingString_setLevMode (tSimpleLivingString* const, int levMode);
-
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-
-/* Living String */
-typedef struct _tLivingString {
- float freq, waveLengthInSamples; // the frequency of the whole string, determining delay length
- float pickPos; // the pick position, dividing the string in two, in ratio
- float prepIndex; // the amount of pressure on the pickpoint of the string (near 0=soft obj, near 1=hard obj)
- float dampFreq; // frequency for the bridge LP filter, in Hz
- float decay; // amplitude damping factor for the string (only active in mode 0)
- float levMode;
- float curr;
- tLinearDelay delLF,delUF,delUB,delLB; // delay for lower/upper/forward/backward part of the waveguide model
- tOnePole bridgeFilter, nutFilter, prepFilterU, prepFilterL;
- tHighpass DCblockerL, DCblockerU;
- tFeedbackLeveler fbLevU, fbLevL;
- tExpSmooth wlSmooth, ppSmooth;
-} tLivingString;
-
-void tLivingString_init (tLivingString* const, float freq, float pickPos, float prepIndex, float dampFreq, float decay,
- float targetLev, float levSmoothFactor, float levStrength, int levMode);
-void tLivingString_free (tLivingString* const);
-float tLivingString_tick (tLivingString* const, float input);
-float tLivingString_sample (tLivingString* const);
-int tLivingString_setFreq (tLivingString* const, float freq);
-int tLivingString_setWaveLength (tLivingString* const, float waveLength); // in samples
-int tLivingString_setPickPos (tLivingString* const, float pickPos);
-int tLivingString_setPrepIndex (tLivingString* const, float prepIndex);
-int tLivingString_setDampFreq (tLivingString* const, float dampFreq);
-int tLivingString_setDecay (tLivingString* const, float decay); // should be near 1.0
-int tLivingString_setTargetLev (tLivingString* const, float targetLev);
-int tLivingString_setLevSmoothFactor (tLivingString* const, float levSmoothFactor);
-int tLivingString_setLevStrength (tLivingString* const, float levStrength);
-int tLivingString_setLevMode (tLivingString* const, int levMode);
+ // Perform the control change specified by \e number and \e value (0.0 - 128.0).
+ void tPluck_controlChange (tPluck* const, int number, float value);
-// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
-
-//Reed Table - borrowed from STK
-typedef struct _tReedTable {
- float offset, slope;
-} tReedTable;
-
-void tReedTable_init (tReedTable* const, float offset, float slope);
-void tReedTable_free (tReedTable* const);
-float tReedTable_tick (tReedTable* const, float input);
-float tReedTable_tanh_tick (tReedTable* const p, float input); //tanh softclip version of reed table - replacing the hard clip in original stk code
-void tReedTable_setOffset (tReedTable* const, float offset);
-void tReedTable_setSlope (tReedTable* const, float slope);
-
-//==============================================================================
+ // tPluck Utilities.
+ float tPluck_getLastOut (tPluck* const);
+ //==============================================================================
+
+ typedef enum SKControlType
+ {
+ SKPickPosition = 0,
+ SKStringDamping,
+ SKDetune,
+ SKControlTypeNil
+ } SKControlType;
+
+ /* Stif Karplus Strong model */
+ typedef struct _tKarplusStrong
+ {
+ tAllpassDelay delayLine;
+ tLinearDelay combDelay;
+ tOneZero filter;
+ tNoise noise;
+ tBiQuad biquad[4];
+
+ uint32_t length;
+ float loopGain;
+ float baseLoopGain;
+ float lastFrequency;
+ float lastLength;
+ float stretching;
+ float pluckAmplitude;
+ float pickupPosition;
+
+ float lastOut;
+
+ } _tKarplusStrong;
+
+ typedef _tKarplusStrong* tKarplusStrong;
+
+ void tKarplusStrong_init (tKarplusStrong* const, float lowestFrequency); // float delayBuff[2][DELAY_LENGTH]);
+ void tKarplusStrong_free (tKarplusStrong* const);
+
+ float tKarplusStrong_tick (tKarplusStrong* const);
+
+ // Pluck the string.
+ void tKarplusStrong_pluck (tKarplusStrong* const, float amplitude);
+
+ // Start a note with the given frequency and amplitude.;
+ void tKarplusStrong_noteOn (tKarplusStrong* const, float frequency, float amplitude );
+
+ // Stop a note with the given amplitude (speed of decay).
+ void tKarplusStrong_noteOff (tKarplusStrong* const, float amplitude );
+
+ // Set instrument parameters for a particular frequency.
+ void tKarplusStrong_setFrequency (tKarplusStrong* const, float frequency );
+
+ // Perform the control change specified by \e number and \e value (0.0 - 128.0).
+ // Use SKPickPosition, SKStringDamping, or SKDetune for type.
+ void tKarplusStrong_controlChange (tKarplusStrong* const, SKControlType type, float value);
+
+ // Set the stretch "factor" of the string (0.0 - 1.0).
+ void tKarplusStrong_setStretch (tKarplusStrong* const, float stretch );
+
+ // Set the pluck or "excitation" position along the string (0.0 - 1.0).
+ void tKarplusStrong_setPickupPosition (tKarplusStrong* const, float position );
+
+ // Set the base loop gain.
+ void tKarplusStrong_setBaseLoopGain (tKarplusStrong* const, float aGain );
+
+ // tKarplusStrong utilities.
+ float tKarplusStrong_getLastOut (tKarplusStrong* const);
+
+ // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
+ /* Simple Living String */
+ typedef struct _tSimpleLivingString {
+ float freq, waveLengthInSamples; // the frequency of the string, determining delay length
+ float dampFreq; // frequency for the bridge LP filter, in Hz
+ float decay; // amplitude damping factor for the string (only active in mode 0)
+ float levMode;
+ float curr;
+ tLinearDelay delayLine;
+ tOnePole bridgeFilter;
+ tHighpass DCblocker;
+ tFeedbackLeveler fbLev;
+ tExpSmooth wlSmooth;
+ } _tSimpleLivingString;
+
+ typedef _tSimpleLivingString* tSimpleLivingString;
+
+ void tSimpleLivingString_init (tSimpleLivingString* const, float freq, float dampFreq, float decay, float targetLev, float levSmoothFactor, float levStrength, int levMode);
+ void tSimpleLivingString_free (tSimpleLivingString* const);
+ float tSimpleLivingString_tick (tSimpleLivingString* const, float input);
+ float tSimpleLivingString_sample (tSimpleLivingString* const);
+ void tSimpleLivingString_setFreq (tSimpleLivingString* const, float freq);
+ void tSimpleLivingString_setWaveLength (tSimpleLivingString* const, float waveLength); // in samples
+ void tSimpleLivingString_setDampFreq (tSimpleLivingString* const, float dampFreq);
+ void tSimpleLivingString_setDecay (tSimpleLivingString* const, float decay); // should be near 1.0
+ void tSimpleLivingString_setTargetLev (tSimpleLivingString* const, float targetLev);
+ void tSimpleLivingString_setLevSmoothFactor (tSimpleLivingString* const, float levSmoothFactor);
+ void tSimpleLivingString_setLevStrength (tSimpleLivingString* const, float levStrength);
+ void tSimpleLivingString_setLevMode (tSimpleLivingString* const, int levMode);
+
+ // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
+ /* Living String */
+ typedef struct _tLivingString {
+ float freq, waveLengthInSamples; // the frequency of the whole string, determining delay length
+ float pickPos; // the pick position, dividing the string in two, in ratio
+ float prepIndex; // the amount of pressure on the pickpoint of the string (near 0=soft obj, near 1=hard obj)
+ float dampFreq; // frequency for the bridge LP filter, in Hz
+ float decay; // amplitude damping factor for the string (only active in mode 0)
+ float levMode;
+ float curr;
+ tLinearDelay delLF,delUF,delUB,delLB; // delay for lower/upper/forward/backward part of the waveguide model
+ tOnePole bridgeFilter, nutFilter, prepFilterU, prepFilterL;
+ tHighpass DCblockerL, DCblockerU;
+ tFeedbackLeveler fbLevU, fbLevL;
+ tExpSmooth wlSmooth, ppSmooth;
+ } _tLivingString;
+
+ typedef _tLivingString* tLivingString;
+
+ void tLivingString_init (tLivingString* const, float freq, float pickPos, float prepIndex, float dampFreq, float decay,
+ float targetLev, float levSmoothFactor, float levStrength, int levMode);
+ void tLivingString_free (tLivingString* const);
+ float tLivingString_tick (tLivingString* const, float input);
+ float tLivingString_sample (tLivingString* const);
+ void tLivingString_setFreq (tLivingString* const, float freq);
+ void tLivingString_setWaveLength (tLivingString* const, float waveLength); // in samples
+ void tLivingString_setPickPos (tLivingString* const, float pickPos);
+ void tLivingString_setPrepIndex (tLivingString* const, float prepIndex);
+ void tLivingString_setDampFreq (tLivingString* const, float dampFreq);
+ void tLivingString_setDecay (tLivingString* const, float decay); // should be near 1.0
+ void tLivingString_setTargetLev (tLivingString* const, float targetLev);
+ void tLivingString_setLevSmoothFactor (tLivingString* const, float levSmoothFactor);
+ void tLivingString_setLevStrength (tLivingString* const, float levStrength);
+ void tLivingString_setLevMode (tLivingString* const, int levMode);
+
+ // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
+ //Reed Table - borrowed from STK
+ typedef struct _tReedTable {
+ float offset, slope;
+ } _tReedTable;
+
+ typedef _tReedTable* tReedTable;
+
+ void tReedTable_init (tReedTable* const, float offset, float slope);
+ void tReedTable_free (tReedTable* const);
+ float tReedTable_tick (tReedTable* const, float input);
+ float tReedTable_tanh_tick (tReedTable* const p, float input); //tanh softclip version of reed table - replacing the hard clip in original stk code
+ void tReedTable_setOffset (tReedTable* const, float offset);
+ void tReedTable_setSlope (tReedTable* const, float slope);
+
+ //==============================================================================
+
#ifdef __cplusplus
}
#endif
@@ -219,3 +227,4 @@
#endif // LEAF_PHYSICAL_H_INCLUDED
//==============================================================================
+
--- a/LEAF/Inc/leaf-reverb.h
+++ b/LEAF/Inc/leaf-reverb.h
@@ -1,11 +1,11 @@
/*==============================================================================
+
+ leaf-reverb.h
+ Created: 20 Jan 2017 12:02:04pm
+ Author: Michael R Mulshine
+
+ ==============================================================================*/
- leaf-reverb.h
- Created: 20 Jan 2017 12:02:04pm
- Author: Michael R Mulshine
-
-==============================================================================*/
-
#ifndef LEAF_REVERB_H_INCLUDED
#define LEAF_REVERB_H_INCLUDED
@@ -12,132 +12,138 @@
#ifdef __cplusplus
extern "C" {
#endif
-
-//==============================================================================
+ //==============================================================================
+
#include "leaf-global.h"
#include "leaf-math.h"
#include "leaf-delay.h"
#include "leaf-filters.h"
#include "leaf-oscillators.h"
-
-//==============================================================================
-
-/* PRCReverb: Reverb, reimplemented from STK (Cook and Scavone). */
-typedef struct _tPRCReverb
-{
- float mix, t60;
- float inv_441;
+ //==============================================================================
- tDelay allpassDelays[2];
- tDelay combDelay;
- float allpassCoeff;
- float combCoeff;
+ /* PRCReverb: Reverb, reimplemented from STK (Cook and Scavone). */
+ typedef struct _tPRCReverb
+ {
+ float mix, t60;
+
+ float inv_441;
+
+ tDelay allpassDelays[2];
+ tDelay combDelay;
+ float allpassCoeff;
+ float combCoeff;
+
+ float lastIn, lastOut;
+
+ } _tPRCReverb;
- float lastIn, lastOut;
+ typedef _tPRCReverb* tPRCReverb;
-} tPRCReverb;
-
-void tPRCReverb_init (tPRCReverb* const, float t60);
-void tPRCReverb_free (tPRCReverb* const);
-
-float tPRCReverb_tick (tPRCReverb* const, float input);
-
-// Set reverb time in seconds.
-void tPRCReverb_setT60 (tPRCReverb* const, float t60);
-
-// Set mix between dry input and wet output signal.
-void tPRCReverb_setMix (tPRCReverb* const, float mix);
-
-//==============================================================================
-
-/* NReverb: Reverb, reimplemented from STK (Cook and Scavone). */
-typedef struct _tNReverb
-{
- float mix, t60;
+ void tPRCReverb_init (tPRCReverb* const, float t60);
+ void tPRCReverb_free (tPRCReverb* const);
- float inv_sr, inv_441;
+ float tPRCReverb_tick (tPRCReverb* const, float input);
- tDelay allpassDelays[8];
- tDelay combDelays[6];
- float allpassCoeff;
- float combCoeffs[6];
- float lowpassState;
+ // Set reverb time in seconds.
+ void tPRCReverb_setT60 (tPRCReverb* const, float t60);
- float lastIn, lastOut;
+ // Set mix between dry input and wet output signal.
+ void tPRCReverb_setMix (tPRCReverb* const, float mix);
-} tNReverb;
-
-void tNReverb_init (tNReverb* const, float t60);
-void tNReverb_free (tNReverb* const);
-
-float tNReverb_tick (tNReverb* const, float input);
-
-// Set reverb time in seconds.
-void tNReverb_setT60 (tNReverb* const, float t60);
-
-// Set mix between dry input and wet output signal.
-void tNReverb_setMix (tNReverb* const, float mix);
-
-//==============================================================================
-
-typedef struct _tDattorroReverb
-{
- float predelay;
- float input_filter;
- float feedback_filter;
- float feedback_gain;
- float mix;
+ //==============================================================================
+ /* NReverb: Reverb, reimplemented from STK (Cook and Scavone). */
+ typedef struct _tNReverb
+ {
+ float mix, t60;
+
+ float inv_sr, inv_441;
+
+ tDelay allpassDelays[8];
+ tDelay combDelays[6];
+ float allpassCoeff;
+ float combCoeffs[6];
+ float lowpassState;
+
+ float lastIn, lastOut;
+
+ } _tNReverb;
- float size, size_max, t;
+ typedef _tNReverb* tNReverb;
- float f1_delay_2_last,
- f2_delay_2_last;
+ void tNReverb_init (tNReverb* const, float t60);
+ void tNReverb_free (tNReverb* const);
- float f1_last,
- f2_last;
+ float tNReverb_tick (tNReverb* const, float input);
- // INPUT
- tTapeDelay in_delay;
- tOnePole in_filter;
- tAllpass in_allpass[4];
+ // Set reverb time in seconds.
+ void tNReverb_setT60 (tNReverb* const, float t60);
- // FEEDBACK 1
- tAllpass f1_allpass;
- tTapeDelay f1_delay_1;
- tOnePole f1_filter;
- tTapeDelay f1_delay_2;
- tTapeDelay f1_delay_3;
- tHighpass f1_hp;
+ // Set mix between dry input and wet output signal.
+ void tNReverb_setMix (tNReverb* const, float mix);
- tCycle f1_lfo;
+ //==============================================================================
- // FEEDBACK 2
- tAllpass f2_allpass;
- tTapeDelay f2_delay_1;
- tOnePole f2_filter;
- tTapeDelay f2_delay_2;
- tTapeDelay f2_delay_3;
- tHighpass f2_hp;
+ typedef struct _tDattorroReverb
+ {
+ float predelay;
+ float input_filter;
+ float feedback_filter;
+ float feedback_gain;
+ float mix;
+
+
+ float size, size_max, t;
+
+ float f1_delay_2_last,
+ f2_delay_2_last;
+
+ float f1_last,
+ f2_last;
+
+ // INPUT
+ tTapeDelay in_delay;
+ tOnePole in_filter;
+ tAllpass in_allpass[4];
+
+ // FEEDBACK 1
+ tAllpass f1_allpass;
+ tTapeDelay f1_delay_1;
+ tOnePole f1_filter;
+ tTapeDelay f1_delay_2;
+ tTapeDelay f1_delay_3;
+ tHighpass f1_hp;
+
+ tCycle f1_lfo;
+
+ // FEEDBACK 2
+ tAllpass f2_allpass;
+ tTapeDelay f2_delay_1;
+ tOnePole f2_filter;
+ tTapeDelay f2_delay_2;
+ tTapeDelay f2_delay_3;
+ tHighpass f2_hp;
+
+ tCycle f2_lfo;
+
+ } _tDattorroReverb;
- tCycle f2_lfo;
+ typedef _tDattorroReverb* tDattorroReverb;
-} tDattorroReverb;
-
-void tDattorroReverb_init (tDattorroReverb* const);
-void tDattorroReverb_free (tDattorroReverb* const);
-
-float tDattorroReverb_tick (tDattorroReverb* const, float input);
-
-void tDattorroReverb_setMix (tDattorroReverb* const, float mix);
-void tDattorroReverb_setSize (tDattorroReverb* const, float size);
-void tDattorroReverb_setInputDelay (tDattorroReverb* const, float preDelay);
-void tDattorroReverb_setInputFilter (tDattorroReverb* const, float freq);
-void tDattorroReverb_setFeedbackFilter (tDattorroReverb* const, float freq);
-void tDattorroReverb_setFeedbackGain (tDattorroReverb* const, float gain);
+ void tDattorroReverb_init (tDattorroReverb* const);
+ void tDattorroReverb_free (tDattorroReverb* const);
+ float tDattorroReverb_tick (tDattorroReverb* const, float input);
+
+ void tDattorroReverb_setMix (tDattorroReverb* const, float mix);
+ void tDattorroReverb_setSize (tDattorroReverb* const, float size);
+ void tDattorroReverb_setInputDelay (tDattorroReverb* const, float preDelay);
+ void tDattorroReverb_setInputFilter (tDattorroReverb* const, float freq);
+ void tDattorroReverb_setFeedbackFilter (tDattorroReverb* const, float freq);
+ void tDattorroReverb_setFeedbackGain (tDattorroReverb* const, float gain);
+
#ifdef __cplusplus
}
#endif
@@ -145,3 +151,4 @@
#endif // LEAF_REVERB_H_INCLUDED
//==============================================================================
+
--- a/LEAF/Inc/leaf-sampling.h
+++ b/LEAF/Inc/leaf-sampling.h
@@ -1,12 +1,12 @@
/*==============================================================================
+
+ leaf-sampling.h
+ Created: 23 Jan 2019 11:22:09am
+ Author: Mike Mulshine
+
+ ==============================================================================*/
-leaf-sampling.h
-Created: 23 Jan 2019 11:22:09am
-Author: Mike Mulshine
-==============================================================================*/
-
-
#ifndef LEAF_SAMPLING_H_INCLUDED
#define LEAF_SAMPLING_H_INCLUDED
@@ -13,108 +13,114 @@
#ifdef __cplusplus
extern "C" {
#endif
-
-//==============================================================================
-
+
+ //==============================================================================
+
#include "leaf-global.h"
#include "leaf-math.h"
#include "leaf-envelopes.h"
-
-//==============================================================================
-
-typedef enum RecordMode
-{
- RecordOneShot = 0,
- RecordLoop,
- RecordModeNil
-} RecordMode;
-
-typedef struct _tBuffer
-{
- float* buff;
- uint32_t idx;
- uint32_t length;
+ //==============================================================================
- RecordMode mode;
+ typedef enum RecordMode
+ {
+ RecordOneShot = 0,
+ RecordLoop,
+ RecordModeNil
+ } RecordMode;
- int active;
+ typedef struct _tBuffer
+ {
+ float* buff;
+
+ uint32_t idx;
+ uint32_t length;
+
+ RecordMode mode;
+
+ int active;
+
+ } _tBuffer;
-} tBuffer;
-
-void tBuffer_init (tBuffer* const, uint32_t length);
-void tBuffer_free (tBuffer* const);
-
-void tBuffer_tick (tBuffer* const, float sample);
-
-void tBuffer_read(tBuffer* const, float* buff, uint32_t len);
-
-float tBuffer_get (tBuffer* const, int idx);
-
-void tBuffer_record (tBuffer* const);
-void tBuffer_stop (tBuffer* const);
-
-void tBuffer_setRecordMode (tBuffer* const, RecordMode mode);
-
-void tBuffer_clear (tBuffer* const);
-
-//==============================================================================
-
-typedef enum PlayMode
-{
- PlayNormal,
- PlayLoop,
- PlayBackAndForth,
- PlayModeNil
-} PlayMode;
-
-typedef struct _tSampler
-{
- tBuffer* samp;
+ typedef _tBuffer* tBuffer;
- tRamp gain;
+ void tBuffer_init (tBuffer* const, uint32_t length);
+ void tBuffer_free (tBuffer* const);
- float idx;
- float inc;
- float last;
- float iinc;
- int8_t dir;
- int8_t flip;
- int8_t bnf;
+ void tBuffer_tick (tBuffer* const, float sample);
- int32_t start;
- int32_t end;
- uint32_t len;
- uint32_t cfxlen;
-
- PlayMode mode;
- int retrigger;
+ void tBuffer_read(tBuffer* const, float* buff, uint32_t len);
- int active;
-
-} tSampler;
-
-void tSampler_init (tSampler* const, tBuffer* const);
-void tSampler_free (tSampler* const);
-
-float tSampler_tick (tSampler* const);
-
-void tSampler_setSample (tSampler* const, tBuffer* s);
-
-void tSampler_setMode (tSampler* const, PlayMode mode);
-
-void tSampler_play (tSampler* const);
-void tSampler_stop (tSampler* const);
-
-void tSampler_setStart (tSampler* const, int32_t start);
-void tSampler_setEnd (tSampler* const, int32_t end);
-
-void tSampler_setCrossfadeLength (tSampler* const p, uint32_t length);
-
-void tSampler_setRate (tSampler* const, float rate);
-
-//==============================================================================
-
+ float tBuffer_get (tBuffer* const, int idx);
+
+ void tBuffer_record (tBuffer* const);
+ void tBuffer_stop (tBuffer* const);
+
+ void tBuffer_setRecordMode (tBuffer* const, RecordMode mode);
+
+ void tBuffer_clear (tBuffer* const);
+
+ uint32_t tBuffe_getLength(tBuffer* const);
+
+ //==============================================================================
+
+ typedef enum PlayMode
+ {
+ PlayNormal,
+ PlayLoop,
+ PlayBackAndForth,
+ PlayModeNil
+ } PlayMode;
+
+ typedef struct _tSampler
+ {
+ tBuffer samp;
+
+ tRamp gain;
+
+ float idx;
+ float inc;
+ float last;
+ float iinc;
+ int8_t dir;
+ int8_t flip;
+ int8_t bnf;
+
+ int32_t start;
+ int32_t end;
+ uint32_t len;
+ uint32_t cfxlen;
+
+ PlayMode mode;
+ int retrigger;
+
+ int active;
+
+ } _tSampler;
+
+ typedef _tSampler* tSampler;
+
+ void tSampler_init (tSampler* const, uint32_t length);
+ void tSampler_free (tSampler* const);
+
+ float tSampler_tick (tSampler* const);
+
+ tBuffer tSampler_getBuffer (tSampler* const);
+
+ void tSampler_setMode (tSampler* const, PlayMode mode);
+
+ void tSampler_play (tSampler* const);
+ void tSampler_stop (tSampler* const);
+
+ void tSampler_setStart (tSampler* const, int32_t start);
+ void tSampler_setEnd (tSampler* const, int32_t end);
+
+ void tSampler_setCrossfadeLength (tSampler* const p, uint32_t length);
+
+ void tSampler_setRate (tSampler* const, float rate);
+
+ //==============================================================================
+
#ifdef __cplusplus
}
#endif
@@ -122,3 +128,4 @@
#endif // LEAF_SAMPLING_H_INCLUDED
//==============================================================================
+
--- a/LEAF/Src/leaf-analysis.c
+++ b/LEAF/Src/leaf-analysis.c
@@ -22,41 +22,49 @@
/* Envelope Follower */
//===========================================================================
-void tEnvelopeFollower_init(tEnvelopeFollower* const e, float attackThreshold, float decayCoeff)
+void tEnvelopeFollower_init(tEnvelopeFollower* const ef, float attackThreshold, float decayCoeff)
{
+ _tEnvelopeFollower* e = *ef = (_tEnvelopeFollower*) leaf_alloc(sizeof(_tEnvelopeFollower));
+
e->y = 0.0f;
e->a_thresh = attackThreshold;
e->d_coeff = decayCoeff;
}
-void tEnvelopeFollower_free(tEnvelopeFollower* const e)
+void tEnvelopeFollower_free(tEnvelopeFollower* const ef)
{
+ _tEnvelopeFollower* e = *ef;
+ leaf_free(e);
}
float tEnvelopeFollower_tick(tEnvelopeFollower* const ef, float x)
{
+ _tEnvelopeFollower* e = *ef;
+
if (x < 0.0f ) x = -x; /* Absolute value. */
- if ((x >= ef->y) && (x > ef->a_thresh)) ef->y = x; /* If we hit a peak, ride the peak to the top. */
- else ef->y = ef->y * ef->d_coeff; /* Else, exponential decay of output. */
+ if ((x >= e->y) && (x > e->a_thresh)) e->y = x; /* If we hit a peak, ride the peak to the top. */
+ else e->y = e->y * e->d_coeff; /* Else, exponential decay of output. */
//ef->y = envelope_pow[(uint16_t)(ef->y * (float)UINT16_MAX)] * ef->d_coeff; //not quite the right behavior - too much loss of precision?
//ef->y = powf(ef->y, 1.000009f) * ef->d_coeff; // too expensive
- if( ef->y < VSF) ef->y = 0.0f;
+ if( e->y < VSF) e->y = 0.0f;
- return ef->y;
+ return e->y;
}
int tEnvelopeFollower_decayCoeff(tEnvelopeFollower* const ef, float decayCoeff)
{
- return ef->d_coeff = decayCoeff;
+ _tEnvelopeFollower* e = *ef;
+ return e->d_coeff = decayCoeff;
}
int tEnvelopeFollower_attackThresh(tEnvelopeFollower* const ef, float attackThresh)
{
- return ef->a_thresh = attackThresh;
+ _tEnvelopeFollower* e = *ef;
+ return e->a_thresh = attackThresh;
}
@@ -66,20 +74,26 @@
//===========================================================================
/* Power Follower */
//===========================================================================
-void tPowerFollower_init(tPowerFollower* const p, float factor)
+void tPowerFollower_init(tPowerFollower* const pf, float factor)
{
+ _tPowerFollower* p = *pf = (_tPowerFollower*) leaf_alloc(sizeof(_tPowerFollower));
+
p->curr=0.0f;
p->factor=factor;
p->oneminusfactor=1.0f-factor;
}
-void tPowerFollower_free(tPowerFollower* const p)
+void tPowerFollower_free(tPowerFollower* const pf)
{
+ _tPowerFollower* p = *pf;
+ leaf_free(p);
}
-int tPowerFollower_setFactor(tPowerFollower* const p, float factor)
+int tPowerFollower_setFactor(tPowerFollower* const pf, float factor)
{
+ _tPowerFollower* p = *pf;
+
if (factor<0) factor=0;
if (factor>1) factor=1;
p->factor=factor;
@@ -87,14 +101,16 @@
return 0;
}
-float tPowerFollower_tick(tPowerFollower* const p, float input)
+float tPowerFollower_tick(tPowerFollower* const pf, float input)
{
+ _tPowerFollower* p = *pf;
p->curr = p->factor*input*input+p->oneminusfactor*p->curr;
return p->curr;
}
-float tPowerFollower_sample(tPowerFollower* const p)
+float tPowerFollower_sample(tPowerFollower* const pf)
{
+ _tPowerFollower* p = *pf;
return p->curr;
}
@@ -105,8 +121,10 @@
/* ---------------- env~ - simple envelope follower. ----------------- */
//===========================================================================
-void tEnvPD_init(tEnvPD* const x, int ws, int hs, int bs)
+void tEnvPD_init(tEnvPD* const xpd, int ws, int hs, int bs)
{
+ _tEnvPD* x = *xpd = (_tEnvPD*) leaf_alloc(sizeof(_tEnvPD));
+
int period = hs, npoints = ws;
int i;
@@ -145,18 +163,23 @@
// ~ ~ ~ ~ ~ ~ ~ ~
}
-void tEnvPD_free (tEnvPD* const x)
+void tEnvPD_free (tEnvPD* const xpd)
{
+ _tEnvPD* x = *xpd;
+ leaf_free(x);
}
-float tEnvPD_tick (tEnvPD* const x)
+float tEnvPD_tick (tEnvPD* const xpd)
{
+ _tEnvPD* x = *xpd;
return powtodb(x->x_result);
}
-void tEnvPD_processBlock(tEnvPD* const x, float* in)
+void tEnvPD_processBlock(tEnvPD* const xpd, float* in)
{
+ _tEnvPD* x = *xpd;
+
int n = x->blockSize;
int count;
@@ -199,26 +222,33 @@
/********Constructor/Destructor***************/
-void tAttackDetection_init(tAttackDetection* const a, int blocksize)
+void tAttackDetection_init(tAttackDetection* const ad, int blocksize)
{
- atkdtk_init(a, blocksize, DEFATTACK, DEFRELEASE);
+ *ad = (_tAttackDetection*) leaf_alloc(sizeof(_tAttackDetection));
+
+ atkdtk_init(ad, blocksize, DEFATTACK, DEFRELEASE);
}
-void tAttackDetection_init_expanded(tAttackDetection* const a, int blocksize, int atk, int rel)
+void tAttackDetection_init_expanded(tAttackDetection* const ad, int blocksize, int atk, int rel)
{
- atkdtk_init(a, blocksize, atk, rel);
+ *ad = (_tAttackDetection*) leaf_alloc(sizeof(_tAttackDetection));
+
+ atkdtk_init(ad, blocksize, atk, rel);
}
-void tAttackDetection_free(tAttackDetection *a)
+void tAttackDetection_free(tAttackDetection* const ad)
{
+ _tAttackDetection* a = *ad;
+ leaf_free(a);
}
/*******Public Functions***********/
-void tAttackDetection_setBlocksize(tAttackDetection* const a, int size)
+void tAttackDetection_setBlocksize(tAttackDetection* const ad, int size)
{
+ _tAttackDetection* a = *ad;
if(!((size==64)|(size==128)|(size==256)|(size==512)|(size==1024)|(size==2048)))
size = DEFBLOCKSIZE;
@@ -228,45 +258,45 @@
}
-void tAttackDetection_setSamplerate(tAttackDetection* const a, int inRate)
+void tAttackDetection_setSamplerate(tAttackDetection* const ad, int inRate)
{
+ _tAttackDetection* a = *ad;
+
a->samplerate = inRate;
//Reset atk and rel to recalculate coeff
- tAttackDetection_setAtk(a, a->atk);
- tAttackDetection_setRel(a, a->rel);
-
- return;
+ tAttackDetection_setAtk(ad, a->atk);
+ tAttackDetection_setRel(ad, a->rel);
}
-void tAttackDetection_setThreshold(tAttackDetection* const a, float thres)
+void tAttackDetection_setThreshold(tAttackDetection* const ad, float thres)
{
+ _tAttackDetection* a = *ad;
a->threshold = thres;
- return;
}
-void tAttackDetection_setAtk(tAttackDetection* const a, int inAtk)
+void tAttackDetection_setAtk(tAttackDetection* const ad, int inAtk)
{
+ _tAttackDetection* a = *ad;
a->atk = inAtk;
a->atk_coeff = pow(0.01, 1.0/(a->atk * a->samplerate * 0.001));
-
- return;
}
-void tAttackDetection_setRel(tAttackDetection* const a, int inRel)
+void tAttackDetection_setRel(tAttackDetection* const ad, int inRel)
{
+ _tAttackDetection* a = *ad;
a->rel = inRel;
a->rel_coeff = pow(0.01, 1.0/(a->rel * a->samplerate * 0.001));
-
- return;
}
-int tAttackDetection_detect(tAttackDetection* const a, float *in)
+int tAttackDetection_detect(tAttackDetection* const ad, float *in)
{
+ _tAttackDetection* a = *ad;
+
int result;
- atkdtk_envelope(a, in);
+ atkdtk_envelope(ad, in);
if(a->env >= a->prevAmp*2) //2 times greater = 6dB increase
result = 1;
@@ -276,13 +306,14 @@
a->prevAmp = a->env;
return result;
-
}
/*******Private Functions**********/
-static void atkdtk_init(tAttackDetection* const a, int blocksize, int atk, int rel)
+static void atkdtk_init(tAttackDetection* const ad, int blocksize, int atk, int rel)
{
+ _tAttackDetection* a = *ad;
+
a->env = 0;
a->blocksize = blocksize;
a->threshold = DEFTHRESHOLD;
@@ -291,12 +322,14 @@
a->env = 0;
- tAttackDetection_setAtk(a, atk);
- tAttackDetection_setRel(a, rel);
+ tAttackDetection_setAtk(ad, atk);
+ tAttackDetection_setRel(ad, rel);
}
-static void atkdtk_envelope(tAttackDetection* const a, float *in)
+static void atkdtk_envelope(tAttackDetection* const ad, float *in)
{
+ _tAttackDetection* a = *ad;
+
int i = 0;
float tmp;
for(i = 0; i < a->blocksize; ++i){
@@ -313,8 +346,10 @@
//===========================================================================
// PERIODDETECTION
//===========================================================================
-void tPeriodDetection_init (tPeriodDetection* const p, float* in, float* out, int bufSize, int frameSize)
+void tPeriodDetection_init (tPeriodDetection* const pd, float* in, float* out, int bufSize, int frameSize)
{
+ _tPeriodDetection* p = *pd = (_tPeriodDetection*) leaf_alloc(sizeof(_tPeriodDetection));
+
p->inBuffer = in;
p->outBuffer = out;
p->bufSize = bufSize;
@@ -336,14 +371,19 @@
p->radius = expf(-1000.0f * p->hopSize * leaf.invSampleRate / p->timeConstant);
}
-void tPeriodDetection_free (tPeriodDetection* const p)
+void tPeriodDetection_free (tPeriodDetection* const pd)
{
+ _tPeriodDetection* p = *pd;
+
tEnvPD_free(&p->env);
tSNAC_free(&p->snac);
+ leaf_free(p);
}
-float tPeriodDetection_findPeriod (tPeriodDetection* p, float sample)
+float tPeriodDetection_findPeriod (tPeriodDetection* pd, float sample)
{
+ _tPeriodDetection* p = *pd;
+
int i, iLast;
i = (p->curBlock*p->frameSize);
@@ -375,13 +415,15 @@
return p->period;
}
-void tPeriodDetection_setHopSize(tPeriodDetection* p, int hs)
+void tPeriodDetection_setHopSize(tPeriodDetection* pd, int hs)
{
+ _tPeriodDetection* p = *pd;
p->hopSize = hs;
}
-void tPeriodDetection_setWindowSize(tPeriodDetection* p, int ws)
+void tPeriodDetection_setWindowSize(tPeriodDetection* pd, int ws)
{
+ _tPeriodDetection* p = *pd;
p->windowSize = ws;
}
@@ -417,8 +459,10 @@
/******************************************************************************/
-void tSNAC_init(tSNAC* const s, int overlaparg)
+void tSNAC_init(tSNAC* const snac, int overlaparg)
{
+ _tSNAC* s = *snac = (_tSNAC*) leaf_alloc(sizeof(_tSNAC));
+
s->biasfactor = DEFBIAS;
s->timeindex = 0;
s->periodindex = 0;
@@ -432,16 +476,19 @@
s->spectrumbuf = (float*) leaf_alloc(sizeof(float) * (SNAC_FRAME_SIZE / 2));
s->biasbuf = (float*) leaf_alloc(sizeof(float) * SNAC_FRAME_SIZE);
- snac_biasbuf(s);
- tSNAC_setOverlap(s, overlaparg);
+ snac_biasbuf(snac);
+ tSNAC_setOverlap(snac, overlaparg);
}
-void tSNAC_free(tSNAC* const s)
+void tSNAC_free(tSNAC* const snac)
{
+ _tSNAC* s = *snac;
+
leaf_free(s->inputbuf);
leaf_free(s->processbuf);
leaf_free(s->spectrumbuf);
leaf_free(s->biasbuf);
+ leaf_free(s);
}
/******************************************************************************/
/************************** public access functions****************************/
@@ -448,8 +495,10 @@
/******************************************************************************/
-void tSNAC_ioSamples(tSNAC* const s, float *in, float *out, int size)
+void tSNAC_ioSamples(tSNAC* const snac, float *in, float *out, int size)
{
+ _tSNAC* s = *snac;
+
int timeindex = s->timeindex;
int mask = s->framesize - 1;
int outindex = 0;
@@ -457,7 +506,7 @@
float *processbuf = s->processbuf;
// call analysis function when it is time
- if(!(timeindex & (s->framesize / s->overlap - 1))) snac_analyzeframe(s);
+ if(!(timeindex & (s->framesize / s->overlap - 1))) snac_analyzeframe(snac);
while(size--)
{
@@ -468,25 +517,28 @@
s->timeindex = timeindex;
}
-void tSNAC_setOverlap(tSNAC* const s, int lap)
+void tSNAC_setOverlap(tSNAC* const snac, int lap)
{
+ _tSNAC* s = *snac;
if(!((lap==1)|(lap==2)|(lap==4)|(lap==8))) lap = DEFOVERLAP;
s->overlap = lap;
}
-void tSNAC_setBias(tSNAC* const s, float bias)
+void tSNAC_setBias(tSNAC* const snac, float bias)
{
+ _tSNAC* s = *snac;
if(bias > 1.) bias = 1.;
if(bias < 0.) bias = 0.;
s->biasfactor = bias;
- snac_biasbuf(s);
+ snac_biasbuf(snac);
return;
}
-void tSNAC_setMinRMS(tSNAC* const s, float rms)
+void tSNAC_setMinRMS(tSNAC* const snac, float rms)
{
+ _tSNAC* s = *snac;
if(rms > 1.) rms = 1.;
if(rms < 0.) rms = 0.;
s->minrms = rms;
@@ -494,14 +546,16 @@
}
-float tSNAC_getPeriod(tSNAC* const s)
+float tSNAC_getPeriod(tSNAC* const snac)
{
+ _tSNAC* s = *snac;
return(s->periodlength);
}
-float tSNAC_getFidelity(tSNAC* const s)
+float tSNAC_getFidelity(tSNAC* const snac)
{
+ _tSNAC* s = *snac;
return(s->fidelity);
}
@@ -512,8 +566,10 @@
// main analysis function
-static void snac_analyzeframe(tSNAC* const s)
+static void snac_analyzeframe(tSNAC* const snac)
{
+ _tSNAC* s = *snac;
+
int n, tindex = s->timeindex;
int framesize = s->framesize;
int mask = framesize - 1;
@@ -534,15 +590,17 @@
for(n=framesize; n<(framesize<<1); n++) processbuf[n] = 0.;
// call analysis procedures
- snac_autocorrelation(s);
- snac_normalize(s);
- snac_pickpeak(s);
- snac_periodandfidelity(s);
+ snac_autocorrelation(snac);
+ snac_normalize(snac);
+ snac_pickpeak(snac);
+ snac_periodandfidelity(snac);
}
-static void snac_autocorrelation(tSNAC* const s)
+static void snac_autocorrelation(tSNAC* const snac)
{
+ _tSNAC* s = *snac;
+
int n, m;
int framesize = s->framesize;
int fftsize = framesize * 2;
@@ -574,8 +632,10 @@
}
-static void snac_normalize(tSNAC* const s)
+static void snac_normalize(tSNAC* const snac)
{
+ _tSNAC* s = *snac;
+
int framesize = s->framesize;
int framesizeplustimeindex = s->framesize + s->timeindex;
int timeindexminusone = s->timeindex - 1;
@@ -611,8 +671,10 @@
}
-static void snac_periodandfidelity(tSNAC* const s)
+static void snac_periodandfidelity(tSNAC* const snac)
{
+ _tSNAC* s = *snac;
+
float periodlength;
if(s->periodindex)
@@ -619,7 +681,7 @@
{
periodlength = (float)s->periodindex +
interpolate3phase(s->processbuf, s->periodindex);
- if(periodlength < 8) periodlength = snac_spectralpeak(s, periodlength);
+ if(periodlength < 8) periodlength = snac_spectralpeak(snac, periodlength);
s->periodlength = periodlength;
s->fidelity = interpolate3max(s->processbuf, s->periodindex);
}
@@ -627,8 +689,10 @@
}
// select the peak which most probably represents period length
-static void snac_pickpeak(tSNAC* const s)
+static void snac_pickpeak(tSNAC* const snac)
{
+ _tSNAC* s = *snac;
+
int n, peakindex=0;
int seek = s->framesize * SEEK;
float *processbuf= s->processbuf;
@@ -669,8 +733,10 @@
// verify period length via frequency domain (up till SR/4)
// frequency domain is more precise than lag domain for period lengths < 8
// argument 'periodlength' is initial estimation from autocorrelation
-static float snac_spectralpeak(tSNAC* const s, float periodlength)
+static float snac_spectralpeak(tSNAC* const snac, float periodlength)
{
+ _tSNAC* s = *snac;
+
if(periodlength < 4.) return periodlength;
float max = 0.;
@@ -713,8 +779,9 @@
// modified logarithmic bias function
-static void snac_biasbuf(tSNAC* const s)
+static void snac_biasbuf(tSNAC* const snac)
{
+ _tSNAC* s = *snac;
int n;
int maxperiod = (int)(s->framesize * (float)SEEK);
--- a/LEAF/Src/leaf-delay.c
+++ b/LEAF/Src/leaf-delay.c
@@ -19,8 +19,10 @@
#endif
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Delay ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
-void tDelay_init (tDelay* const d, uint32_t delay, uint32_t maxDelay)
+void tDelay_init (tDelay* const dl, uint32_t delay, uint32_t maxDelay)
{
+ _tDelay* d = *dl = (_tDelay*) leaf_alloc(sizeof(_tDelay));
+
d->maxDelay = maxDelay;
d->delay = delay;
@@ -35,16 +37,21 @@
d->gain = 1.0f;
- tDelay_setDelay(d, d->delay);
+ tDelay_setDelay(dl, d->delay);
}
-void tDelay_free(tDelay* const d)
+void tDelay_free(tDelay* const dl)
{
+ _tDelay* d = *dl;
+
leaf_free(d->buff);
+ leaf_free(d);
}
-float tDelay_tick (tDelay* const d, float input)
+float tDelay_tick (tDelay* const dl, float input)
{
+ _tDelay* d = *dl;
+
// Input
d->lastIn = input;
d->buff[d->inPoint] = input * d->gain;
@@ -57,12 +64,12 @@
return d->lastOut;
}
-
-int tDelay_setDelay (tDelay* const d, uint32_t delay)
+int tDelay_setDelay (tDelay* const dl, uint32_t delay)
{
+ _tDelay* d = *dl;
+
d->delay = LEAF_clip(0.0f, delay, d->maxDelay);
-
// read chases write
if ( d->inPoint >= delay ) d->outPoint = d->inPoint - d->delay;
else d->outPoint = d->maxDelay + d->inPoint - d->delay;
@@ -70,8 +77,10 @@
return 0;
}
-float tDelay_tapOut (tDelay* const d, uint32_t tapDelay)
+float tDelay_tapOut (tDelay* const dl, uint32_t tapDelay)
{
+ _tDelay* d = *dl;
+
int32_t tap = d->inPoint - tapDelay - 1;
// Check for wraparound.
@@ -81,8 +90,10 @@
}
-void tDelay_tapIn (tDelay* const d, float value, uint32_t tapDelay)
+void tDelay_tapIn (tDelay* const dl, float value, uint32_t tapDelay)
{
+ _tDelay* d = *dl;
+
int32_t tap = d->inPoint - tapDelay - 1;
// Check for wraparound.
@@ -91,8 +102,10 @@
d->buff[tap] = value;
}
-float tDelay_addTo (tDelay* const d, float value, uint32_t tapDelay)
+float tDelay_addTo (tDelay* const dl, float value, uint32_t tapDelay)
{
+ _tDelay* d = *dl;
+
int32_t tap = d->inPoint - tapDelay - 1;
// Check for wraparound.
@@ -101,35 +114,42 @@
return (d->buff[tap] += value);
}
-uint32_t tDelay_getDelay (tDelay* const d)
+uint32_t tDelay_getDelay (tDelay* const dl)
{
+ _tDelay* d = *dl;
return d->delay;
}
-float tDelay_getLastOut (tDelay* const d)
+float tDelay_getLastOut (tDelay* const dl)
{
+ _tDelay* d = *dl;
return d->lastOut;
}
-float tDelay_getLastIn (tDelay* const d)
+float tDelay_getLastIn (tDelay* const dl)
{
+ _tDelay* d = *dl;
return d->lastIn;
}
-void tDelay_setGain (tDelay* const d, float gain)
+void tDelay_setGain (tDelay* const dl, float gain)
{
+ _tDelay* d = *dl;
if (gain < 0.0f) d->gain = 0.0f;
else d->gain = gain;
}
-float tDelay_getGain (tDelay* const d)
+float tDelay_getGain (tDelay* const dl)
{
+ _tDelay* d = *dl;
return d->gain;
}
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ LinearDelay ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
-void tLinearDelay_init (tLinearDelay* const d, float delay, uint32_t maxDelay)
+void tLinearDelay_init (tLinearDelay* const dl, float delay, uint32_t maxDelay)
{
+ _tLinearDelay* d = *dl = (_tLinearDelay*) leaf_alloc(sizeof(_tLinearDelay));
+
d->maxDelay = maxDelay;
if (delay > maxDelay) d->delay = maxDelay;
@@ -146,16 +166,21 @@
d->inPoint = 0;
d->outPoint = 0;
- tLinearDelay_setDelay(d, d->delay);
+ tLinearDelay_setDelay(dl, d->delay);
}
-void tLinearDelay_free(tLinearDelay* const d)
+void tLinearDelay_free(tLinearDelay* const dl)
{
+ _tLinearDelay* d = *dl;
+
leaf_free(d->buff);
+ leaf_free(d);
}
-float tLinearDelay_tick (tLinearDelay* const d, float input)
+float tLinearDelay_tick (tLinearDelay* const dl, float input)
{
+ _tLinearDelay* d = *dl;
+
d->buff[d->inPoint] = input * d->gain;
// Increment input pointer modulo length.
@@ -176,8 +201,10 @@
return d->lastOut;
}
-void tLinearDelay_tickIn (tLinearDelay* const d, float input)
+void tLinearDelay_tickIn (tLinearDelay* const dl, float input)
{
+ _tLinearDelay* d = *dl;
+
d->buff[d->inPoint] = input * d->gain;
// Increment input pointer modulo length.
@@ -184,8 +211,10 @@
if (++(d->inPoint) == d->maxDelay ) d->inPoint = 0;
}
-float tLinearDelay_tickOut (tLinearDelay* const d)
+float tLinearDelay_tickOut (tLinearDelay* const dl)
{
+ _tLinearDelay* d = *dl;
+
uint32_t idx = (uint32_t) d->outPoint;
d->lastOut = LEAF_interpolate_hermite (d->buff[((idx - 1) + d->maxDelay) % d->maxDelay],
@@ -200,8 +229,10 @@
return d->lastOut;
}
-int tLinearDelay_setDelay (tLinearDelay* const d, float delay)
+int tLinearDelay_setDelay (tLinearDelay* const dl, float delay)
{
+ _tLinearDelay* d = *dl;
+
d->delay = LEAF_clip(0.0f, delay, d->maxDelay);
float outPointer = d->inPoint - d->delay;
@@ -219,8 +250,10 @@
return 0;
}
-float tLinearDelay_tapOut (tLinearDelay* const d, float tapDelay)
+float tLinearDelay_tapOut (tLinearDelay* const dl, float tapDelay)
{
+ _tLinearDelay* d = *dl;
+
float tap = (float) d->inPoint - tapDelay - 1.f;
// Check for wraparound.
@@ -244,8 +277,10 @@
}
-void tLinearDelay_tapIn (tLinearDelay* const d, float value, uint32_t tapDelay)
+void tLinearDelay_tapIn (tLinearDelay* const dl, float value, uint32_t tapDelay)
{
+ _tLinearDelay* d = *dl;
+
int32_t tap = d->inPoint - tapDelay - 1;
// Check for wraparound.
@@ -254,8 +289,10 @@
d->buff[tap] = value;
}
-float tLinearDelay_addTo (tLinearDelay* const d, float value, uint32_t tapDelay)
+float tLinearDelay_addTo (tLinearDelay* const dl, float value, uint32_t tapDelay)
{
+ _tLinearDelay* d = *dl;
+
int32_t tap = d->inPoint - tapDelay - 1;
// Check for wraparound.
@@ -264,35 +301,42 @@
return (d->buff[tap] += value);
}
-float tLinearDelay_getDelay (tLinearDelay *d)
+float tLinearDelay_getDelay (tLinearDelay* const dl)
{
+ _tLinearDelay* d = *dl;
return d->delay;
}
-float tLinearDelay_getLastOut (tLinearDelay* const d)
+float tLinearDelay_getLastOut (tLinearDelay* const dl)
{
+ _tLinearDelay* d = *dl;
return d->lastOut;
}
-float tLinearDelay_getLastIn (tLinearDelay* const d)
+float tLinearDelay_getLastIn (tLinearDelay* const dl)
{
+ _tLinearDelay* d = *dl;
return d->lastIn;
}
-void tLinearDelay_setGain (tLinearDelay* const d, float gain)
+void tLinearDelay_setGain (tLinearDelay* const dl, float gain)
{
+ _tLinearDelay* d = *dl;
if (gain < 0.0f) d->gain = 0.0f;
else d->gain = gain;
}
-float tLinearDelay_getGain (tLinearDelay* const d)
+float tLinearDelay_getGain (tLinearDelay* const dl)
{
+ _tLinearDelay* d = *dl;
return d->gain;
}
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ AllpassDelay ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
-void tAllpassDelay_init (tAllpassDelay* const d, float delay, uint32_t maxDelay)
+void tAllpassDelay_init (tAllpassDelay* const dl, float delay, uint32_t maxDelay)
{
+ _tAllpassDelay* d = *dl = (_tAllpassDelay*) leaf_alloc(sizeof(_tAllpassDelay));
+
d->maxDelay = maxDelay;
if (delay > maxDelay) d->delay = maxDelay;
@@ -309,18 +353,23 @@
d->inPoint = 0;
d->outPoint = 0;
- tAllpassDelay_setDelay(d, d->delay);
+ tAllpassDelay_setDelay(dl, d->delay);
d->apInput = 0.0f;
}
-void tAllpassDelay_free(tAllpassDelay* const d)
+void tAllpassDelay_free(tAllpassDelay* const dl)
{
+ _tAllpassDelay* d = *dl;
+
leaf_free(d->buff);
+ leaf_free(d);
}
-float tAllpassDelay_tick (tAllpassDelay* const d, float input)
+float tAllpassDelay_tick (tAllpassDelay* const dl, float input)
{
+ _tAllpassDelay* d = *dl;
+
d->buff[d->inPoint] = input * d->gain;
// Increment input pointer modulo length.
@@ -340,11 +389,12 @@
return d->lastOut;
}
-int tAllpassDelay_setDelay (tAllpassDelay* const d, float delay)
+int tAllpassDelay_setDelay (tAllpassDelay* const dl, float delay)
{
+ _tAllpassDelay* d = *dl;
+
d->delay = LEAF_clip(0.5f, delay, d->maxDelay);
-
// outPoint chases inPoint
float outPointer = (float)d->inPoint - d->delay + 1.0f;
@@ -373,8 +423,10 @@
return 0;
}
-float tAllpassDelay_tapOut (tAllpassDelay* const d, uint32_t tapDelay)
+float tAllpassDelay_tapOut (tAllpassDelay* const dl, uint32_t tapDelay)
{
+ _tAllpassDelay* d = *dl;
+
int32_t tap = d->inPoint - tapDelay - 1;
// Check for wraparound.
@@ -384,8 +436,10 @@
}
-void tAllpassDelay_tapIn (tAllpassDelay* const d, float value, uint32_t tapDelay)
+void tAllpassDelay_tapIn (tAllpassDelay* const dl, float value, uint32_t tapDelay)
{
+ _tAllpassDelay* d = *dl;
+
int32_t tap = d->inPoint - tapDelay - 1;
// Check for wraparound.
@@ -394,8 +448,10 @@
d->buff[tap] = value;
}
-float tAllpassDelay_addTo (tAllpassDelay* const d, float value, uint32_t tapDelay)
+float tAllpassDelay_addTo (tAllpassDelay* const dl, float value, uint32_t tapDelay)
{
+ _tAllpassDelay* d = *dl;
+
int32_t tap = d->inPoint - tapDelay - 1;
// Check for wraparound.
@@ -404,35 +460,42 @@
return (d->buff[tap] += value);
}
-float tAllpassDelay_getDelay (tAllpassDelay* const d)
+float tAllpassDelay_getDelay (tAllpassDelay* const dl)
{
+ _tAllpassDelay* d = *dl;
return d->delay;
}
-float tAllpassDelay_getLastOut (tAllpassDelay* const d)
+float tAllpassDelay_getLastOut (tAllpassDelay* const dl)
{
+ _tAllpassDelay* d = *dl;
return d->lastOut;
}
-float tAllpassDelay_getLastIn (tAllpassDelay* const d)
+float tAllpassDelay_getLastIn (tAllpassDelay* const dl)
{
+ _tAllpassDelay* d = *dl;
return d->lastIn;
}
-void tAllpassDelay_setGain (tAllpassDelay* const d, float gain)
+void tAllpassDelay_setGain (tAllpassDelay* const dl, float gain)
{
+ _tAllpassDelay* d = *dl;
if (gain < 0.0f) d->gain = 0.0f;
else d->gain = gain;
}
-float tAllpassDelay_getGain (tAllpassDelay* const d)
+float tAllpassDelay_getGain (tAllpassDelay* const dl)
{
+ _tAllpassDelay* d = *dl;
return d->gain;
}
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ TapeDelay ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
-void tTapeDelay_init (tTapeDelay* const d, float delay, uint32_t maxDelay)
+void tTapeDelay_init (tTapeDelay* const dl, float delay, uint32_t maxDelay)
{
+ _tTapeDelay* d = *dl = (_tTapeDelay*) leaf_alloc(sizeof(_tTapeDelay));
+
d->maxDelay = maxDelay;
d->buff = (float*) leaf_alloc(sizeof(float) * maxDelay);
@@ -446,18 +509,23 @@
d->inc = 1.0f;
d->inPoint = 0;
- tTapeDelay_setDelay(d, delay);
+ tTapeDelay_setDelay(dl, delay);
}
-void tTapeDelay_free(tTapeDelay* const d)
+void tTapeDelay_free(tTapeDelay* const dl)
{
+ _tTapeDelay* d = *dl;
+
leaf_free(d->buff);
+ leaf_free(d);
}
//#define SMOOTH_FACTOR 10.f
-float tTapeDelay_tick (tTapeDelay* const d, float input)
+float tTapeDelay_tick (tTapeDelay* const dl, float input)
{
+ _tTapeDelay* d = *dl;
+
d->buff[d->inPoint] = input * d->gain;
// Increment input pointer modulo length.
@@ -485,20 +553,22 @@
}
-void tTapeDelay_setRate(tTapeDelay* const d, float rate)
+void tTapeDelay_setRate(tTapeDelay* const dl, float rate)
{
+ _tTapeDelay* d = *dl;
d->inc = rate;
}
-int tTapeDelay_setDelay (tTapeDelay* const d, float delay)
+void tTapeDelay_setDelay (tTapeDelay* const dl, float delay)
{
+ _tTapeDelay* d = *dl;
d->delay = LEAF_clip(1.f, delay, d->maxDelay);
-
- return 0;
}
-float tTapeDelay_tapOut (tTapeDelay* const d, float tapDelay)
+float tTapeDelay_tapOut (tTapeDelay* const dl, float tapDelay)
{
+ _tTapeDelay* d = *dl;
+
float tap = (float) d->inPoint - tapDelay - 1.f;
// Check for wraparound.
@@ -518,8 +588,10 @@
}
-void tTapeDelay_tapIn (tTapeDelay* const d, float value, uint32_t tapDelay)
+void tTapeDelay_tapIn (tTapeDelay* const dl, float value, uint32_t tapDelay)
{
+ _tTapeDelay* d = *dl;
+
int32_t tap = d->inPoint - tapDelay - 1;
// Check for wraparound.
@@ -528,8 +600,10 @@
d->buff[tap] = value;
}
-float tTapeDelay_addTo (tTapeDelay* const d, float value, uint32_t tapDelay)
+float tTapeDelay_addTo (tTapeDelay* const dl, float value, uint32_t tapDelay)
{
+ _tTapeDelay* d = *dl;
+
int32_t tap = d->inPoint - tapDelay - 1;
// Check for wraparound.
@@ -538,29 +612,34 @@
return (d->buff[tap] += value);
}
-float tTapeDelay_getDelay (tTapeDelay *d)
+float tTapeDelay_getDelay (tTapeDelay *dl)
{
+ _tTapeDelay* d = *dl;
return d->delay;
}
-float tTapeDelay_getLastOut (tTapeDelay* const d)
+float tTapeDelay_getLastOut (tTapeDelay* const dl)
{
+ _tTapeDelay* d = *dl;
return d->lastOut;
}
-float tTapeDelay_getLastIn (tTapeDelay* const d)
+float tTapeDelay_getLastIn (tTapeDelay* const dl)
{
+ _tTapeDelay* d = *dl;
return d->lastIn;
}
-void tTapeDelay_setGain (tTapeDelay* const d, float gain)
+void tTapeDelay_setGain (tTapeDelay* const dl, float gain)
{
+ _tTapeDelay* d = *dl;
if (gain < 0.0f) d->gain = 0.0f;
else d->gain = gain;
}
-float tTapeDelay_getGain (tTapeDelay* const d)
+float tTapeDelay_getGain (tTapeDelay* const dl)
{
+ _tTapeDelay* d = *dl;
return d->gain;
}
--- a/LEAF/Src/leaf-distortion.c
+++ b/LEAF/Src/leaf-distortion.c
@@ -21,16 +21,20 @@
//============================================================================================================
// WAVEFOLDER
//============================================================================================================
-void tLockhartWavefolder_init(tLockhartWavefolder* const w)
+void tLockhartWavefolder_init(tLockhartWavefolder* const wf)
{
+ _tLockhartWavefolder* w = *wf = (_tLockhartWavefolder*) leaf_alloc(sizeof(_tLockhartWavefolder));
+
w->Ln1 = 0.0;
w->Fn1 = 0.0;
w->xn1 = 0.0f;
}
-void tLockhardWavefolder_free(tLockhartWavefolder* const w)
+void tLockhardWavefolder_free(tLockhartWavefolder* const wf)
{
+ _tLockhartWavefolder* w = *wf;
+ leaf_free(w);
}
double tLockhartWavefolderLambert(double x, double ln)
@@ -63,8 +67,9 @@
return w;
}
-float tLockhartWavefolder_tick(tLockhartWavefolder* const w, float samp)
+float tLockhartWavefolder_tick(tLockhartWavefolder* const wf, float samp)
{
+ _tLockhartWavefolder* w = *wf;
float out = 0.0f;
// Constants
@@ -123,8 +128,10 @@
//============================================================================================================
#define SCALAR 5000.f
-void tCrusher_init (tCrusher* const c)
+void tCrusher_init (tCrusher* const cr)
{
+ _tCrusher* c = *cr = (_tCrusher*) leaf_alloc(sizeof(_tCrusher));
+
c->op = 4;
c->div = SCALAR;
c->rnd = 0.25f;
@@ -133,13 +140,17 @@
c->gain = (c->div / SCALAR) * 0.7f + 0.3f;
}
-void tCrusher_free (tCrusher* const c)
+void tCrusher_free (tCrusher* const cr)
{
+ _tCrusher* c = *cr;
+ leaf_free(c);
}
-float tCrusher_tick (tCrusher* const c, float input)
+float tCrusher_tick (tCrusher* const cr, float input)
{
+ _tCrusher* c = *cr;
+
float sample = input;
sample *= SCALAR; // SCALAR is 5000 by default
@@ -160,14 +171,17 @@
}
-void tCrusher_setOperation (tCrusher* const c, float op)
+void tCrusher_setOperation (tCrusher* const cr, float op)
{
+ _tCrusher* c = *cr;
c->op = (uint32_t) (op * 8.0f);
}
// 0.0 - 1.0
-void tCrusher_setQuality (tCrusher* const c, float val)
+void tCrusher_setQuality (tCrusher* const cr, float val)
{
+ _tCrusher* c = *cr;
+
val = LEAF_clip(0.0f, val, 1.0f);
c->div = 0.01f + val * SCALAR;
@@ -176,13 +190,15 @@
}
// what decimal to round to
-void tCrusher_setRound (tCrusher* const c, float rnd)
+void tCrusher_setRound (tCrusher* const cr, float rnd)
{
+ _tCrusher* c = *cr;
c->rnd = fabsf(rnd);
}
-void tCrusher_setSamplingRatio (tCrusher* const c, float ratio)
+void tCrusher_setSamplingRatio (tCrusher* const cr, float ratio)
{
+ _tCrusher* c = *cr;
c->srr = ratio;
}
@@ -191,8 +207,10 @@
// Oversampler
//============================================================================================================
// Latency is equal to the phase length (numTaps / ratio)
-void tOversampler_init(tOversampler* const os, int ratio, oBool extraQuality)
+void tOversampler_init(tOversampler* const osr, int ratio, oBool extraQuality)
{
+ _tOversampler* os = *osr = (_tOversampler*) leaf_alloc(sizeof(_tOversampler));
+
uint8_t offset = 0;
if (extraQuality) offset = 6;
if (ratio == 2 || ratio == 4 ||
@@ -208,28 +226,35 @@
}
}
-void tOversampler_free(tOversampler* const os)
+void tOversampler_free(tOversampler* const osr)
{
+ _tOversampler* os = *osr;
+
leaf_free(os->upState);
leaf_free(os->downState);
+ leaf_free(os);
}
-float tOversampler_tick(tOversampler* const os, float input, float (*effectTick)(float))
+float tOversampler_tick(tOversampler* const osr, float input, float (*effectTick)(float))
{
+ _tOversampler* os = *osr;
+
float buf[os->ratio];
- tOversampler_upsample(os, input, buf);
+ tOversampler_upsample(osr, input, buf);
for (int i = 0; i < os->ratio; ++i) {
buf[i] = effectTick(buf[i]);
}
- return tOversampler_downsample(os, buf);
+ return tOversampler_downsample(osr, buf);
}
// From CMSIS DSP Library
-void tOversampler_upsample(tOversampler* const os, float input, float* output)
+void tOversampler_upsample(tOversampler* const osr, float input, float* output)
{
+ _tOversampler* os = *osr;
+
float *pState = os->upState; /* State pointer */
const float *pCoeffs = os->pCoeffs; /* Coefficient pointer */
float *pStateCur;
@@ -319,8 +344,10 @@
}
// From CMSIS DSP Library
-float tOversampler_downsample(tOversampler *const os, float* input)
+float tOversampler_downsample(tOversampler *const osr, float* input)
{
+ _tOversampler* os = *osr;
+
float *pState = os->downState; /* State pointer */
const float *pCoeffs = os->pCoeffs; /* Coefficient pointer */
float *pStateCur; /* Points to the current sample of the state */
@@ -401,7 +428,8 @@
return output;
}
-int tOversampler_getLatency(tOversampler* const os)
+int tOversampler_getLatency(tOversampler* const osr)
{
+ _tOversampler* os = *osr;
return os->phaseLength;
}
--- a/LEAF/Src/leaf-dynamics.c
+++ b/LEAF/Src/leaf-dynamics.c
@@ -41,8 +41,10 @@
return c;
}
*/
-void tCompressor_init(tCompressor* const c)
+void tCompressor_init(tCompressor* const comp)
{
+ _tCompressor* c = *comp = (_tCompressor*) leaf_alloc(sizeof(_tCompressor));
+
c->tauAttack = 100;
c->tauRelease = 100;
@@ -54,14 +56,18 @@
c->W = 1.0f; // decibel Make-up gain
}
-void tCompressor_free(tCompressor* const c)
+void tCompressor_free(tCompressor* const comp)
{
+ _tCompressor* c = *comp;
+ leaf_free(c);
}
int ccount = 0;
-float tCompressor_tick(tCompressor* const c, float in)
+float tCompressor_tick(tCompressor* const comp, float in)
{
+ _tCompressor* c = *comp;
+
float slope, overshoot;
float alphaAtt, alphaRel;
@@ -115,14 +121,14 @@
}
*/
return attenuation * in;
-
-
}
/* Feedback Leveler */
-void tFeedbackLeveler_init(tFeedbackLeveler* const p, float targetLevel, float factor, float strength, int mode)
+void tFeedbackLeveler_init(tFeedbackLeveler* const fb, float targetLevel, float factor, float strength, int mode)
{
+ _tFeedbackLeveler* p = *fb = (_tFeedbackLeveler*) leaf_alloc(sizeof(_tFeedbackLeveler));
+
p->curr=0.0f;
p->targetLevel=targetLevel;
tPowerFollower_init(&p->pwrFlw,factor);
@@ -130,29 +136,36 @@
p->strength=strength;
}
-void tFeedbackLeveler_free(tFeedbackLeveler* const p)
+void tFeedbackLeveler_free(tFeedbackLeveler* const fb)
{
+ _tFeedbackLeveler* p = *fb;
+
tPowerFollower_free(&p->pwrFlw);
+ leaf_free(p);
}
-void tFeedbackLeveler_setStrength(tFeedbackLeveler* const p, float strength)
+void tFeedbackLeveler_setStrength(tFeedbackLeveler* const fb, float strength)
{ // strength is how strongly level diff is affecting the amp ratio
// try 0.125 for a start
+ _tFeedbackLeveler* p = *fb;
p->strength=strength;
}
-void tFeedbackLeveler_setFactor(tFeedbackLeveler* const p, float factor)
+void tFeedbackLeveler_setFactor(tFeedbackLeveler* const fb, float factor)
{
+ _tFeedbackLeveler* p = *fb;
tPowerFollower_setFactor(&p->pwrFlw,factor);
}
-void tFeedbackLeveler_setMode(tFeedbackLeveler* const p, int mode)
+void tFeedbackLeveler_setMode(tFeedbackLeveler* const fb, int mode)
{ // 0 for decaying with upwards lev limiting, 1 for constrained absolute level (also downwards limiting)
+ _tFeedbackLeveler* p = *fb;
p->mode=mode;
}
-float tFeedbackLeveler_tick(tFeedbackLeveler* const p, float input)
+float tFeedbackLeveler_tick(tFeedbackLeveler* const fb, float input)
{
+ _tFeedbackLeveler* p = *fb;
float levdiff=(tPowerFollower_tick(&p->pwrFlw, input)-p->targetLevel);
if (p->mode==0 && levdiff<0) levdiff=0;
p->curr=input*(1-p->strength*levdiff);
@@ -159,14 +172,16 @@
return p->curr;
}
-float tFeedbackLeveler_sample(tFeedbackLeveler* const p)
+float tFeedbackLeveler_sample(tFeedbackLeveler* const fb)
{
+ _tFeedbackLeveler* p = *fb;
return p->curr;
}
-void tFeedbackLeveler_setTargetLevel (tFeedbackLeveler* const p, float TargetLevel)
+void tFeedbackLeveler_setTargetLevel (tFeedbackLeveler* const fb, float TargetLevel)
{
+ _tFeedbackLeveler* p = *fb;
p->targetLevel=TargetLevel;
}
--- a/LEAF/Src/leaf-effects.c
+++ b/LEAF/Src/leaf-effects.c
@@ -1,11 +1,11 @@
/*==============================================================================
+
+ leaf-vocoder.c
+ Created: 20 Jan 2017 12:01:54pm
+ Author: Michael R Mulshine
+
+ ==============================================================================*/
- leaf-vocoder.c
- Created: 20 Jan 2017 12:01:54pm
- Author: Michael R Mulshine
-
-==============================================================================*/
-
#if _WIN32 || _WIN64
#include "..\Inc\leaf-effects.c"
@@ -24,8 +24,11 @@
// TALKBOX
//============================================================================================================
-void tTalkbox_init(tTalkbox* const v, int bufsize)
+void tTalkbox_init(tTalkbox* const voc, int bufsize)
{
+
+ _tTalkbox* v = *voc = (_tTalkbox*) leaf_alloc(sizeof(_tTalkbox));
+
v->param[0] = 0.5f; //wet
v->param[1] = 0.0f; //dry
v->param[2] = 0; // Swap
@@ -39,20 +42,27 @@
v->buf0 = (float*) leaf_alloc(sizeof(float) * v->bufsize);
v->buf1 = (float*) leaf_alloc(sizeof(float) * v->bufsize);
- tTalkbox_update(v);
+ tTalkbox_update(voc);
+ tTalkbox_suspend(voc);
}
-void tTalkbox_free(tTalkbox* const v)
+void tTalkbox_free(tTalkbox* const voc)
{
+ _tTalkbox* v = *voc;
+
leaf_free(v->buf1);
leaf_free(v->buf0);
leaf_free(v->window);
leaf_free(v->car1);
leaf_free(v->car0);
+
+ leaf_free(v);
}
-void tTalkbox_update(tTalkbox* const v) ///update internal parameters...
+void tTalkbox_update(tTalkbox* const voc) ///update internal parameters...
{
+ _tTalkbox* v = *voc;
+
float fs = leaf.sampleRate;
if(fs < 8000.0f) fs = 8000.0f;
if(fs > 96000.0f) fs = 96000.0f;
@@ -78,8 +88,10 @@
v->dry = 2.0f * v->param[1] * v->param[1];
}
-void tTalkbox_suspend(tTalkbox* const v) ///clear any buffers...
+void tTalkbox_suspend(tTalkbox* const voc) ///clear any buffers...
{
+ _tTalkbox* v = *voc;
+
v->pos = v->K = 0;
v->emphasis = 0.0f;
v->FX = 0;
@@ -162,9 +174,10 @@
*g = sqrtf(e);
}
-float tTalkbox_tick(tTalkbox* const v, float synth, float voice)
+float tTalkbox_tick(tTalkbox* const voc, float synth, float voice)
{
-
+ _tTalkbox* v = *voc;
+
int32_t p0=v->pos, p1 = (v->pos + v->N/2) % v->N;
float e=v->emphasis, w, o, x, dr, fx=v->FX;
float p, q, h0=0.3f, h1=0.77f;
@@ -204,7 +217,7 @@
v->emphasis = e;
v->pos = p0;
v->FX = fx;
-
+
float den = 1.0e-10f; //(float)pow(10.0f, -10.0f * param[4]);
if(fabs(v->d0) < den) v->d0 = 0.0f; //anti-denormal (doesn't seem necessary but P4?)
if(fabs(v->d1) < den) v->d1 = 0.0f;
@@ -217,10 +230,12 @@
return o;
}
-void tTalkbox_setQuality(tTalkbox* const v, float quality)
+void tTalkbox_setQuality(tTalkbox* const voc, float quality)
{
- v->param[3] = quality;
- v->O = (int32_t)((0.0001f + 0.0004f * v->param[3]) * leaf.sampleRate);
+ _tTalkbox* v = *voc;
+
+ v->param[3] = quality;
+ v->O = (int32_t)((0.0001f + 0.0004f * v->param[3]) * leaf.sampleRate);
}
@@ -228,8 +243,10 @@
// VOCODER
//============================================================================================================
-void tVocoder_init (tVocoder* const v)
+void tVocoder_init (tVocoder* const voc)
{
+ _tVocoder* v = *voc = (_tVocoder*) leaf_alloc(sizeof(_tVocoder));
+
v->param[0] = 0.33f; //input select
v->param[1] = 0.50f; //output dB
v->param[2] = 0.40f; //hi thru
@@ -239,16 +256,20 @@
v->param[6] = 0.6667f;//freq range
v->param[7] = 0.33f; //num bands
- tVocoder_update(v);
+ tVocoder_update(voc);
}
-void tVocoder_free (tVocoder* const v)
+void tVocoder_free (tVocoder* const voc)
{
+ _tVocoder* v = *voc;
+ leaf_free(v);
}
-void tVocoder_update (tVocoder* const v)
+void tVocoder_update (tVocoder* const voc)
{
+ _tVocoder* v = *voc;
+
float tpofs = 6.2831853f * leaf.invSampleRate;
float rr, th, re;
@@ -329,11 +350,13 @@
}
}
-float tVocoder_tick (tVocoder* const v, float synth, float voice)
+float tVocoder_tick (tVocoder* const voc, float synth, float voice)
{
+ _tVocoder* v = *voc;
+
float a, b, o=0.0f, aa, bb, oo = v->kout, g = v->gain, ht = v->thru, hh = v->high, tmp;
uint32_t i, k = v->kval, nb = v->nbnd;
-
+
a = voice; //speech
b = synth; //synth
@@ -377,7 +400,7 @@
}
}
o += oo * g; //effect of interpolating back up to Fs would be minimal (aliasing >16kHz)
-
+
v->kout = oo;
v->kval = k & 0x1;
if(fabs(v->f[0][11])<1.0e-10) v->f[0][11] = 0.0f; //catch HF envelope denormal
@@ -386,14 +409,16 @@
if(fabs(v->f[i][3])<1.0e-10 || fabs(v->f[i][7])<1.0e-10)
for(k=3; k<12; k++) v->f[i][k] = 0.0f; //catch reson & envelope denormals
- if(fabs(o)>10.0f) tVocoder_suspend(v); //catch instability
+ if(fabs(o)>10.0f) tVocoder_suspend(voc); //catch instability
return o;
}
-void tVocoder_suspend (tVocoder* const v)
+void tVocoder_suspend (tVocoder* const voc)
{
+ _tVocoder* v = *voc;
+
int32_t i, j;
for(i=0; i<v->nbnd; i++) for(j=3; j<12; j++) v->f[i][j] = 0.0f; //zero band filters and envelopes
@@ -405,8 +430,10 @@
// RETUNE
//============================================================================================================
-void tRetune_init(tRetune* const r, int numVoices, int bufSize, int frameSize)
+void tRetune_init(tRetune* const rt, int numVoices, int bufSize, int frameSize)
{
+ _tRetune* r = *rt = (_tRetune*) leaf_alloc(sizeof(_tRetune));
+
r->bufSize = bufSize;
r->frameSize = frameSize;
r->numVoices = numVoices;
@@ -417,7 +444,7 @@
r->hopSize = DEFHOPSIZE;
r->windowSize = DEFWINDOWSIZE;
r->fba = FBA;
- tRetune_setTimeConstant(r, DEFTIMECONSTANT);
+ tRetune_setTimeConstant(rt, DEFTIMECONSTANT);
r->inputPeriod = 0.0f;
@@ -437,8 +464,10 @@
}
}
-void tRetune_free(tRetune* const r)
+void tRetune_free(tRetune* const rt)
{
+ _tRetune* r = *rt;
+
tPeriodDetection_free(&r->pd);
for (int i = 0; i < r->numVoices; ++i)
{
@@ -450,10 +479,13 @@
leaf_free(r->ps);
leaf_free(r->inBuffer);
leaf_free(r->outBuffers);
+ leaf_free(r);
}
-float* tRetune_tick(tRetune* const r, float sample)
+float* tRetune_tick(tRetune* const rt, float sample)
{
+ _tRetune* r = *rt;
+
r->inputPeriod = tPeriodDetection_findPeriod(&r->pd, sample);
for (int v = 0; v < r->numVoices; ++v)
@@ -460,12 +492,14 @@
{
r->tickOutput[v] = tPitchShift_shift(&r->ps[v]);
}
-
+
return r->tickOutput;
}
-void tRetune_setNumVoices(tRetune* const r, int numVoices)
+void tRetune_setNumVoices(tRetune* const rt, int numVoices)
{
+ _tRetune* r = *rt;
+
for (int i = 0; i < r->numVoices; ++i)
{
tPitchShift_free(&r->ps[i]);
@@ -491,8 +525,10 @@
}
-void tRetune_setPitchFactors(tRetune* const r, float pf)
+void tRetune_setPitchFactors(tRetune* const rt, float pf)
{
+ _tRetune* r = *rt;
+
for (int i = 0; i < r->numVoices; ++i)
{
r->pitchFactor[i] = pf;
@@ -500,37 +536,49 @@
}
}
-void tRetune_setPitchFactor(tRetune* const r, float pf, int voice)
+void tRetune_setPitchFactor(tRetune* const rt, float pf, int voice)
{
+ _tRetune* r = *rt;
+
r->pitchFactor[voice] = pf;
tPitchShift_setPitchFactor(&r->ps[voice], r->pitchFactor[voice]);
}
-void tRetune_setTimeConstant(tRetune* const r, float tc)
+void tRetune_setTimeConstant(tRetune* const rt, float tc)
{
+ _tRetune* r = *rt;
+
r->timeConstant = tc;
r->radius = expf(-1000.0f * r->hopSize * leaf.invSampleRate / r->timeConstant);
}
-void tRetune_setHopSize(tRetune* const r, int hs)
+void tRetune_setHopSize(tRetune* const rt, int hs)
{
+ _tRetune* r = *rt;
+
r->hopSize = hs;
tPeriodDetection_setHopSize(&r->pd, r->hopSize);
}
-void tRetune_setWindowSize(tRetune* const r, int ws)
+void tRetune_setWindowSize(tRetune* const rt, int ws)
{
+ _tRetune* r = *rt;
+
r->windowSize = ws;
tPeriodDetection_setWindowSize(&r->pd, r->windowSize);
}
-float tRetune_getInputPeriod(tRetune* const r)
+float tRetune_getInputPeriod(tRetune* const rt)
{
+ _tRetune* r = *rt;
+
return r->inputPeriod;
}
-float tRetune_getInputFreq(tRetune* const r)
+float tRetune_getInputFreq(tRetune* const rt)
{
+ _tRetune* r = *rt;
+
return 1.0f/r->inputPeriod;
}
@@ -538,8 +586,10 @@
// AUTOTUNE
//============================================================================================================
-void tAutotune_init(tAutotune* const r, int numVoices, int bufSize, int frameSize)
+void tAutotune_init(tAutotune* const rt, int numVoices, int bufSize, int frameSize)
{
+ _tAutotune* r = *rt = (_tAutotune*) leaf_alloc(sizeof(_tAutotune));
+
r->bufSize = bufSize;
r->frameSize = frameSize;
r->numVoices = numVoices;
@@ -550,7 +600,7 @@
r->hopSize = DEFHOPSIZE;
r->windowSize = DEFWINDOWSIZE;
r->fba = FBA;
- tAutotune_setTimeConstant(r, DEFTIMECONSTANT);
+ tAutotune_setTimeConstant(rt, DEFTIMECONSTANT);
@@ -572,8 +622,10 @@
r->inputPeriod = 0.0f;
}
-void tAutotune_free(tAutotune* const r)
+void tAutotune_free(tAutotune* const rt)
{
+ _tAutotune* r = *rt;
+
tPeriodDetection_free(&r->pd);
for (int i = 0; i < r->numVoices; ++i)
{
@@ -585,10 +637,13 @@
leaf_free(r->ps);
leaf_free(r->inBuffer);
leaf_free(r->outBuffers);
+ leaf_free(r);
}
-float* tAutotune_tick(tAutotune* const r, float sample)
+float* tAutotune_tick(tAutotune* const rt, float sample)
{
+ _tAutotune* r = *rt;
+
r->inputPeriod = tPeriodDetection_findPeriod(&r->pd, sample);
for (int v = 0; v < r->numVoices; ++v)
@@ -599,8 +654,10 @@
return r->tickOutput;
}
-void tAutotune_setNumVoices(tAutotune* const r, int numVoices)
+void tAutotune_setNumVoices(tAutotune* const rt, int numVoices)
{
+ _tAutotune* r = *rt;
+
for (int i = 0; i < r->numVoices; ++i)
{
tPitchShift_free(&r->ps[i]);
@@ -626,8 +683,10 @@
}
-void tAutotune_setFreqs(tAutotune* const r, float f)
+void tAutotune_setFreqs(tAutotune* const rt, float f)
{
+ _tAutotune* r = *rt;
+
for (int i = 0; i < r->numVoices; ++i)
{
r->freq[i] = f;
@@ -634,36 +693,48 @@
}
}
-void tAutotune_setFreq(tAutotune* const r, float f, int voice)
+void tAutotune_setFreq(tAutotune* const rt, float f, int voice)
{
+ _tAutotune* r = *rt;
+
r->freq[voice] = f;
}
-void tAutotune_setTimeConstant(tAutotune* const r, float tc)
+void tAutotune_setTimeConstant(tAutotune* const rt, float tc)
{
+ _tAutotune* r = *rt;
+
r->timeConstant = tc;
r->radius = expf(-1000.0f * r->hopSize * leaf.invSampleRate / r->timeConstant);
}
-void tAutotune_setHopSize(tAutotune* const r, int hs)
+void tAutotune_setHopSize(tAutotune* const rt, int hs)
{
+ _tAutotune* r = *rt;
+
r->hopSize = hs;
tPeriodDetection_setHopSize(&r->pd, r->hopSize);
}
-void tAutotune_setWindowSize(tAutotune* const r, int ws)
+void tAutotune_setWindowSize(tAutotune* const rt, int ws)
{
+ _tAutotune* r = *rt;
+
r->windowSize = ws;
tPeriodDetection_setWindowSize(&r->pd, r->windowSize);
}
-float tAutotune_getInputPeriod(tAutotune* const r)
+float tAutotune_getInputPeriod(tAutotune* const rt)
{
+ _tAutotune* r = *rt;
+
return r->inputPeriod;
}
-float tAutotune_getInputFreq(tAutotune* const r)
+float tAutotune_getInputFreq(tAutotune* const rt)
{
+ _tAutotune* r = *rt;
+
return 1.0f/r->inputPeriod;
}
@@ -671,36 +742,41 @@
// PITCHSHIFT
//============================================================================================================
-static int pitchshift_attackdetect(tPitchShift* ps)
+static int pitchshift_attackdetect(_tPitchShift* ps)
{
float envout;
- envout = tEnvPD_tick(&ps->p->env);
+ _tPeriodDetection* p = *ps->p;
+ envout = tEnvPD_tick(&p->env);
+
if (envout >= 1.0f)
{
- ps->p->lastmax = ps->p->max;
- if (envout > ps->p->max)
+ p->lastmax = p->max;
+ if (envout > p->max)
{
- ps->p->max = envout;
+ p->max = envout;
}
else
{
- ps->p->deltamax = envout - ps->p->max;
- ps->p->max = ps->p->max * ps->radius;
+ p->deltamax = envout - p->max;
+ p->max = p->max * ps->radius;
}
- ps->p->deltamax = ps->p->max - ps->p->lastmax;
+ p->deltamax = p->max - p->lastmax;
}
- ps->p->fba = ps->p->fba ? (ps->p->fba - 1) : 0;
+ p->fba = p->fba ? (p->fba - 1) : 0;
- return (ps->p->fba == 0 && (ps->p->max > 60 && ps->p->deltamax > 6)) ? 1 : 0;
+ return (p->fba == 0 && (p->max > 60 && p->deltamax > 6)) ? 1 : 0;
}
-void tPitchShift_init (tPitchShift* const ps, tPeriodDetection* p, float* out, int bufSize)
+void tPitchShift_init (tPitchShift* const psr, tPeriodDetection* pd, float* out, int bufSize)
{
- ps->p = p;
+ _tPitchShift* ps = *psr = (_tPitchShift*) leaf_alloc(sizeof(_tPitchShift));
+ _tPeriodDetection* p = *pd;
+ ps->p = pd;
+
ps->outBuffer = out;
ps->bufSize = bufSize;
ps->frameSize = p->frameSize;
@@ -717,64 +793,75 @@
tSOLAD_setPitchFactor(&ps->sola, DEFPITCHRATIO);
}
-void tPitchShift_free(tPitchShift* const ps)
+void tPitchShift_free(tPitchShift* const psr)
{
+ _tPitchShift* ps = *psr;
+
tSOLAD_free(&ps->sola);
tHighpass_free(&ps->hp);
+ leaf_free(ps);
}
-void tPitchShift_setPitchFactor(tPitchShift* ps, float pf)
+void tPitchShift_setPitchFactor(tPitchShift* psr, float pf)
{
+ _tPitchShift* ps = *psr;
+
ps->pitchFactor = pf;
}
-float tPitchShift_shift (tPitchShift* ps)
+float tPitchShift_shift (tPitchShift* psr)
{
+ _tPitchShift* ps = *psr;
+ _tPeriodDetection* p = *ps->p;
+
float period, out;
int i, iLast;
- i = ps->p->i;
- iLast = ps->p->iLast;
+ i = p->i;
+ iLast = p->iLast;
out = tHighpass_tick(&ps->hp, ps->outBuffer[iLast]);
- if (ps->p->indexstore >= ps->frameSize)
+ if (p->indexstore >= ps->frameSize)
{
- period = ps->p->period;
+ period = p->period;
if(pitchshift_attackdetect(ps) == 1)
{
- ps->p->fba = 5;
- tSOLAD_setReadLag(&ps->sola, ps->p->windowSize);
+ p->fba = 5;
+ tSOLAD_setReadLag(&ps->sola, p->windowSize);
}
tSOLAD_setPeriod(&ps->sola, period);
tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
- tSOLAD_ioSamples(&ps->sola, &(ps->p->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
+ tSOLAD_ioSamples(&ps->sola, &(p->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
}
return out;
}
-float tPitchShift_shiftToFreq (tPitchShift* ps, float freq)
+float tPitchShift_shiftToFreq (tPitchShift* psr, float freq)
{
+ _tPitchShift* ps = *psr;
+ _tPeriodDetection* p = *ps->p;
+
float period, out;
int i, iLast;
- i = ps->p->i;
- iLast = ps->p->iLast;
+ i = p->i;
+ iLast = p->iLast;
out = tHighpass_tick(&ps->hp, ps->outBuffer[iLast]);
- if (ps->p->indexstore >= ps->frameSize)
+ if (p->indexstore >= ps->frameSize)
{
- period = ps->p->period;
+ period = p->period;
if(pitchshift_attackdetect(ps) == 1)
{
- ps->p->fba = 5;
- tSOLAD_setReadLag(&ps->sola, ps->p->windowSize);
+ p->fba = 5;
+ tSOLAD_setReadLag(&ps->sola, p->windowSize);
}
tSOLAD_setPeriod(&ps->sola, period);
@@ -781,32 +868,35 @@
if (period != 0) ps->pitchFactor = period*freq*leaf.invSampleRate;
else ps->pitchFactor = 1.0f;
-
+
tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
- tSOLAD_ioSamples(&ps->sola, &(ps->p->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
+ tSOLAD_ioSamples(&ps->sola, &(p->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
}
return out;
}
-float tPitchShift_shiftToFunc (tPitchShift* ps, float (*fun)(float))
+float tPitchShift_shiftToFunc (tPitchShift* psr, float (*fun)(float))
{
+ _tPitchShift* ps = *psr;
+ _tPeriodDetection* p = *ps->p;
+
float period, out;
int i, iLast;
- i = ps->p->i;
- iLast = ps->p->iLast;
+ i = p->i;
+ iLast = p->iLast;
out = tHighpass_tick(&ps->hp, ps->outBuffer[iLast]);
- if (ps->p->indexstore >= ps->frameSize)
+ if (p->indexstore >= ps->frameSize)
{
- period = ps->p->period;
+ period = p->period;
if(pitchshift_attackdetect(ps) == 1)
{
- ps->p->fba = 5;
- tSOLAD_setReadLag(&ps->sola, ps->p->windowSize);
+ p->fba = 5;
+ tSOLAD_setReadLag(&ps->sola, p->windowSize);
}
tSOLAD_setPeriod(&ps->sola, period);
@@ -814,10 +904,10 @@
ps->pitchFactor = period/fun(period);
tSOLAD_setPitchFactor(&ps->sola, ps->pitchFactor);
- tSOLAD_ioSamples(&ps->sola, &(ps->p->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
+ tSOLAD_ioSamples(&ps->sola, &(p->inBuffer[i]), &(ps->outBuffer[i]), ps->frameSize);
ps->curBlock++;
- if (ps->curBlock >= ps->p->framesPerBuffer) ps->curBlock = 0;
+ if (ps->curBlock >= p->framesPerBuffer) ps->curBlock = 0;
ps->lastBlock++;
if (ps->lastBlock >= ps->framesPerBuffer) ps->lastBlock = 0;
}
@@ -832,10 +922,10 @@
/***************** static function declarations *******************************/
/******************************************************************************/
-static void solad_init(tSOLAD *w);
-static inline float read_sample(tSOLAD *w, float floatindex);
-static void pitchdown(tSOLAD *w, float *out);
-static void pitchup(tSOLAD *w, float *out);
+static void solad_init(_tSOLAD *w);
+static inline float read_sample(_tSOLAD *w, float floatindex);
+static void pitchdown(_tSOLAD *w, float *out);
+static void pitchup(_tSOLAD *w, float *out);
/******************************************************************************/
/***************** public access functions ************************************/
@@ -842,21 +932,28 @@
/******************************************************************************/
// init
-void tSOLAD_init(tSOLAD* const w)
+void tSOLAD_init(tSOLAD* const wp)
{
+ _tSOLAD* w = *wp = (_tSOLAD*) leaf_alloc(sizeof(_tSOLAD));
+
w->pitchfactor = 1.;
w->delaybuf = (float*) leaf_alloc(sizeof(float) * (LOOPSIZE+16));
solad_init(w);
}
-void tSOLAD_free(tSOLAD* const w)
+void tSOLAD_free(tSOLAD* const wp)
{
+ _tSOLAD* w = *wp;
+
leaf_free(w->delaybuf);
+ leaf_free(w);
}
// send one block of input samples, receive one block of output samples
-void tSOLAD_ioSamples(tSOLAD* const w, float* in, float* out, int blocksize)
+void tSOLAD_ioSamples(tSOLAD* const wp, float* in, float* out, int blocksize)
{
+ _tSOLAD* w = *wp;
+
int i = w->timeindex;
int n = w->blocksize = blocksize;
@@ -871,22 +968,28 @@
}
// set periodicity analysis data
-void tSOLAD_setPeriod(tSOLAD* const w, float period)
+void tSOLAD_setPeriod(tSOLAD* const wp, float period)
{
+ _tSOLAD* w = *wp;
+
if(period > MAXPERIOD) period = MAXPERIOD;
if(period > MINPERIOD) w->period = period; // ignore period when too small
}
// set pitch factor between 0.25 and 4
-void tSOLAD_setPitchFactor(tSOLAD* const w, float pitchfactor)
+void tSOLAD_setPitchFactor(tSOLAD* const wp, float pitchfactor)
{
+ _tSOLAD* w = *wp;
+
if (pitchfactor <= 0.0f) return;
w->pitchfactor = pitchfactor;
}
// force readpointer lag
-void tSOLAD_setReadLag(tSOLAD* const w, float readlag)
+void tSOLAD_setReadLag(tSOLAD* const wp, float readlag)
{
+ _tSOLAD* w = *wp;
+
if(readlag < 0) readlag = 0;
if(readlag < w->readlag) // do not jump backward, only forward
{
@@ -898,8 +1001,10 @@
}
// reset state variables
-void tSOLAD_resetState(tSOLAD* const w)
+void tSOLAD_resetState(tSOLAD* const wp)
{
+ _tSOLAD* w = *wp;
+
int n = LOOPSIZE + 1;
float *buf = w->delaybuf;
@@ -939,7 +1044,7 @@
*/
-static void pitchdown(tSOLAD* const w, float *out)
+static void pitchdown(_tSOLAD* const w, float *out)
{
int n = w->blocksize;
float refindex = (float)(w->timeindex + LOOPSIZE); // no negative values!
@@ -1057,7 +1162,7 @@
possibility is done. A previous crossfade must be completed before a forward
jump is allowed.
*/
-static void pitchup(tSOLAD* const w, float *out)
+static void pitchup(_tSOLAD* const w, float *out)
{
int n = w->blocksize;
float refindex = (float)(w->timeindex + LOOPSIZE); // no negative values
@@ -1123,7 +1228,7 @@
}
// read one sample from delay buffer, with linear interpolation
-static inline float read_sample(tSOLAD* const w, float floatindex)
+static inline float read_sample(_tSOLAD* const w, float floatindex)
{
int index = (int)floatindex;
float fraction = floatindex - (float)index;
@@ -1133,7 +1238,7 @@
return (buf[index] + (fraction * (buf[index+1] - buf[index])));
}
-static void solad_init(tSOLAD* const w)
+static void solad_init(_tSOLAD* const w)
{
w->timeindex = 0;
w->xfadevalue = -1;
@@ -1145,8 +1250,10 @@
// FORMANTSHIFTER
//============================================================================================================
-void tFormantShifter_init(tFormantShifter* const fs, int bufsize, int order)
+void tFormantShifter_init(tFormantShifter* const fsr, int bufsize, int order)
{
+ _tFormantShifter* fs = *fsr = (_tFormantShifter*) leaf_alloc(sizeof(_tFormantShifter));
+
fs->ford = order;
fs->bufsize = bufsize;
fs->fk = (float*) leaf_alloc(sizeof(float) * fs->ford);
@@ -1175,8 +1282,10 @@
fs->cbi = 0;
}
-void tFormantShifter_free(tFormantShifter* const fs)
+void tFormantShifter_free(tFormantShifter* const fsr)
{
+ _tFormantShifter* fs = *fsr;
+
leaf_free(fs->fk);
leaf_free(fs->fb);
leaf_free(fs->fc);
@@ -1190,16 +1299,19 @@
leaf_free(fs->fbuff[i]);
}
leaf_free(fs->fbuff);
+ leaf_free(fs);
}
-float tFormantShifter_tick(tFormantShifter* fs, float in, float fwarp)
+float tFormantShifter_tick(tFormantShifter* fsr, float in, float fwarp)
{
- return tFormantShifter_add(fs, tFormantShifter_remove(fs, in), fwarp);
+ return tFormantShifter_add(fsr, tFormantShifter_remove(fsr, in), fwarp);
}
-float tFormantShifter_remove(tFormantShifter* fs, float in)
+float tFormantShifter_remove(tFormantShifter* fsr, float in)
{
+ _tFormantShifter* fs = *fsr;
+
float fa, fb, fc, foma, falph, ford, flpa, flamb, tf, fk;
int ti4;
ford = fs->ford;
@@ -1238,8 +1350,10 @@
return fa;
}
-float tFormantShifter_add(tFormantShifter* fs, float in, float fwarp)
+float tFormantShifter_add(tFormantShifter* fsr, float in, float fwarp)
{
+ _tFormantShifter* fs = *fsr;
+
float fa, fb, fc, foma, falph, ford, flpa, flamb, tf, tf2, f0resp, f1resp, frlamb;
int ti4;
ford = fs->ford;
@@ -1247,7 +1361,7 @@
foma = (1.0f - falph);
flpa = fs->flpa;
flamb = fs->flamb;
- tf = exp2(fwarp/2.0f) * (1+flamb)/(1-flamb);
+ tf = exp2f(fwarp*0.5f) * (1+flamb)/(1-flamb);
frlamb = (tf-1)/(tf+1);
ti4 = fs->cbi;
--- a/LEAF/Src/leaf-electrical.c
+++ b/LEAF/Src/leaf-electrical.c
@@ -46,8 +46,10 @@
static float get_reflected_wave_for_diode_pair(tWDF* const n, float input, float incident_wave);
//WDF
-void tWDF_init(tWDF* const r, WDFComponentType type, float value, tWDF* const rL, tWDF* const rR)
+void tWDF_init(tWDF* const wdf, WDFComponentType type, float value, tWDF* const rL, tWDF* const rR)
{
+ _tWDF* r = *wdf = (_tWDF*) leaf_alloc(sizeof(_tWDF));
+
r->type = type;
r->child_left = rL;
r->child_right = rR;
@@ -163,19 +165,23 @@
}
}
-void tWDF_free(tWDF* const r)
+void tWDF_free(tWDF* const wdf)
{
-
+ _tWDF* r = *wdf;
+
+ leaf_free(r);
}
-float tWDF_tick(tWDF* const r, float sample, tWDF* const outputPoint, uint8_t paramsChanged)
+float tWDF_tick(tWDF* const wdf, float sample, tWDF* const outputPoint, uint8_t paramsChanged)
{
+ _tWDF* r = *wdf;
+
tWDF* child;
if (r->child_left != NULL) child = r->child_left;
else child = r->child_right;
//step 0 : update port resistances if something changed
- if (paramsChanged) tWDF_getPortResistance(r);
+ if (paramsChanged) tWDF_getPortResistance(wdf);
//step 1 : set inputs to what they should be
float input = sample;
@@ -184,7 +190,7 @@
r->incident_wave_up = tWDF_getReflectedWaveUp(child, input);
//step 3 : do root scattering computation
- r->reflected_wave_up = tWDF_getReflectedWaveDown(r, input, r->incident_wave_up);
+ r->reflected_wave_up = tWDF_getReflectedWaveDown(wdf, input, r->incident_wave_up);
//step 4 : propogate waves down the tree
tWDF_setIncidentWave(child, r->reflected_wave_up, input);
@@ -193,49 +199,58 @@
return tWDF_getVoltage(outputPoint);
}
-void tWDF_setValue(tWDF* const r, float value)
+void tWDF_setValue(tWDF* const wdf, float value)
{
+ _tWDF* r = *wdf;
r->value = value;
}
-void tWDF_setSampleRate(tWDF* const r, float sample_rate)
+void tWDF_setSampleRate(tWDF* const wdf, float sample_rate)
{
+ _tWDF* r = *wdf;
r->sample_rate = sample_rate;
}
-uint8_t tWDF_isLeaf(tWDF* const r)
+uint8_t tWDF_isLeaf(tWDF* const wdf)
{
+ _tWDF* r = *wdf;
if (r->child_left == NULL && r->child_right == NULL) return 1;
return 0;
}
-float tWDF_getPortResistance(tWDF* const r)
+float tWDF_getPortResistance(tWDF* const wdf)
{
- return r->get_port_resistance(r);
+ _tWDF* r = *wdf;
+ return r->get_port_resistance(wdf);
}
-void tWDF_setIncidentWave(tWDF* const r, float incident_wave, float input)
+void tWDF_setIncidentWave(tWDF* const wdf, float incident_wave, float input)
{
- r->set_incident_wave(r, incident_wave, input);
+ _tWDF* r = *wdf;
+ r->set_incident_wave(wdf, incident_wave, input);
}
-float tWDF_getReflectedWaveUp(tWDF* const r, float input)
+float tWDF_getReflectedWaveUp(tWDF* const wdf, float input)
{
- return r->get_reflected_wave_up(r, input);
+ _tWDF* r = *wdf;
+ return r->get_reflected_wave_up(wdf, input);
}
-float tWDF_getReflectedWaveDown(tWDF* const r, float input, float incident_wave)
+float tWDF_getReflectedWaveDown(tWDF* const wdf, float input, float incident_wave)
{
- return r->get_reflected_wave_down(r, input, incident_wave);
+ _tWDF* r = *wdf;
+ return r->get_reflected_wave_down(wdf, input, incident_wave);
}
-float tWDF_getVoltage(tWDF* const r)
+float tWDF_getVoltage(tWDF* const wdf)
{
+ _tWDF* r = *wdf;
return ((r->incident_wave_up * 0.5f) + (r->reflected_wave_up * 0.5f));
}
-float tWDF_getCurrent(tWDF* const r)
+float tWDF_getCurrent(tWDF* const wdf)
{
+ _tWDF* r = *wdf;
return (((r->incident_wave_up * 0.5f) - (r->reflected_wave_up * 0.5f)) * r->port_conductance_up);
}
@@ -243,8 +258,10 @@
//===================================================================
//============ Get and Calculate Port Resistances ===================
-static float get_port_resistance_for_resistor(tWDF* const r)
+static float get_port_resistance_for_resistor(tWDF* const wdf)
{
+ _tWDF* r = *wdf;
+
r->port_resistance_up = r->value;
r->port_conductance_up = 1.0f / r->value;
@@ -251,8 +268,10 @@
return r->port_resistance_up;
}
-static float get_port_resistance_for_capacitor(tWDF* const r)
+static float get_port_resistance_for_capacitor(tWDF* const wdf)
{
+ _tWDF* r = *wdf;
+
r->port_conductance_up = r->sample_rate * 2.0f * r->value; //based on trapezoidal discretization
r->port_resistance_up = (1.0f / r->port_conductance_up);
@@ -259,8 +278,10 @@
return r->port_resistance_up;
}
-static float get_port_resistance_for_inductor(tWDF* const r)
+static float get_port_resistance_for_inductor(tWDF* const wdf)
{
+ _tWDF* r = *wdf;
+
r->port_resistance_up = r->sample_rate * 2.0f * r->value; //based on trapezoidal discretization
r->port_conductance_up = (1.0f / r->port_resistance_up);
@@ -267,8 +288,10 @@
return r->port_resistance_up;
}
-static float get_port_resistance_for_resistive(tWDF* const r)
+static float get_port_resistance_for_resistive(tWDF* const wdf)
{
+ _tWDF* r = *wdf;
+
r->port_resistance_up = r->value;
r->port_conductance_up = 1.0f / r->port_resistance_up;
@@ -275,8 +298,10 @@
return r->port_resistance_up;
}
-static float get_port_resistance_for_inverter(tWDF* const r)
+static float get_port_resistance_for_inverter(tWDF* const wdf)
{
+ _tWDF* r = *wdf;
+
r->port_resistance_up = tWDF_getPortResistance(r->child_left);
r->port_conductance_up = 1.0f / r->port_resistance_up;
@@ -283,8 +308,10 @@
return r->port_resistance_up;
}
-static float get_port_resistance_for_series(tWDF* const r)
+static float get_port_resistance_for_series(tWDF* const wdf)
{
+ _tWDF* r = *wdf;
+
r->port_resistance_left = tWDF_getPortResistance(r->child_left);
r->port_resistance_right = tWDF_getPortResistance(r->child_right);
r->port_resistance_up = r->port_resistance_left + r->port_resistance_right;
@@ -296,8 +323,10 @@
return r->port_resistance_up;
}
-static float get_port_resistance_for_parallel(tWDF* const r)
+static float get_port_resistance_for_parallel(tWDF* const wdf)
{
+ _tWDF* r = *wdf;
+
r->port_resistance_left = tWDF_getPortResistance(r->child_left);
r->port_resistance_right = tWDF_getPortResistance(r->child_right);
r->port_resistance_up = (r->port_resistance_left * r->port_resistance_right) / (r->port_resistance_left + r->port_resistance_right);
@@ -309,8 +338,10 @@
return r->port_resistance_up;
}
-static float get_port_resistance_for_root(tWDF* const r)
+static float get_port_resistance_for_root(tWDF* const wdf)
{
+ _tWDF* r = *wdf;
+
tWDF* child;
if (r->child_left != NULL) child = r->child_left;
else child = r->child_right;
@@ -324,24 +355,29 @@
//===================================================================
//================ Set Incident Waves ===============================
-static void set_incident_wave_for_leaf(tWDF* const r, float incident_wave, float input)
+static void set_incident_wave_for_leaf(tWDF* const wdf, float incident_wave, float input)
{
+ _tWDF* r = *wdf;
r->incident_wave_up = incident_wave;
}
-static void set_incident_wave_for_leaf_inverted(tWDF* const r, float incident_wave, float input)
+static void set_incident_wave_for_leaf_inverted(tWDF* const wdf, float incident_wave, float input)
{
+ _tWDF* r = *wdf;
r->incident_wave_up = -1.0f * incident_wave;
}
-static void set_incident_wave_for_inverter(tWDF* const r, float incident_wave, float input)
+static void set_incident_wave_for_inverter(tWDF* const wdf, float incident_wave, float input)
{
+ _tWDF* r = *wdf;
r->incident_wave_up = incident_wave;
tWDF_setIncidentWave(r->child_left, -1.0f * incident_wave, input);
}
-static void set_incident_wave_for_series(tWDF* const r, float incident_wave, float input)
+static void set_incident_wave_for_series(tWDF* const wdf, float incident_wave, float input)
{
+ _tWDF* r = *wdf;
+
r->incident_wave_up = incident_wave;
float gamma_left = r->port_resistance_left * r->gamma_zero;
float gamma_right = r->port_resistance_right * r->gamma_zero;
@@ -357,8 +393,10 @@
}
-static void set_incident_wave_for_parallel(tWDF* const r, float incident_wave, float input)
+static void set_incident_wave_for_parallel(tWDF* const wdf, float incident_wave, float input)
{
+ _tWDF* r = *wdf;
+
r->incident_wave_up = incident_wave;
float gamma_left = r->port_conductance_left * r->gamma_zero;
float gamma_right = r->port_conductance_right * r->gamma_zero;
@@ -373,39 +411,46 @@
//===================================================================
//================ Get Reflected Waves ==============================
-static float get_reflected_wave_for_resistor(tWDF* const r, float input)
+static float get_reflected_wave_for_resistor(tWDF* const wdf, float input)
{
+ _tWDF* r = *wdf;
r->reflected_wave_up = 0.0f;
return r->reflected_wave_up;
}
-static float get_reflected_wave_for_capacitor(tWDF* const r, float input)
+static float get_reflected_wave_for_capacitor(tWDF* const wdf, float input)
{
+ _tWDF* r = *wdf;
r->reflected_wave_up = r->incident_wave_up;
return r->reflected_wave_up;
}
-static float get_reflected_wave_for_resistive(tWDF* const r, float input)
+static float get_reflected_wave_for_resistive(tWDF* const wdf, float input)
{
+ _tWDF* r = *wdf;
r->reflected_wave_up = input;
return r->reflected_wave_up;
}
-static float get_reflected_wave_for_inverter(tWDF* const r, float input)
+static float get_reflected_wave_for_inverter(tWDF* const wdf, float input)
{
+ _tWDF* r = *wdf;
r->reflected_wave_up = -1.0f * tWDF_getReflectedWaveUp(r->child_left, input);
return r->reflected_wave_up;
}
-static float get_reflected_wave_for_series(tWDF* const r, float input)
+static float get_reflected_wave_for_series(tWDF* const wdf, float input)
{
+ _tWDF* r = *wdf;
//-( downPorts[0]->a + downPorts[1]->a );
r->reflected_wave_up = (-1.0f * (tWDF_getReflectedWaveUp(r->child_left, input) + tWDF_getReflectedWaveUp(r->child_right, input)));
return r->reflected_wave_up;
}
-static float get_reflected_wave_for_parallel(tWDF* const r, float input)
+static float get_reflected_wave_for_parallel(tWDF* const wdf, float input)
{
+ _tWDF* r = *wdf;
+
float gamma_left = r->port_conductance_left * r->gamma_zero;
float gamma_right = r->port_conductance_right * r->gamma_zero;
//return ( dl * downPorts[0]->a + dr * downPorts[1]->a );
@@ -413,7 +458,7 @@
return r->reflected_wave_up;
}
-static float get_reflected_wave_for_ideal(tWDF* const n, float input, float incident_wave)
+static float get_reflected_wave_for_ideal(tWDF* const wdf, float input, float incident_wave)
{
return (2.0f * input) - incident_wave;
}
@@ -462,15 +507,19 @@
#define Is_DIODE 2.52e-9f
#define VT_DIODE 0.02585f
-static float get_reflected_wave_for_diode(tWDF* const n, float input, float incident_wave)
+static float get_reflected_wave_for_diode(tWDF* const wdf, float input, float incident_wave)
{
+ _tWDF* n = *wdf;
+
float a = incident_wave;
float r = n->port_resistance_up;
return a + 2.0f*r*Is_DIODE - 2.0f*VT_DIODE*lambertW(a, r, Is_DIODE, 1.0f/VT_DIODE);
}
-static float get_reflected_wave_for_diode_pair(tWDF* const n, float input, float incident_wave)
+static float get_reflected_wave_for_diode_pair(tWDF* const wdf, float input, float incident_wave)
{
+ _tWDF* n = *wdf;
+
float a = incident_wave;
float sgn = 0.0f;
if (a > 0.0f) sgn = 1.0f;
--- a/LEAF/Src/leaf-envelopes.c
+++ b/LEAF/Src/leaf-envelopes.c
@@ -24,8 +24,10 @@
#endif
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Envelope ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
-void tEnvelope_init(tEnvelope* const env, float attack, float decay, oBool loop)
+void tEnvelope_init(tEnvelope* const envlp, float attack, float decay, oBool loop)
{
+ _tEnvelope* env = *envlp = (_tEnvelope*) leaf_alloc(sizeof(_tEnvelope));
+
env->exp_buff = exp_decay;
env->inc_buff = attack_decay_inc;
env->buff_size = sizeof(exp_decay);
@@ -63,13 +65,16 @@
}
-void tEnvelope_free(tEnvelope* const env)
+void tEnvelope_free(tEnvelope* const envlp)
{
-
+ _tEnvelope* env = *envlp;
+ leaf_free(env);
}
-int tEnvelope_setAttack(tEnvelope* const env, float attack)
+void tEnvelope_setAttack(tEnvelope* const envlp, float attack)
{
+ _tEnvelope* env = *envlp;
+
int32_t attackIndex;
if (attack < 0.0f) {
@@ -81,12 +86,12 @@
}
env->attackInc = env->inc_buff[attackIndex];
-
- return 0;
}
-int tEnvelope_setDecay(tEnvelope* const env, float decay)
+void tEnvelope_setDecay(tEnvelope* const envlp, float decay)
{
+ _tEnvelope* env = *envlp;
+
int32_t decayIndex;
if (decay < 0.0f) {
@@ -97,21 +102,20 @@
decayIndex = ((int32_t)(8192.0f * 8.0f)) - 1;
}
- env->decayInc = env->inc_buff[decayIndex];
-
- return 0;
+ env->decayInc = env->inc_buff[decayIndex];
}
-int tEnvelope_loop(tEnvelope* const env, oBool loop)
+void tEnvelope_loop(tEnvelope* const envlp, oBool loop)
{
+ _tEnvelope* env = *envlp;
env->loop = loop;
-
- return 0;
}
-int tEnvelope_on(tEnvelope* const env, float velocity)
+void tEnvelope_on(tEnvelope* const envlp, float velocity)
{
+ _tEnvelope* env = *envlp;
+
if (env->inAttack || env->inDecay) // In case envelope retriggered while it is still happening.
{
env->rampPhase = 0;
@@ -128,12 +132,12 @@
env->decayPhase = 0;
env->inDecay = OFALSE;
env->gain = velocity;
-
- return 0;
}
-float tEnvelope_tick(tEnvelope* const env)
+float tEnvelope_tick(tEnvelope* const envlp)
{
+ _tEnvelope* env = *envlp;
+
if (env->inRamp)
{
if (env->rampPhase > UINT16_MAX)
@@ -203,8 +207,10 @@
}
/* ADSR */
-void tADSR_init(tADSR* const adsr, float attack, float decay, float sustain, float release)
+void tADSR_init(tADSR* const adsrenv, float attack, float decay, float sustain, float release)
{
+ _tADSR* adsr = *adsrenv = (_tADSR*) leaf_alloc(sizeof(_tADSR));
+
adsr->exp_buff = exp_decay;
adsr->inc_buff = attack_decay_inc;
adsr->buff_size = sizeof(exp_decay);
@@ -257,13 +263,17 @@
adsr->rampInc = adsr->inc_buff[rampIndex];
}
-void tADSR_free(tADSR* const adsr)
+void tADSR_free(tADSR* const adsrenv)
{
+ _tADSR* adsr = *adsrenv;
+ leaf_free(adsr);
}
-int tADSR_setAttack(tADSR* const adsr, float attack)
+void tADSR_setAttack(tADSR* const adsrenv, float attack)
{
+ _tADSR* adsr = *adsrenv;
+
int32_t attackIndex;
if (attack < 0.0f) {
@@ -275,12 +285,12 @@
}
adsr->attackInc = adsr->inc_buff[attackIndex];
-
- return 0;
}
-int tADSR_detDecay(tADSR* const adsr, float decay)
+void tADSR_detDecay(tADSR* const adsrenv, float decay)
{
+ _tADSR* adsr = *adsrenv;
+
int32_t decayIndex;
if (decay < 0.0f) {
@@ -292,21 +302,21 @@
}
adsr->decayInc = adsr->inc_buff[decayIndex];
-
- return 0;
}
-int tADSR_setSustain(tADSR *const adsr, float sustain)
+void tADSR_setSustain(tADSR* const adsrenv, float sustain)
{
+ _tADSR* adsr = *adsrenv;
+
if (sustain > 1.0f) adsr->sustain = 1.0f;
else if (sustain < 0.0f) adsr->sustain = 0.0f;
else adsr->sustain = sustain;
-
- return 0;
}
-int tADSR_setRelease(tADSR* const adsr, float release)
+void tADSR_setRelease(tADSR* const adsrenv, float release)
{
+ _tADSR* adsr = *adsrenv;
+
int32_t releaseIndex;
if (release < 0.0f) {
@@ -318,12 +328,12 @@
}
adsr->releaseInc = adsr->inc_buff[releaseIndex];
-
- return 0;
}
-int tADSR_on(tADSR* const adsr, float velocity)
+void tADSR_on(tADSR* const adsrenv, float velocity)
{
+ _tADSR* adsr = *adsrenv;
+
if ((adsr->inAttack || adsr->inDecay) || (adsr->inSustain || adsr->inRelease)) // In case ADSR retriggered while it is still happening.
{
adsr->rampPhase = 0;
@@ -342,14 +352,14 @@
adsr->inSustain = OFALSE;
adsr->inRelease = OFALSE;
adsr->gain = velocity;
-
- return 0;
}
-int tADSR_off(tADSR* const adsr)
+void tADSR_off(tADSR* const adsrenv)
{
- if (adsr->inRelease) return 0;
+ _tADSR* adsr = *adsrenv;
+ if (adsr->inRelease) return;
+
adsr->inAttack = OFALSE;
adsr->inDecay = OFALSE;
adsr->inSustain = OFALSE;
@@ -356,12 +366,12 @@
adsr->inRelease = OTRUE;
adsr->releasePeak = adsr->next;
-
- return 0;
}
-float tADSR_tick(tADSR* const adsr)
+float tADSR_tick(tADSR* const adsrenv)
{
+ _tADSR* adsr = *adsrenv;
+
if (adsr->inRamp)
{
if (adsr->rampPhase > UINT16_MAX)
@@ -440,8 +450,10 @@
}
/* Ramp */
-void tRamp_init(tRamp* const ramp, float time, int samples_per_tick)
+void tRamp_init(tRamp* const r, float time, int samples_per_tick)
{
+ _tRamp* ramp = *r = (_tRamp*) leaf_alloc(sizeof(_tRamp));
+
ramp->inv_sr_ms = 1.0f/(leaf.sampleRate*0.001f);
ramp->minimum_time = ramp->inv_sr_ms * samples_per_tick;
ramp->curr = 0.0f;
@@ -460,13 +472,17 @@
ramp->inc = ((ramp->dest - ramp->curr) / ramp->time * ramp->inv_sr_ms) * (float)ramp->samples_per_tick;
}
-void tRamp_free(tRamp* const ramp)
+void tRamp_free(tRamp* const r)
{
+ _tRamp* ramp = *r;
+ leaf_free(ramp);
}
-int tRamp_setTime(tRamp* const r, float time)
+void tRamp_setTime(tRamp* const ramp, float time)
{
+ _tRamp* r = *ramp;
+
if (time < r->minimum_time)
{
r->time = r->minimum_time;
@@ -476,24 +492,25 @@
r->time = time;
}
r->inc = ((r->dest-r->curr)/r->time * r->inv_sr_ms) * ((float)r->samples_per_tick);
- return 0;
}
-int tRamp_setDest(tRamp* const r, float dest)
+void tRamp_setDest(tRamp* const ramp, float dest)
{
+ _tRamp* r = *ramp;
r->dest = dest;
r->inc = ((r->dest-r->curr)/r->time * r->inv_sr_ms) * ((float)r->samples_per_tick);
- return 0;
}
-int tRamp_setVal(tRamp* const r, float val)
+void tRamp_setVal(tRamp* const ramp, float val)
{
+ _tRamp* r = *ramp;
r->curr = val;
r->inc = ((r->dest-r->curr)/r->time * r->inv_sr_ms) * ((float)r->samples_per_tick);
- return 0;
}
-float tRamp_tick(tRamp* const r) {
+float tRamp_tick(tRamp* const ramp)
+{
+ _tRamp* r = *ramp;
r->curr += r->inc;
@@ -504,13 +521,15 @@
return r->curr;
}
-float tRamp_sample(tRamp* const r) {
-
+float tRamp_sample(tRamp* const ramp)
+{
+ _tRamp* r = *ramp;
return r->curr;
}
-void tRampSampleRateChanged(tRamp* const r)
+void tRampSampleRateChanged(tRamp* const ramp)
{
+ _tRamp* r = *ramp;
r->inv_sr_ms = 1.0f / (leaf.sampleRate * 0.001f);
r->inc = ((r->dest-r->curr)/r->time * r->inv_sr_ms)*((float)r->samples_per_tick);
}
@@ -517,8 +536,10 @@
/* Exponential Smoother */
-void tExpSmooth_init(tExpSmooth* const smooth, float val, float factor)
+void tExpSmooth_init(tExpSmooth* const expsmooth, float val, float factor)
{ // factor is usually a value between 0 and 0.1. Lower value is slower. 0.01 for example gives you a smoothing time of about 10ms
+ _tExpSmooth* smooth = *expsmooth = (_tExpSmooth*) leaf_alloc(sizeof(_tExpSmooth));
+
smooth->curr=val;
smooth->dest=val;
if (factor<0) factor=0;
@@ -527,13 +548,17 @@
smooth->oneminusfactor=1.0f-factor;
}
-void tExpSmooth_free(tExpSmooth* const smooth)
+void tExpSmooth_free(tExpSmooth* const expsmooth)
{
+ _tExpSmooth* smooth = *expsmooth;
+ leaf_free(smooth);
}
-int tExpSmooth_setFactor(tExpSmooth* const smooth, float factor)
+void tExpSmooth_setFactor(tExpSmooth* const expsmooth, float factor)
{ // factor is usually a value between 0 and 0.1. Lower value is slower. 0.01 for example gives you a smoothing time of about 10ms
+ _tExpSmooth* smooth = *expsmooth;
+
if (factor<0)
factor=0;
else
@@ -540,29 +565,30 @@
if (factor>1) factor=1;
smooth->factor=factor;
smooth->oneminusfactor=1.0f-factor;
- return 0;
}
-int tExpSmooth_setDest(tExpSmooth* const smooth, float dest)
+void tExpSmooth_setDest(tExpSmooth* const expsmooth, float dest)
{
+ _tExpSmooth* smooth = *expsmooth;
smooth->dest=dest;
- return 0;
}
-int tExpSmooth_setVal(tExpSmooth* const smooth, float val)
+void tExpSmooth_setVal(tExpSmooth* const expsmooth, float val)
{
+ _tExpSmooth* smooth = *expsmooth;
smooth->curr=val;
- return 0;
}
-float tExpSmooth_tick(tExpSmooth* const smooth)
+float tExpSmooth_tick(tExpSmooth* const expsmooth)
{
+ _tExpSmooth* smooth = *expsmooth;
smooth->curr = smooth->factor*smooth->dest+smooth->oneminusfactor*smooth->curr;
return smooth->curr;
}
-float tExpSmooth_sample(tExpSmooth* const smooth)
+float tExpSmooth_sample(tExpSmooth* const expsmooth)
{
+ _tExpSmooth* smooth = *expsmooth;
return smooth->curr;
}
--- a/LEAF/Src/leaf-filters.c
+++ b/LEAF/Src/leaf-filters.c
@@ -21,8 +21,10 @@
#endif
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ OnePole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
-void tAllpass_init(tAllpass* const f, float initDelay, uint32_t maxDelay)
+void tAllpass_init(tAllpass* const ft, float initDelay, uint32_t maxDelay)
{
+ _tAllpass* f = *ft = (_tAllpass*) leaf_alloc(sizeof(_tAllpass));
+
f->gain = 0.7f;
f->lastOut = 0.0f;
@@ -30,23 +32,32 @@
tLinearDelay_init(&f->delay, initDelay, maxDelay);
}
-void tAllpass_free(tAllpass* const f)
+void tAllpass_free(tAllpass* const ft)
{
+ _tAllpass* f = *ft;
+
tLinearDelay_free(&f->delay);
+ leaf_free(f);
}
-void tAllpass_setDelay(tAllpass* const f, float delay)
+void tAllpass_setDelay(tAllpass* const ft, float delay)
{
+ _tAllpass* f = *ft;
+
tLinearDelay_setDelay(&f->delay, delay);
}
-void tAllpass_setGain(tAllpass* const f, float gain)
+void tAllpass_setGain(tAllpass* const ft, float gain)
{
+ _tAllpass* f = *ft;
+
f->gain = gain;
}
-float tAllpass_tick(tAllpass* const f, float input)
+float tAllpass_tick(tAllpass* const ft, float input)
{
+ _tAllpass* f = *ft;
+
float s1 = (-f->gain) * f->lastOut + input;
float s2 = tLinearDelay_tick(&f->delay, s1) + (f->gain) * input;
@@ -56,8 +67,10 @@
return f->lastOut;
}
-void tButterworth_init(tButterworth* const f, int N, float f1, float f2)
+void tButterworth_init(tButterworth* const ft, int N, float f1, float f2)
{
+ _tButterworth* f = *ft = (_tButterworth*) leaf_alloc(sizeof(_tButterworth));
+
f->f1 = f1;
f->f2 = f2;
f->gain = 1.0f;
@@ -73,17 +86,23 @@
}
}
-void tButterworth_free(tButterworth* const f)
+void tButterworth_free(tButterworth* const ft)
{
+ _tButterworth* f = *ft;
+
for(int i = 0; i < f->N/2; ++i)
{
tSVF_free(&f->low[i]);
tSVF_free(&f->high[i]);
}
+
+ leaf_free(f);
}
-float tButterworth_tick(tButterworth* const f, float samp)
+float tButterworth_tick(tButterworth* const ft, float samp)
{
+ _tButterworth* f = *ft;
+
for(int i = 0; i < ((f->N)/2); ++i)
{
samp = tSVF_tick(&f->low[i],samp);
@@ -92,20 +111,26 @@
return samp;
}
-void tButterworth_setF1(tButterworth* const f, float f1)
+void tButterworth_setF1(tButterworth* const ft, float f1)
{
+ _tButterworth* f = *ft;
+
f->f1 = f1;
for(int i = 0; i < ((f->N)/2); ++i) tSVF_setFreq(&f->low[i], f1);
}
-void tButterworth_setF2(tButterworth* const f, float f2)
+void tButterworth_setF2(tButterworth* const ft, float f2)
{
+ _tButterworth* f = *ft;
+
f->f2 = f2;
for(int i = 0; i < ((f->N)/2); ++i) tSVF_setFreq(&f->high[i], f2);
}
-void tButterworth_setFreqs(tButterworth* const f, float f1, float f2)
+void tButterworth_setFreqs(tButterworth* const ft, float f1, float f2)
{
+ _tButterworth* f = *ft;
+
f->f1 = f1;
f->f2 = f2;
for(int i = 0; i < ((f->N)/2); ++i)
@@ -116,21 +141,27 @@
}
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ OneZero Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
-void tOneZero_init(tOneZero* const f, float theZero)
+void tOneZero_init(tOneZero* const ft, float theZero)
{
+ _tOneZero* f = *ft = (_tOneZero*) leaf_alloc(sizeof(_tOneZero));
+
f->gain = 1.0f;
f->lastIn = 0.0f;
f->lastOut = 0.0f;
- tOneZero_setZero(f, theZero);
+ tOneZero_setZero(ft, theZero);
}
-void tOneZero_free(tOneZero* const f)
+void tOneZero_free(tOneZero* const ft)
{
+ _tOneZero* f = *ft;
+ leaf_free(f);
}
-float tOneZero_tick(tOneZero* const f, float input)
+float tOneZero_tick(tOneZero* const ft, float input)
{
+ _tOneZero* f = *ft;
+
float in = input * f->gain;
float out = f->b1 * f->lastIn + f->b0 * in;
@@ -139,8 +170,10 @@
return out;
}
-void tOneZero_setZero(tOneZero* const f, float theZero)
+void tOneZero_setZero(tOneZero* const ft, float theZero)
{
+ _tOneZero* f = *ft;
+
if (theZero > 0.0f) f->b0 = 1.0f / (1.0f + theZero);
else f->b0 = 1.0f / (1.0f - theZero);
@@ -148,29 +181,36 @@
}
-void tOneZero_setB0(tOneZero* const f, float b0)
+void tOneZero_setB0(tOneZero* const ft, float b0)
{
+ _tOneZero* f = *ft;
+
f->b0 = b0;
}
-void tOneZero_setB1(tOneZero* const f, float b1)
+void tOneZero_setB1(tOneZero* const ft, float b1)
{
+ _tOneZero* f = *ft;
f->b1 = b1;
}
-void tOneZero_setCoefficients(tOneZero* const f, float b0, float b1)
+void tOneZero_setCoefficients(tOneZero* const ft, float b0, float b1)
{
+ _tOneZero* f = *ft;
f->b0 = b0;
f->b1 = b1;
}
-void tOneZero_setGain(tOneZero *f, float gain)
+void tOneZero_setGain(tOneZero *ft, float gain)
{
+ _tOneZero* f = *ft;
f->gain = gain;
}
-float tOneZero_getPhaseDelay(tOneZero* const f, float frequency )
+float tOneZero_getPhaseDelay(tOneZero* const ft, float frequency )
{
+ _tOneZero* f = *ft;
+
if ( frequency <= 0.0f) frequency = 0.05f;
f->frequency = frequency;
@@ -198,20 +238,26 @@
}
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ TwoZero Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
-void tTwoZero_init(tTwoZero* const f)
+void tTwoZero_init(tTwoZero* const ft)
{
+ _tTwoZero* f = *ft = (_tTwoZero*) leaf_alloc(sizeof(_tTwoZero));
+
f->gain = 1.0f;
f->lastIn[0] = 0.0f;
f->lastIn[1] = 0.0f;
}
-void tTwoZero_free(tTwoZero* const f)
+void tTwoZero_free(tTwoZero* const ft)
{
+ _tTwoZero* f = *ft;
+ leaf_free(f);
}
-float tTwoZero_tick(tTwoZero* const f, float input)
+float tTwoZero_tick(tTwoZero* const ft, float input)
{
+ _tTwoZero* f = *ft;
+
float in = input * f->gain;
float out = f->b2 * f->lastIn[1] + f->b1 * f->lastIn[0] + f->b0 * in;
@@ -221,8 +267,10 @@
return out;
}
-void tTwoZero_setNotch(tTwoZero* const f, float freq, float radius)
+void tTwoZero_setNotch(tTwoZero* const ft, float freq, float radius)
{
+ _tTwoZero* f = *ft;
+
// Should also deal with frequency being > half sample rate / nyquist. See STK
if (freq < 0.0f) freq = 0.0f;
if (radius < 0.0f) radius = 0.0f;
@@ -243,64 +291,77 @@
}
-void tTwoZero_setB0(tTwoZero* const f, float b0)
+void tTwoZero_setB0(tTwoZero* const ft, float b0)
{
+ _tTwoZero* f = *ft;
f->b0 = b0;
}
-void tTwoZero_setB1(tTwoZero* const f, float b1)
+void tTwoZero_setB1(tTwoZero* const ft, float b1)
{
+ _tTwoZero* f = *ft;
f->b1 = b1;
}
-void tTwoZero_setCoefficients(tTwoZero* const f, float b0, float b1, float b2)
+void tTwoZero_setCoefficients(tTwoZero* const ft, float b0, float b1, float b2)
{
+ _tTwoZero* f = *ft;
f->b0 = b0;
f->b1 = b1;
f->b2 = b2;
}
-void tTwoZero_setGain(tTwoZero* const f, float gain)
+void tTwoZero_setGain(tTwoZero* const ft, float gain)
{
+ _tTwoZero* f = *ft;
f->gain = gain;
}
-void tTwoZeroSampleRateChanged(tTwoZero* const f)
+void tTwoZeroSampleRateChanged(tTwoZero* const ft)
{
- tTwoZero_setNotch(f, f->frequency, f->radius);
+ _tTwoZero* f = *ft;
+
+ tTwoZero_setNotch(ft, f->frequency, f->radius);
}
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ OnePole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
-void tOnePole_init(tOnePole* const f, float freq)
+void tOnePole_init(tOnePole* const ft, float freq)
{
+ _tOnePole* f = *ft = (_tOnePole*) leaf_alloc(sizeof(_tOnePole));
+
f->gain = 1.0f;
f->a0 = 1.0;
- tOnePole_setFreq(f, freq);
+ tOnePole_setFreq(ft, freq);
f->lastIn = 0.0f;
f->lastOut = 0.0f;
}
-void tOnePole_free(tOnePole* const f)
+void tOnePole_free(tOnePole* const ft)
{
+ _tOnePole* f = *ft;
+ leaf_free(f);
}
-void tOnePole_setB0(tOnePole* const f, float b0)
+void tOnePole_setB0(tOnePole* const ft, float b0)
{
+ _tOnePole* f = *ft;
f->b0 = b0;
}
-void tOnePole_setA1(tOnePole* const f, float a1)
+void tOnePole_setA1(tOnePole* const ft, float a1)
{
+ _tOnePole* f = *ft;
if (a1 >= 1.0f) a1 = 0.999999f;
-
f->a1 = a1;
}
-void tOnePole_setPole(tOnePole* const f, float thePole)
+void tOnePole_setPole(tOnePole* const ft, float thePole)
{
+ _tOnePole* f = *ft;
+
if (thePole >= 1.0f) thePole = 0.999999f;
// Normalize coefficients for peak unity gain.
@@ -310,30 +371,32 @@
f->a1 = -thePole;
}
-void tOnePole_setFreq (tOnePole* const f, float freq)
+void tOnePole_setFreq (tOnePole* const ft, float freq)
{
+ _tOnePole* f = *ft;
f->b0 = freq * TWO_PI * leaf.invSampleRate;
-
f->b0 = LEAF_clip(0.0f, f->b0, 1.0f);
-
f->a1 = 1.0f - f->b0;
}
-void tOnePole_setCoefficients(tOnePole* const f, float b0, float a1)
+void tOnePole_setCoefficients(tOnePole* const ft, float b0, float a1)
{
+ _tOnePole* f = *ft;
if (a1 >= 1.0f) a1 = 0.999999f;
-
f->b0 = b0;
f->a1 = a1;
}
-void tOnePole_setGain(tOnePole* const f, float gain)
+void tOnePole_setGain(tOnePole* const ft, float gain)
{
+ _tOnePole* f = *ft;
f->gain = gain;
}
-float tOnePole_tick(tOnePole* const f, float input)
+float tOnePole_tick(tOnePole* const ft, float input)
{
+ _tOnePole* f = *ft;
+
float in = input * f->gain;
float out = (f->b0 * in) + (f->a1 * f->lastOut);
@@ -344,8 +407,10 @@
}
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ TwoPole Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
-void tTwoPole_init(tTwoPole* const f)
+void tTwoPole_init(tTwoPole* const ft)
{
+ _tTwoPole* f = *ft = (_tTwoPole*) leaf_alloc(sizeof(_tTwoPole));
+
f->gain = 1.0f;
f->a0 = 1.0;
f->b0 = 1.0;
@@ -354,13 +419,17 @@
f->lastOut[1] = 0.0f;
}
-void tTwoPole_free(tTwoPole* const f)
+void tTwoPole_free(tTwoPole* const ft)
{
+ _tTwoPole* f = *ft;
+ leaf_free(f);
}
-float tTwoPole_tick(tTwoPole* const f, float input)
+float tTwoPole_tick(tTwoPole* const ft, float input)
{
+ _tTwoPole* f = *ft;
+
float in = input * f->gain;
float out = (f->b0 * in) - (f->a1 * f->lastOut[0]) - (f->a2 * f->lastOut[1]);
@@ -370,24 +439,29 @@
return out;
}
-void tTwoPole_setB0(tTwoPole* const f, float b0)
+void tTwoPole_setB0(tTwoPole* const ft, float b0)
{
+ _tTwoPole* f = *ft;
f->b0 = b0;
}
-void tTwoPole_setA1(tTwoPole* const f, float a1)
+void tTwoPole_setA1(tTwoPole* const ft, float a1)
{
+ _tTwoPole* f = *ft;
f->a1 = a1;
}
-void tTwoPole_setA2(tTwoPole* const f, float a2)
+void tTwoPole_setA2(tTwoPole* const ft, float a2)
{
+ _tTwoPole* f = *ft;
f->a2 = a2;
}
-void tTwoPole_setResonance(tTwoPole* const f, float frequency, float radius, oBool normalize)
+void tTwoPole_setResonance(tTwoPole* const ft, float frequency, float radius, oBool normalize)
{
+ _tTwoPole* f = *ft;
+
if (frequency < 0.0f) frequency = 0.0f; // need to also handle when frequency > nyquist
if (radius < 0.0f) radius = 0.0f;
if (radius >= 1.0f) radius = 0.999999f;
@@ -408,20 +482,24 @@
}
}
-void tTwoPole_setCoefficients(tTwoPole* const f, float b0, float a1, float a2)
+void tTwoPole_setCoefficients(tTwoPole* const ft, float b0, float a1, float a2)
{
+ _tTwoPole* f = *ft;
f->b0 = b0;
f->a1 = a1;
f->a2 = a2;
}
-void tTwoPole_setGain(tTwoPole* const f, float gain)
+void tTwoPole_setGain(tTwoPole* const ft, float gain)
{
+ _tTwoPole* f = *ft;
f->gain = gain;
}
-void tTwoPoleSampleRateChanged (tTwoPole* const f)
+void tTwoPoleSampleRateChanged (tTwoPole* const ft)
{
+ _tTwoPole* f = *ft;
+
f->a2 = f->radius * f->radius;
f->a1 = -2.0f * f->radius * cos(TWO_PI * f->frequency * leaf.invSampleRate);
@@ -435,8 +513,10 @@
}
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ PoleZero Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
-void tPoleZero_init(tPoleZero* const f)
+void tPoleZero_init(tPoleZero* const pzf)
{
+ _tPoleZero* f = *pzf = (_tPoleZero*) leaf_alloc(sizeof(_tPoleZero));
+
f->gain = 1.0f;
f->b0 = 1.0;
f->a0 = 1.0;
@@ -445,88 +525,105 @@
f->lastOut = 0.0f;
}
-void tPoleZero_free(tPoleZero* const f)
+void tPoleZero_free(tPoleZero* const pzf)
{
+ _tPoleZero* f = *pzf;
+ leaf_free(f);
}
void tPoleZero_setB0(tPoleZero* const pzf, float b0)
{
- pzf->b0 = b0;
+ _tPoleZero* f = *pzf;
+ f->b0 = b0;
}
void tPoleZero_setB1(tPoleZero* const pzf, float b1)
{
- pzf->b1 = b1;
+ _tPoleZero* f = *pzf;
+ f->b1 = b1;
}
void tPoleZero_setA1(tPoleZero* const pzf, float a1)
{
+ _tPoleZero* f = *pzf;
+
if (a1 >= 1.0f) // a1 should be less than 1.0
{
a1 = 0.999999f;
}
- pzf->a1 = a1;
+ f->a1 = a1;
}
void tPoleZero_setCoefficients(tPoleZero* const pzf, float b0, float b1, float a1)
{
+ _tPoleZero* f = *pzf;
+
if (a1 >= 1.0f) // a1 should be less than 1.0
{
a1 = 0.999999f;
}
- pzf->b0 = b0;
- pzf->b1 = b1;
- pzf->a1 = a1;
+ f->b0 = b0;
+ f->b1 = b1;
+ f->a1 = a1;
}
void tPoleZero_setAllpass(tPoleZero* const pzf, float coeff)
{
+ _tPoleZero* f = *pzf;
+
if (coeff >= 1.0f) // allpass coefficient >= 1.0 makes filter unstable
{
coeff = 0.999999f;
}
- pzf->b0 = coeff;
- pzf->b1 = 1.0f;
- pzf->a0 = 1.0f;
- pzf->a1 = coeff;
+ f->b0 = coeff;
+ f->b1 = 1.0f;
+ f->a0 = 1.0f;
+ f->a1 = coeff;
}
void tPoleZero_setBlockZero(tPoleZero* const pzf, float thePole)
{
+ _tPoleZero* f = *pzf;
+
if (thePole >= 1.0f) // allpass coefficient >= 1.0 makes filter unstable
{
thePole = 0.999999f;
}
- pzf->b0 = 1.0f;
- pzf->b1 = -1.0f;
- pzf->a0 = 1.0f;
- pzf->a1 = -thePole;
+ f->b0 = 1.0f;
+ f->b1 = -1.0f;
+ f->a0 = 1.0f;
+ f->a1 = -thePole;
}
void tPoleZero_setGain(tPoleZero* const pzf, float gain)
{
- pzf->gain = gain;
+ _tPoleZero* f = *pzf;
+ f->gain = gain;
}
float tPoleZero_tick(tPoleZero* const pzf, float input)
{
- float in = input * pzf->gain;
- float out = (pzf->b0 * in) + (pzf->b1 * pzf->lastIn) - (pzf->a1 * pzf->lastOut);
+ _tPoleZero* f = *pzf;
- pzf->lastIn = in;
- pzf->lastOut = out;
+ float in = input * f->gain;
+ float out = (f->b0 * in) + (f->b1 * f->lastIn) - (f->a1 * f->lastOut);
+ f->lastIn = in;
+ f->lastOut = out;
+
return out;
}
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ BiQuad Filter ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
-void tBiQuad_init(tBiQuad* const f)
+void tBiQuad_init(tBiQuad* const ft)
{
+ _tBiQuad* f = *ft = (_tBiQuad*) leaf_alloc(sizeof(_tBiQuad));
+
f->gain = 1.0f;
f->b0 = 0.0f;
@@ -538,13 +635,17 @@
f->lastOut[1] = 0.0f;
}
-void tBiQuad_free(tBiQuad* const f)
+void tBiQuad_free(tBiQuad* const ft)
{
+ _tBiQuad* f = *ft;
+ leaf_free(f);
}
-float tBiQuad_tick(tBiQuad* const f, float input)
+float tBiQuad_tick(tBiQuad* const ft, float input)
{
+ _tBiQuad* f = *ft;
+
float in = input * f->gain;
float out = f->b0 * in + f->b1 * f->lastIn[0] + f->b2 * f->lastIn[1];
out -= f->a2 * f->lastOut[1] + f->a1 * f->lastOut[0];
@@ -558,8 +659,10 @@
return out;
}
-void tBiQuad_setResonance(tBiQuad* const f, float freq, float radius, oBool normalize)
+void tBiQuad_setResonance(tBiQuad* const ft, float freq, float radius, oBool normalize)
{
+ _tBiQuad* f = *ft;
+
// Should also deal with frequency being > half sample rate / nyquist. See STK
if (freq < 0.0f) freq = 0.0f;
if (radius < 0.0f) radius = 0.0f;
@@ -580,8 +683,10 @@
}
}
-void tBiQuad_setNotch(tBiQuad* const f, float freq, float radius)
+void tBiQuad_setNotch(tBiQuad* const ft, float freq, float radius)
{
+ _tBiQuad* f = *ft;
+
// Should also deal with frequency being > half sample rate / nyquist. See STK
if (freq < 0.0f) freq = 0.0f;
if (radius < 0.0f) radius = 0.0f;
@@ -592,40 +697,47 @@
// Does not attempt to normalize filter gain.
}
-void tBiQuad_setEqualGainZeros(tBiQuad* const f)
+void tBiQuad_setEqualGainZeros(tBiQuad* const ft)
{
+ _tBiQuad* f = *ft;
f->b0 = 1.0f;
f->b1 = 0.0f;
f->b2 = -1.0f;
}
-void tBiQuad_setB0(tBiQuad* const f, float b0)
+void tBiQuad_setB0(tBiQuad* const ft, float b0)
{
+ _tBiQuad* f = *ft;
f->b0 = b0;
}
-void tBiQuad_setB1(tBiQuad* const f, float b1)
+void tBiQuad_setB1(tBiQuad* const ft, float b1)
{
+ _tBiQuad* f = *ft;
f->b1 = b1;
}
-void tBiQuad_setB2(tBiQuad* const f, float b2)
+void tBiQuad_setB2(tBiQuad* const ft, float b2)
{
+ _tBiQuad* f = *ft;
f->b2 = b2;
}
-void tBiQuad_setA1(tBiQuad* const f, float a1)
+void tBiQuad_setA1(tBiQuad* const ft, float a1)
{
+ _tBiQuad* f = *ft;
f->a1 = a1;
}
-void tBiQuad_setA2(tBiQuad* const f, float a2)
+void tBiQuad_setA2(tBiQuad* const ft, float a2)
{
+ _tBiQuad* f = *ft;
f->a2 = a2;
}
-void tBiQuad_setCoefficients(tBiQuad* const f, float b0, float b1, float b2, float a1, float a2)
+void tBiQuad_setCoefficients(tBiQuad* const ft, float b0, float b1, float b2, float a1, float a2)
{
+ _tBiQuad* f = *ft;
f->b0 = b0;
f->b1 = b1;
f->b2 = b2;
@@ -633,13 +745,15 @@
f->a2 = a2;
}
-void tBiQuad_setGain(tBiQuad* const f, float gain)
+void tBiQuad_setGain(tBiQuad* const ft, float gain)
{
+ _tBiQuad* f = *ft;
f->gain = gain;
}
-void tBiQuadSampleRateChanged(tBiQuad* const f)
+void tBiQuadSampleRateChanged(tBiQuad* const ft)
{
+ _tBiQuad* f = *ft;
f->a2 = f->radius * f->radius;
f->a1 = -2.0f * f->radius * cosf(TWO_PI * f->frequency * leaf.invSampleRate);
@@ -652,8 +766,10 @@
}
/* Highpass */
-void tHighpass_init(tHighpass* const f, float freq)
+void tHighpass_init(tHighpass* const ft, float freq)
{
+ _tHighpass* f = *ft = (_tHighpass*) leaf_alloc(sizeof(_tHighpass));
+
f->R = (1.0f-((freq * 2.0f * 3.14f)* leaf.invSampleRate));
f->ys = 0.0f;
f->xs = 0.0f;
@@ -661,58 +777,48 @@
f->frequency = freq;
}
-void tHighpass_free(tHighpass* const f)
+void tHighpass_free(tHighpass* const ft)
{
+ _tHighpass* f = *ft;
+ leaf_free(f);
}
-void tHighpass_setFreq(tHighpass* const f, float freq)
+void tHighpass_setFreq(tHighpass* const ft, float freq)
{
+ _tHighpass* f = *ft;
f->frequency = freq;
f->R = (1.0f-((freq * 2.0f * 3.14f) * leaf.invSampleRate));
}
-float tHighpass_getFreq(tHighpass* const f)
+float tHighpass_getFreq(tHighpass* const ft)
{
+ _tHighpass* f = *ft;
return f->frequency;
}
// From JOS DC Blocker
-float tHighpass_tick(tHighpass* const f, float x)
+float tHighpass_tick(tHighpass* const ft, float x)
{
+ _tHighpass* f = *ft;
f->ys = x - f->xs + f->R * f->ys;
f->xs = x;
return f->ys;
}
-void tHighpassSampleRateChanged(tHighpass* const f)
+void tHighpassSampleRateChanged(tHighpass* const ft)
{
+ _tHighpass* f = *ft;
f->R = (1.0f-((f->frequency * 2.0f * 3.14f) * leaf.invSampleRate));
}
-float tSVF_tick(tSVF* const svf, float v0)
-{
- float v1,v2,v3;
- v3 = v0 - svf->ic2eq;
- v1 = (svf->a1 * svf->ic1eq) + (svf->a2 * v3);
- v2 = svf->ic2eq + (svf->a2 * svf->ic1eq) + (svf->a3 * v3);
- svf->ic1eq = (2.0f * v1) - svf->ic1eq;
- svf->ic2eq = (2.0f * v2) - svf->ic2eq;
-
- if (svf->type == SVFTypeLowpass) return v2;
- else if (svf->type == SVFTypeBandpass) return v1;
- else if (svf->type == SVFTypeHighpass) return v0 - (svf->k * v1) - v2;
- else if (svf->type == SVFTypeNotch) return v0 - (svf->k * v1);
- else if (svf->type == SVFTypePeak) return v0 - (svf->k * v1) - (2.0f * v2);
- else return 0.0f;
-
-}
-
// Less efficient, more accurate version of SVF, in which cutoff frequency is taken as floating point Hz value and tanh
// is calculated when frequency changes.
-void tSVF_init(tSVF* const svf, SVFType type, float freq, float Q)
+void tSVF_init(tSVF* const svff, SVFType type, float freq, float Q)
{
+ _tSVF* svf = *svff = (_tSVF*) leaf_alloc(sizeof(_tSVF));
+
svf->type = type;
svf->ic1eq = 0;
@@ -732,34 +838,58 @@
svf->a3 = a3;
}
-void tSVF_free(tSVF* const svf)
+void tSVF_free(tSVF* const svff)
{
+ _tSVF* svf = *svff;
+ leaf_free(svf);
}
-int tSVF_setFreq(tSVF* const svf, float freq)
+float tSVF_tick(tSVF* const svff, float v0)
{
+ _tSVF* svf = *svff;
+
+ float v1,v2,v3;
+ v3 = v0 - svf->ic2eq;
+ v1 = (svf->a1 * svf->ic1eq) + (svf->a2 * v3);
+ v2 = svf->ic2eq + (svf->a2 * svf->ic1eq) + (svf->a3 * v3);
+ svf->ic1eq = (2.0f * v1) - svf->ic1eq;
+ svf->ic2eq = (2.0f * v2) - svf->ic2eq;
+
+ if (svf->type == SVFTypeLowpass) return v2;
+ else if (svf->type == SVFTypeBandpass) return v1;
+ else if (svf->type == SVFTypeHighpass) return v0 - (svf->k * v1) - v2;
+ else if (svf->type == SVFTypeNotch) return v0 - (svf->k * v1);
+ else if (svf->type == SVFTypePeak) return v0 - (svf->k * v1) - (2.0f * v2);
+ else return 0.0f;
+
+}
+
+void tSVF_setFreq(tSVF* const svff, float freq)
+{
+ _tSVF* svf = *svff;
+
svf->g = tanf(PI * freq * leaf.invSampleRate);
svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
svf->a2 = svf->g * svf->a1;
svf->a3 = svf->g * svf->a2;
-
- return 0;
}
-int tSVF_setQ(tSVF* const svf, float Q)
+void tSVF_setQ(tSVF* const svff, float Q)
{
+ _tSVF* svf = *svff;
+
svf->k = 1.0f/Q;
svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
svf->a2 = svf->g * svf->a1;
svf->a3 = svf->g * svf->a2;
-
- return 0;
}
// Efficient version of tSVF where frequency is set based on 12-bit integer input for lookup in tanh wavetable.
-void tEfficientSVF_init(tEfficientSVF* const svf, SVFType type, uint16_t input, float Q)
+void tEfficientSVF_init(tEfficientSVF* const svff, SVFType type, uint16_t input, float Q)
{
+ _tEfficientSVF* svf = *svff = (_tEfficientSVF*) leaf_alloc(sizeof(_tEfficientSVF));
+
svf->type = type;
svf->ic1eq = 0;
@@ -779,13 +909,17 @@
svf->a3 = a3;
}
-void tEfficientSVF_free(tEfficientSVF* const svf)
+void tEfficientSVF_free(tEfficientSVF* const svff)
{
+ _tEfficientSVF* svf = *svff;
+ leaf_free(svf);
}
-float tEfficientSVF_tick(tEfficientSVF* const svf, float v0)
+float tEfficientSVF_tick(tEfficientSVF* const svff, float v0)
{
+ _tEfficientSVF* svf = *svff;
+
float v1,v2,v3;
v3 = v0 - svf->ic2eq;
v1 = (svf->a1 * svf->ic1eq) + (svf->a2 * v3);
@@ -802,27 +936,30 @@
}
-int tEfficientSVF_setFreq(tEfficientSVF* const svf, uint16_t input)
+void tEfficientSVF_setFreq(tEfficientSVF* const svff, uint16_t input)
{
+ _tEfficientSVF* svf = *svff;
+
svf->g = filtertan[input];
svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
svf->a2 = svf->g * svf->a1;
svf->a3 = svf->g * svf->a2;
-
- return 0;
}
-int tEfficientSVF_setQ(tEfficientSVF* const svf, float Q)
+void tEfficientSVF_setQ(tEfficientSVF* const svff, float Q)
{
+ _tEfficientSVF* svf = *svff;
+
svf->k = 1.0f/Q;
svf->a1 = 1.0f/(1.0f + svf->g * (svf->g + svf->k));
svf->a2 = svf->g * svf->a1;
svf->a3 = svf->g * svf->a2;
-
- return 0;
}
-void tFIR_init(tFIR* const fir, float* coeffs, int numTaps){
+void tFIR_init(tFIR* const firf, float* coeffs, int numTaps)
+{
+ _tFIR* fir = *firf = (_tFIR*) leaf_alloc(sizeof(_tFIR));
+
fir->numTaps = numTaps;
fir->coeff = coeffs;
fir->past = (float*)leaf_alloc(sizeof(float) * fir->numTaps);
@@ -829,7 +966,10 @@
for (int i = 0; i < fir->numTaps; ++i) fir->past[i] = 0.0f;
}
-float tFIR_tick(tFIR* const fir, float input){
+float tFIR_tick(tFIR* const firf, float input)
+{
+ _tFIR* fir = *firf;
+
fir->past[0] = input;
float y = 0.0f;
for (int i = 0; i < fir->numTaps; ++i) y += fir->past[i]*fir->coeff[i];
@@ -837,7 +977,10 @@
return y;
}
-void tFIR_free(tFIR* const fir)
+void tFIR_free(tFIR* const firf)
{
+ _tFIR* fir = *firf;
+
leaf_free(fir->past);
+ leaf_free(fir);
}
--- a/LEAF/Src/leaf-instruments.c
+++ b/LEAF/Src/leaf-instruments.c
@@ -18,7 +18,9 @@
// ----------------- COWBELL ----------------------------//
-void t808Cowbell_init(t808Cowbell* const cowbell, int useStick) {
+void t808Cowbell_init(t808Cowbell* const cowbellInst, int useStick)
+{
+ _t808Cowbell* cowbell = *cowbellInst = (_t808Cowbell*) leaf_alloc(sizeof(_t808Cowbell));
tSquare_init(&cowbell->p[0]);
tSquare_setFreq(&cowbell->p[0], 540.0f);
@@ -45,8 +47,10 @@
cowbell->useStick = useStick;
}
-void t808Cowebell_free(t808Cowbell* const cowbell)
+void t808Cowebell_free(t808Cowbell* const cowbellInst)
{
+ _t808Cowbell* cowbell = *cowbellInst;
+
tSquare_free(&cowbell->p[0]);
tSquare_free(&cowbell->p[1]);
tSVF_free(&cowbell->bandpassOsc);
@@ -56,10 +60,13 @@
tHighpass_free(&cowbell->highpass);
tNoise_free(&cowbell->stick);
tEnvelope_free(&cowbell->envStick);
+ leaf_free(cowbell);
}
-void t808Cowbell_on(t808Cowbell* const cowbell, float vel)
+void t808Cowbell_on(t808Cowbell* const cowbellInst, float vel)
{
+ _t808Cowbell* cowbell = *cowbellInst;
+
tEnvelope_on(&cowbell->envGain, vel);
if (cowbell->useStick)
@@ -66,7 +73,9 @@
tEnvelope_on(&cowbell->envStick,vel);
}
-float t808Cowbell_tick(t808Cowbell* const cowbell) {
+float t808Cowbell_tick(t808Cowbell* const cowbellInst)
+{
+ _t808Cowbell* cowbell = *cowbellInst;
float sample = 0.0f;
@@ -88,42 +97,49 @@
return sample;
}
-void t808Cowbell_setDecay(t808Cowbell* const cowbell, float decay)
+void t808Cowbell_setDecay(t808Cowbell* const cowbellInst, float decay)
{
+ _t808Cowbell* cowbell = *cowbellInst;
tEnvelope_setDecay(&cowbell->envGain,decay);
}
-void t808Cowbell_setHighpassFreq(t808Cowbell *cowbell, float freq)
+void t808Cowbell_setHighpassFreq(t808Cowbell *cowbellInst, float freq)
{
+ _t808Cowbell* cowbell = *cowbellInst;
tHighpass_setFreq(&cowbell->highpass,freq);
}
-void t808Cowbell_setBandpassFreq(t808Cowbell* const cowbell, float freq)
+void t808Cowbell_setBandpassFreq(t808Cowbell* const cowbellInst, float freq)
{
+ _t808Cowbell* cowbell = *cowbellInst;
cowbell->filterCutoff = freq;
}
-void t808Cowbell_setFreq(t808Cowbell* const cowbell, float freq)
+void t808Cowbell_setFreq(t808Cowbell* const cowbellInst, float freq)
{
-
+ _t808Cowbell* cowbell = *cowbellInst;
tSquare_setFreq(&cowbell->p[0],freq);
tSquare_setFreq(&cowbell->p[1],1.48148f*freq);
}
-void t808Cowbell_setOscMix(t808Cowbell* const cowbell, float oscMix)
+void t808Cowbell_setOscMix(t808Cowbell* const cowbellInst, float oscMix)
{
+ _t808Cowbell* cowbell = *cowbellInst;
cowbell->oscMix = oscMix;
}
-void t808Cowbell_setStick(t808Cowbell* const cowbell, int useStick)
+void t808Cowbell_setStick(t808Cowbell* const cowbellInst, int useStick)
{
+ _t808Cowbell* cowbell = *cowbellInst;
cowbell->useStick = useStick;
}
// ----------------- HIHAT ----------------------------//
-void t808Hihat_init(t808Hihat* const hihat)
+void t808Hihat_init(t808Hihat* const hihatInst)
{
+ _t808Hihat* hihat = *hihatInst = (_t808Hihat*) leaf_alloc(sizeof(_t808Hihat));
+
for (int i = 0; i < 6; i++)
{
tSquare_init(&hihat->p[i]);
@@ -153,8 +169,10 @@
tSquare_setFreq(&hihat->p[5], 8.21f * hihat->freq);
}
-void t808Hihat_free(t808Hihat* const hihat)
+void t808Hihat_free(t808Hihat* const hihatInst)
{
+ _t808Hihat* hihat = *hihatInst;
+
for (int i = 0; i < 6; i++)
{
tSquare_free(&hihat->p[i]);
@@ -170,26 +188,29 @@
tEnvelope_free(&hihat->envStick);
tHighpass_free(&hihat->highpass);
+
+ leaf_free(hihat);
}
-void t808Hihat_on(t808Hihat* const hihat, float vel) {
-
+void t808Hihat_on(t808Hihat* const hihatInst, float vel)
+{
+ _t808Hihat* hihat = *hihatInst;
tEnvelope_on(&hihat->envGain, vel);
tEnvelope_on(&hihat->envStick, vel);
-
}
-void t808Hihat_setOscNoiseMix(t808Hihat* const hihat, float oscNoiseMix) {
-
+void t808Hihat_setOscNoiseMix(t808Hihat* const hihatInst, float oscNoiseMix)
+{
+ _t808Hihat* hihat = *hihatInst;
hihat->oscNoiseMix = oscNoiseMix;
-
}
-float t808Hihat_tick(t808Hihat* const hihat) {
+float t808Hihat_tick(t808Hihat* const hihatInst)
+{
+ _t808Hihat* hihat = *hihatInst;
float sample = 0.0f;
float gainScale = 0.1666f;
-
float myNoise = tNoise_tick(&hihat->n);
@@ -220,57 +241,68 @@
return sample;
}
-void t808Hihat_setDecay(t808Hihat* const hihat, float decay)
+void t808Hihat_setDecay(t808Hihat* const hihatInst, float decay)
{
+ _t808Hihat* hihat = *hihatInst;
tEnvelope_setDecay(&hihat->envGain,decay);
}
-void t808Hihat_setHighpassFreq(t808Hihat* const hihat, float freq)
+void t808Hihat_setHighpassFreq(t808Hihat* const hihatInst, float freq)
{
+ _t808Hihat* hihat = *hihatInst;
tHighpass_setFreq(&hihat->highpass,freq);
}
-void t808Hihat_setStretch(t808Hihat* const hihat, float stretch)
+void t808Hihat_setStretch(t808Hihat* const hihatInst, float stretch)
{
+ _t808Hihat* hihat = *hihatInst;
hihat->stretch = stretch;
}
-void t808Hihat_setFM(t808Hihat* const hihat, float FM_amount)
+void t808Hihat_setFM(t808Hihat* const hihatInst, float FM_amount)
{
+ _t808Hihat* hihat = *hihatInst;
hihat->FM_amount = FM_amount;
}
-void t808Hihat_setOscBandpassFreq(t808Hihat* const hihat, float freq)
+void t808Hihat_setOscBandpassFreq(t808Hihat* const hihatInst, float freq)
{
+ _t808Hihat* hihat = *hihatInst;
tSVF_setFreq(&hihat->bandpassOsc,freq);
}
-void t808Hihat_setOscBandpassQ(t808Hihat* const hihat, float Q)
+void t808Hihat_setOscBandpassQ(t808Hihat* const hihatInst, float Q)
{
+ _t808Hihat* hihat = *hihatInst;
tSVF_setQ(&hihat->bandpassOsc,Q);
}
-void t808Hihat_setStickBandPassFreq(t808Hihat* const hihat, float freq)
+void t808Hihat_setStickBandPassFreq(t808Hihat* const hihatInst, float freq)
{
+ _t808Hihat* hihat = *hihatInst;
tSVF_setFreq(&hihat->bandpassStick,freq);
}
-void t808Hihat_setStickBandPassQ(t808Hihat* const hihat, float Q)
+void t808Hihat_setStickBandPassQ(t808Hihat* const hihatInst, float Q)
{
+ _t808Hihat* hihat = *hihatInst;
tSVF_setQ(&hihat->bandpassStick,Q);
}
-void t808Hihat_setOscFreq(t808Hihat* const hihat, float freq)
+void t808Hihat_setOscFreq(t808Hihat* const hihatInst, float freq)
{
- hihat->freq = freq;
+ _t808Hihat* hihat = *hihatInst;
+ hihat->freq = freq;
}
// ----------------- SNARE ----------------------------//
-void t808Snare_init(t808Snare* const snare)
+void t808Snare_init(t808Snare* const snareInst)
{
+ _t808Snare* snare = *snareInst = (_t808Snare*) leaf_alloc(sizeof(_t808Snare));
+
float ratio[2] = {1.0, 1.5};
for (int i = 0; i < 2; i++)
{
@@ -295,8 +327,10 @@
snare->noiseGain = 1.0f;
}
-void t808Snare_free (t808Snare* const snare)
+void t808Snare_free (t808Snare* const snareInst)
{
+ _t808Snare* snare = *snareInst;
+
for (int i = 0; i < 2; i++)
{
tTriangle_free(&snare->tone[i]);
@@ -306,15 +340,18 @@
tEnvelope_free(&snare->toneEnvFilter[i]);
}
-
tNoise_free(&snare->noiseOsc);
tSVF_free(&snare->noiseLowpass);
tEnvelope_free(&snare->noiseEnvGain);
tEnvelope_free(&snare->noiseEnvFilter);
+
+ leaf_free(snare);
}
-void t808Snare_on(t808Snare* const snare, float vel)
+void t808Snare_on(t808Snare* const snareInst, float vel)
{
+ _t808Snare* snare = *snareInst;
+
for (int i = 0; i < 2; i++)
{
tEnvelope_on(&snare->toneEnvOsc[i], vel);
@@ -326,53 +363,62 @@
tEnvelope_on(&snare->noiseEnvFilter, vel);
}
-void t808Snare_setTone1Freq(t808Snare* const snare, float freq)
+void t808Snare_setTone1Freq(t808Snare* const snareInst, float freq)
{
+ _t808Snare* snare = *snareInst;
snare->tone1Freq = freq;
tTriangle_setFreq(&snare->tone[0], freq);
-
}
-void t808Snare_setTone2Freq(t808Snare* const snare, float freq)
+void t808Snare_setTone2Freq(t808Snare* const snareInst, float freq)
{
+ _t808Snare* snare = *snareInst;
snare->tone2Freq = freq;
tTriangle_setFreq(&snare->tone[1],freq);
}
-void t808Snare_setTone1Decay(t808Snare* const snare, float decay)
+void t808Snare_setTone1Decay(t808Snare* const snareInst, float decay)
{
+ _t808Snare* snare = *snareInst;
tEnvelope_setDecay(&snare->toneEnvGain[0],decay);
}
-void t808Snare_setTone2Decay(t808Snare* const snare, float decay)
+void t808Snare_setTone2Decay(t808Snare* const snareInst, float decay)
{
+ _t808Snare* snare = *snareInst;
tEnvelope_setDecay(&snare->toneEnvGain[1],decay);
}
-void t808Snare_setNoiseDecay(t808Snare* const snare, float decay)
+void t808Snare_setNoiseDecay(t808Snare* const snareInst, float decay)
{
+ _t808Snare* snare = *snareInst;
tEnvelope_setDecay(&snare->noiseEnvGain,decay);
}
-void t808Snare_setToneNoiseMix(t808Snare* const snare, float toneNoiseMix)
+void t808Snare_setToneNoiseMix(t808Snare* const snareInst, float toneNoiseMix)
{
+ _t808Snare* snare = *snareInst;
snare->toneNoiseMix = toneNoiseMix;
}
-void t808Snare_setNoiseFilterFreq(t808Snare* const snare, float noiseFilterFreq)
+void t808Snare_setNoiseFilterFreq(t808Snare* const snareInst, float noiseFilterFreq)
{
+ _t808Snare* snare = *snareInst;
snare->noiseFilterFreq = noiseFilterFreq;
}
-void t808Snare_setNoiseFilterQ(t808Snare* const snare, float noiseFilterQ)
+void t808Snare_setNoiseFilterQ(t808Snare* const snareInst, float noiseFilterQ)
{
+ _t808Snare* snare = *snareInst;
tSVF_setQ(&snare->noiseLowpass, noiseFilterQ);
}
static float tone[2];
-float t808Snare_tick(t808Snare* const snare)
+float t808Snare_tick(t808Snare* const snareInst)
{
+ _t808Snare* snare = *snareInst;
+
for (int i = 0; i < 2; i++)
{
tTriangle_setFreq(&snare->tone[i], snare->tone1Freq + (20.0f * tEnvelope_tick(&snare->toneEnvOsc[i])));
@@ -393,8 +439,10 @@
// ----------------- KICK ----------------------------//
-void t808Kick_init (t808Kick* const kick)
+void t808Kick_init (t808Kick* const kickInst)
{
+ _t808Kick* kick = *kickInst = (_t808Kick*) leaf_alloc(sizeof(_t808Kick));
+
tCycle_init(&kick->tone);
kick->toneInitialFreq = 40.0f;
kick->sighAmountInHz = 7.0f;
@@ -409,8 +457,10 @@
kick->noiseGain = 0.3f;
}
-void t808Kick_free (t808Kick* const kick)
+void t808Kick_free (t808Kick* const kickInst)
{
+ _t808Kick* kick = *kickInst;
+
tCycle_free(&kick->tone);
tSVF_free(&kick->toneLowpass);
tEnvelope_free(&kick->toneEnvOscChirp);
@@ -418,10 +468,14 @@
tEnvelope_free(&kick->toneEnvGain);
tNoise_free(&kick->noiseOsc);
tEnvelope_free(&kick->noiseEnvGain);
+
+ leaf_free(kick);
}
-float t808Kick_tick (t808Kick* const kick)
+float t808Kick_tick (t808Kick* const kickInst)
{
+ _t808Kick* kick = *kickInst;
+
tCycle_setFreq(&kick->tone, (kick->toneInitialFreq * (1.0f + (kick->chirpRatioMinusOne * tEnvelope_tick(&kick->toneEnvOscChirp)))) + (kick->sighAmountInHz * tEnvelope_tick(&kick->toneEnvOscSigh)));
float sample = tCycle_tick(&kick->tone) * tEnvelope_tick(&kick->toneEnvGain);
sample+= tNoise_tick(&kick->noiseOsc) * tEnvelope_tick(&kick->noiseEnvGain);
@@ -430,8 +484,9 @@
return sample;
}
-void t808Kick_on (t808Kick* const kick, float vel)
+void t808Kick_on (t808Kick* const kickInst, float vel)
{
+ _t808Kick* kick = *kickInst;
tEnvelope_on(&kick->toneEnvOscChirp, vel);
tEnvelope_on(&kick->toneEnvOscSigh, vel);
tEnvelope_on(&kick->toneEnvGain, vel);
@@ -438,23 +493,25 @@
tEnvelope_on(&kick->noiseEnvGain, vel);
}
-void t808Kick_setToneFreq (t808Kick* const kick, float freq)
+void t808Kick_setToneFreq (t808Kick* const kickInst, float freq)
{
+ _t808Kick* kick = *kickInst;
kick->toneInitialFreq = freq;
}
-void t808Kick_setToneDecay (t808Kick* const kick, float decay)
+void t808Kick_setToneDecay (t808Kick* const kickInst, float decay)
{
+ _t808Kick* kick = *kickInst;
tEnvelope_setDecay(&kick->toneEnvGain,decay);
tEnvelope_setDecay(&kick->toneEnvGain,decay * 3.0f);
}
-void t808Kick_setNoiseDecay (t808Kick* const kick, float decay);
-void t808Kick_setSighAmount (t808Kick* const kick, float sigh);
-void t808Kick_setChirpAmount (t808Kick* const kick, float chirp);
-void t808Kick_setToneNoiseMix (t808Kick* const kick, float toneNoiseMix);
-void t808Kick_setNoiseFilterFreq (t808Kick* const kick, float noiseFilterFreq);
-void t808Kick_setNoiseFilterQ (t808Kick* const kick, float noiseFilterQ);
+void t808Kick_setNoiseDecay (t808Kick* const kickInst, float decay);
+void t808Kick_setSighAmount (t808Kick* const kickInst, float sigh);
+void t808Kick_setChirpAmount (t808Kick* const kickInst, float chirp);
+void t808Kick_setToneNoiseMix (t808Kick* const kickInst, float toneNoiseMix);
+void t808Kick_setNoiseFilterFreq (t808Kick* const kickInst, float noiseFilterFreq);
+void t808Kick_setNoiseFilterQ (t808Kick* const kickInst, float noiseFilterQ);
--- a/LEAF/Src/leaf-mempool.c
+++ b/LEAF/Src/leaf-mempool.c
@@ -169,7 +169,7 @@
freed_node->size += header_size + other_node->size;
// If we are merging with the head, move the head forward
if (other_node == pool->head) pool->head = pool->head->next;
- // Delink the merged node (Shouldn't really be necessary since we're formatting)
+ // Delink the merged node
delink_node(other_node);
}
--- a/LEAF/Src/leaf-midi.c
+++ b/LEAF/Src/leaf-midi.c
@@ -17,8 +17,10 @@
#endif
// POLY
-void tPoly_init(tPoly* const poly, int maxNumVoices)
+void tPoly_init(tPoly* const polyh, int maxNumVoices)
{
+ _tPoly* poly = *polyh = (_tPoly*) leaf_alloc(sizeof(_tPoly));
+
poly->numVoices = maxNumVoices;
poly->maxNumVoices = maxNumVoices;
poly->lastVoiceToChange = 0;
@@ -60,8 +62,10 @@
poly->pitchGlideIsActive = OFALSE;
}
-void tPoly_free(tPoly* const poly)
+void tPoly_free(tPoly* const polyh)
{
+ _tPoly* poly = *polyh;
+
for (int i = 0; i < poly->maxNumVoices; i++)
{
tRamp_free(&poly->ramps[i]);
@@ -75,16 +79,19 @@
leaf_free(poly->ramps);
leaf_free(poly->rampVals);
leaf_free(poly->firstReceived);
+
+ leaf_free(poly);
}
-void tPoly_tickPitch(tPoly* poly)
+void tPoly_tickPitch(tPoly* polyh)
{
- tPoly_tickPitchGlide(poly);
- tPoly_tickPitchBend(poly);
+ tPoly_tickPitchGlide(polyh);
+ tPoly_tickPitchBend(polyh);
}
-void tPoly_tickPitchGlide(tPoly* poly)
+void tPoly_tickPitchGlide(tPoly* polyh)
{
+ _tPoly* poly = *polyh;
for (int i = 0; i < poly->maxNumVoices; ++i)
{
tRamp_tick(&poly->ramps[i]);
@@ -91,25 +98,29 @@
}
}
-void tPoly_tickPitchBend(tPoly* poly)
+void tPoly_tickPitchBend(tPoly* polyh)
{
+ _tPoly* poly = *polyh;
tRamp_tick(&poly->pitchBendRamp);
}
//instead of including in dacsend, should have a separate pitch bend ramp, that is added when the ramps are ticked and sent to DAC
-void tPoly_setPitchBend(tPoly* const poly, float pitchBend)
+void tPoly_setPitchBend(tPoly* const polyh, float pitchBend)
{
+ _tPoly* poly = *polyh;
poly->pitchBend = pitchBend;
tRamp_setDest(&poly->pitchBendRamp, poly->pitchBend);
}
-int tPoly_noteOn(tPoly* const poly, int note, uint8_t vel)
+int tPoly_noteOn(tPoly* const polyh, int note, uint8_t vel)
{
+ _tPoly* poly = *polyh;
+
// if not in keymap or already on stack, dont do anything. else, add that note.
if (tStack_contains(&poly->stack, note) >= 0) return -1;
else
{
- tPoly_orderedAddToStack(poly, note);
+ tPoly_orderedAddToStack(polyh, note);
tStack_add(&poly->stack, note);
int alteredVoice = -1;
@@ -172,8 +183,10 @@
int16_t noteToTest = -1;
-int tPoly_noteOff(tPoly* const poly, uint8_t note)
+int tPoly_noteOff(tPoly* const polyh, uint8_t note)
{
+ _tPoly* poly = *polyh;
+
tStack_remove(&poly->stack, note);
tStack_remove(&poly->orderStack, note);
poly->notes[note][0] = 0;
@@ -222,8 +235,9 @@
return deactivatedVoice;
}
-void tPoly_orderedAddToStack(tPoly* const poly, uint8_t noteVal)
+void tPoly_orderedAddToStack(tPoly* const polyh, uint8_t noteVal)
{
+ _tPoly* poly = *polyh;
uint8_t j;
int myPitch, thisPitch, nextPitch;
@@ -232,11 +246,11 @@
int whereToInsert = 0;
- for (j = 0; j < ns.size; j++)
+ for (j = 0; j < ns->size; j++)
{
myPitch = noteVal;
- thisPitch = ns.data[j];
- nextPitch = ns.data[j+1];
+ thisPitch = ns->data[j];
+ nextPitch = ns->data[j+1];
if (myPitch > thisPitch)
{
@@ -249,30 +263,33 @@
}
//first move notes that are already in the stack one position to the right
- for (j = ns.size; j > whereToInsert; j--)
+ for (j = ns->size; j > whereToInsert; j--)
{
- ns.data[j] = ns.data[(j - 1)];
+ ns->data[j] = ns->data[(j - 1)];
}
//then, insert the new note into the front of the stack
- ns.data[whereToInsert] = noteVal;
+ ns->data[whereToInsert] = noteVal;
- ns.size++;
+ ns->size++;
}
-void tPoly_setNumVoices(tPoly* const poly, uint8_t numVoices)
+void tPoly_setNumVoices(tPoly* const polyh, uint8_t numVoices)
{
+ _tPoly* poly = *polyh;
poly->numVoices = (numVoices > poly->maxNumVoices) ? poly->maxNumVoices : numVoices;
}
-void tPoly_setPitchGlideActive(tPoly* const poly, oBool isActive)
+void tPoly_setPitchGlideActive(tPoly* const polyh, oBool isActive)
{
+ _tPoly* poly = *polyh;
poly->pitchGlideIsActive = isActive;
}
-void tPoly_setPitchGlideTime(tPoly* const poly, float t)
+void tPoly_setPitchGlideTime(tPoly* const polyh, float t)
{
+ _tPoly* poly = *polyh;
poly->glideTime = t;
for (int i = 0; i < poly->maxNumVoices; ++i)
{
@@ -280,28 +297,33 @@
}
}
-int tPoly_getNumVoices(tPoly* const poly)
+int tPoly_getNumVoices(tPoly* const polyh)
{
+ _tPoly* poly = *polyh;
return poly->numVoices;
}
-float tPoly_getPitch(tPoly* const poly, uint8_t voice)
+float tPoly_getPitch(tPoly* const polyh, uint8_t voice)
{
+ _tPoly* poly = *polyh;
return tRamp_sample(&poly->ramps[voice]) + tRamp_sample(&poly->pitchBendRamp);
}
-int tPoly_getKey(tPoly* const poly, uint8_t voice)
+int tPoly_getKey(tPoly* const polyh, uint8_t voice)
{
+ _tPoly* poly = *polyh;
return poly->voices[voice][0];
}
-int tPoly_getVelocity(tPoly* const poly, uint8_t voice)
+int tPoly_getVelocity(tPoly* const polyh, uint8_t voice)
{
+ _tPoly* poly = *polyh;
return poly->voices[voice][1];
}
-int tPoly_isOn(tPoly* const poly, uint8_t voice)
+int tPoly_isOn(tPoly* const polyh, uint8_t voice)
{
+ _tPoly* poly = *polyh;
return (poly->voices[voice][0] > 0) ? 1 : 0;
}
@@ -310,8 +332,10 @@
/* Stack */
//====================================================================================
-void tStack_init(tStack* const ns)
+void tStack_init(tStack* const stack)
{
+ _tStack* ns = *stack = (_tStack*) leaf_alloc(sizeof(_tStack));
+
ns->ordered = OFALSE;
ns->size = 0;
ns->pos = 0;
@@ -320,14 +344,17 @@
for (int i = 0; i < STACK_SIZE; i++) ns->data[i] = -1;
}
-void tStack_free(tStack* const ns)
+void tStack_free(tStack* const stack)
{
+ _tStack* ns = *stack;
+ leaf_free(ns);
}
// If stack contains note, returns index. Else returns -1;
-int tStack_contains(tStack* const ns, uint16_t noteVal)
+int tStack_contains(tStack* const stack, uint16_t noteVal)
{
+ _tStack* ns = *stack;
for (int i = 0; i < ns->size; i++)
{
if (ns->data[i] == noteVal) return i;
@@ -335,8 +362,10 @@
return -1;
}
-void tStack_add(tStack* const ns, uint16_t noteVal)
+void tStack_add(tStack* const stack, uint16_t noteVal)
{
+ _tStack* ns = *stack;
+
uint8_t j;
int whereToInsert = 0;
@@ -367,13 +396,15 @@
ns->size++;
}
-int tStack_addIfNotAlreadyThere(tStack* const ns, uint16_t noteVal)
+int tStack_addIfNotAlreadyThere(tStack* const stack, uint16_t noteVal)
{
+ _tStack* ns = *stack;
+
uint8_t j;
int added = 0;
- if (tStack_contains(ns, noteVal) == -1)
+ if (tStack_contains(stack, noteVal) == -1)
{
int whereToInsert = 0;
if (ns->ordered)
@@ -410,10 +441,12 @@
// Remove noteVal. return 1 if removed, 0 if not
-int tStack_remove(tStack* const ns, uint16_t noteVal)
+int tStack_remove(tStack* const stack, uint16_t noteVal)
{
+ _tStack* ns = *stack;
+
uint8_t k;
- int foundIndex = tStack_contains(ns, noteVal);
+ int foundIndex = tStack_contains(stack, noteVal);
int removed = 0;
if (foundIndex >= 0)
@@ -440,14 +473,14 @@
removed = 1;
}
-
-
return removed;
}
// Doesn't change size of data types
-void tStack_setCapacity(tStack* const ns, uint16_t cap)
+void tStack_setCapacity(tStack* const stack, uint16_t cap)
{
+ _tStack* ns = *stack;
+
if (cap <= 0)
ns->capacity = 1;
else if (cap <= STACK_SIZE)
@@ -470,13 +503,17 @@
}
}
-int tStack_getSize(tStack* const ns)
+int tStack_getSize(tStack* const stack)
{
+ _tStack* ns = *stack;
+
return ns->size;
}
-void tStack_clear(tStack* const ns)
+void tStack_clear(tStack* const stack)
{
+ _tStack* ns = *stack;
+
for (int i = 0; i < STACK_SIZE; i++)
{
ns->data[i] = -1;
@@ -486,8 +523,10 @@
}
// Next item in order of addition to stack. Return 0-31 if there is a next item to move to. Returns -1 otherwise.
-int tStack_next(tStack* const ns)
+int tStack_next(tStack* const stack)
{
+ _tStack* ns = *stack;
+
int step = 0;
if (ns->size != 0) // if there is at least one note in the stack
{
@@ -509,12 +548,14 @@
}
}
-int tStack_get(tStack* const ns, int which)
+int tStack_get(tStack* const stack, int which)
{
+ _tStack* ns = *stack;
return ns->data[which];
}
-int tStack_first(tStack* const ns)
+int tStack_first(tStack* const stack)
{
+ _tStack* ns = *stack;
return ns->data[0];
}
--- a/LEAF/Src/leaf-oscillators.c
+++ b/LEAF/Src/leaf-oscillators.c
@@ -21,29 +21,34 @@
#endif
// Cycle
-void tCycle_init(tCycle* const c)
+void tCycle_init(tCycle* const cy)
{
+ _tCycle* c = *cy = (_tCycle*) leaf_alloc(sizeof(_tCycle));
+
c->inc = 0.0f;
c->phase = 0.0f;
}
-void tCycle_free(tCycle* const c)
+void tCycle_free(tCycle* const cy)
{
-
+ _tCycle* c = *cy;
+ leaf_free(c);
}
-int tCycle_setFreq(tCycle* const c, float freq)
+void tCycle_setFreq(tCycle* const cy, float freq)
{
+ _tCycle* c = *cy;
+
if (freq < 0.0f) freq = 0.0f;
c->freq = freq;
c->inc = freq * leaf.invSampleRate;
-
- return 0;
}
-float tCycle_tick(tCycle* const c)
+float tCycle_tick(tCycle* const cy)
{
+ _tCycle* c = *cy;
+
// Phasor increment
c->phase += c->inc;
while (c->phase >= 1.0f) c->phase -= 1.0f;
@@ -58,31 +63,39 @@
return (samp0 + (samp1 - samp0) * fracPart);
}
-void tCycleSampleRateChanged (tCycle* const c)
+void tCycleSampleRateChanged (tCycle* const cy)
{
+ _tCycle* c = *cy;
+
c->inc = c->freq * leaf.invSampleRate;
}
//========================================================================
/* Triangle */
-void tTriangle_start(tTriangle* const c)
+void tTriangle_start(tTriangle* const cy)
{
}
-void tTriangle_init(tTriangle* const c)
+void tTriangle_init(tTriangle* const cy)
{
+ _tTriangle* c = *cy = (_tTriangle*) leaf_alloc(sizeof(_tTriangle));
+
c->inc = 0.0f;
c->phase = 0.0f;
}
-void tTriangle_free(tTriangle* const c)
+void tTriangle_free(tTriangle* const cy)
{
+ _tTriangle* c = *cy;
+ leaf_free(c);
}
-int tTriangle_setFreq(tTriangle* const c, float freq)
+int tTriangle_setFreq(tTriangle* const cy, float freq)
{
+ _tTriangle* c = *cy;
+
if (freq < 0.0f) freq = 0.0f;
c->freq = freq;
@@ -92,8 +105,10 @@
}
-float tTriangle_tick(tTriangle* const c)
+float tTriangle_tick(tTriangle* const cy)
{
+ _tTriangle* c = *cy;
+
// Phasor increment
c->phase += c->inc;
while (c->phase >= 1.0f) c->phase -= 1.0f;
@@ -167,26 +182,34 @@
return out;
}
-void tTriangleSampleRateChanged (tTriangle* const c)
+void tTriangleSampleRateChanged (tTriangle* const cy)
{
+ _tTriangle* c = *cy;
+
c->inc = c->freq * leaf.invSampleRate;
}
//========================================================================
/* Square */
-void tSquare_init(tSquare* const c)
+void tSquare_init(tSquare* const cy)
{
+ _tSquare* c = *cy = (_tSquare*) leaf_alloc(sizeof(_tSquare));
+
c->inc = 0.0f;
c->phase = 0.0f;
}
-void tSquare_free(tSquare* const c)
+void tSquare_free(tSquare* const cy)
{
+ _tSquare* c = *cy;
+ leaf_free(c);
}
-int tSquare_setFreq(tSquare* const c, float freq)
+int tSquare_setFreq(tSquare* const cy, float freq)
{
+ _tSquare* c = *cy;
+
if (freq < 0.0f) freq = 0.0f;
c->freq = freq;
@@ -195,8 +218,10 @@
return 0;
}
-float tSquare_tick(tSquare* const c)
+float tSquare_tick(tSquare* const cy)
{
+ _tSquare* c = *cy;
+
// Phasor increment
c->phase += c->inc;
while (c->phase >= 1.0f) c->phase -= 1.0f;
@@ -269,26 +294,34 @@
return out;
}
-void tSquareSampleRateChanged (tSquare* const c)
+void tSquareSampleRateChanged (tSquare* const cy)
{
+ _tSquare* c = *cy;
+
c->inc = c->freq * leaf.invSampleRate;
}
//=====================================================================
// Sawtooth
-void tSawtooth_init(tSawtooth* const c)
+void tSawtooth_init(tSawtooth* const cy)
{
+ _tSawtooth* c = *cy = (_tSawtooth*) leaf_alloc(sizeof(_tSawtooth));
+
c->inc = 0.0f;
c->phase = 0.0f;
}
-void tSawtooth_free(tSawtooth* const c)
+void tSawtooth_free(tSawtooth* const cy)
{
-
+ _tSawtooth* c = *cy;
+
+ leaf_free(c);
}
-int tSawtooth_setFreq(tSawtooth* const c, float freq)
+int tSawtooth_setFreq(tSawtooth* const cy, float freq)
{
+ _tSawtooth* c = *cy;
+
if (freq < 0.0f) freq = 0.0f;
c->freq = freq;
@@ -297,8 +330,10 @@
return 0;
}
-float tSawtooth_tick(tSawtooth* const c)
+float tSawtooth_tick(tSawtooth* const cy)
{
+ _tSawtooth* c = *cy;
+
// Phasor increment
c->phase += c->inc;
while (c->phase >= 1.0f) c->phase -= 1.0f;
@@ -372,31 +407,41 @@
return out;
}
-void tSawtoothSampleRateChanged (tSawtooth* const c)
+void tSawtoothSampleRateChanged (tSawtooth* const cy)
{
+ _tSawtooth* c = *cy;
+
c->inc = c->freq * leaf.invSampleRate;
}
//========================================================================
/* Phasor */
-void tPhasorSampleRateChanged (tPhasor* const p)
+void tPhasorSampleRateChanged (tPhasor* const ph)
{
+ _tPhasor* p = *ph;
+
p->inc = p->freq * leaf.invSampleRate;
-};
+}
-void tPhasor_init(tPhasor* const p)
+void tPhasor_init(tPhasor* const ph)
{
+ _tPhasor* p = *ph = (_tPhasor*) leaf_alloc(sizeof(_tPhasor));
+
p->phase = 0.0f;
p->inc = 0.0f;
}
-void tPhasor_free(tPhasor* const p)
+void tPhasor_free(tPhasor* const ph)
{
+ _tPhasor* p = *ph;
+ leaf_free(p);
}
-int tPhasor_setFreq(tPhasor* const p, float freq)
+int tPhasor_setFreq(tPhasor* const ph, float freq)
{
+ _tPhasor* p = *ph;
+
if (freq < 0.0f) freq = 0.0f;
p->freq = freq;
@@ -405,8 +450,10 @@
return 0;
}
-float tPhasor_tick(tPhasor* const p)
+float tPhasor_tick(tPhasor* const ph)
{
+ _tPhasor* p = *ph;
+
p->phase += p->inc;
if (p->phase >= 1.0f) p->phase -= 1.0f;
@@ -415,19 +462,25 @@
}
/* Noise */
-void tNoise_init(tNoise* const n, NoiseType type)
+void tNoise_init(tNoise* const ns, NoiseType type)
{
+ _tNoise* n = *ns = (_tNoise*) leaf_alloc(sizeof(_tNoise));
+
n->type = type;
n->rand = leaf.random;
}
-void tNoise_free(tNoise* const n)
+void tNoise_free(tNoise* const ns)
{
+ _tNoise* n = *ns;
+ leaf_free(n);
}
-float tNoise_tick(tNoise* const n)
+float tNoise_tick(tNoise* const ns)
{
+ _tNoise* n = *ns;
+
float rand = (n->rand() * 2.0f) - 1.0f;
if (n->type == PinkNoise)
@@ -448,13 +501,15 @@
//=================================================================================
/* Neuron */
-void tNeuronSampleRateChanged(tNeuron* n)
+void tNeuronSampleRateChanged(tNeuron* nr)
{
}
-void tNeuron_init(tNeuron* const n)
+void tNeuron_init(tNeuron* const nr)
{
+ _tNeuron* n = *nr = (_tNeuron*) leaf_alloc(sizeof(_tNeuron));
+
tPoleZero_init(&n->f);
tPoleZero_setBlockZero(&n->f, 0.99f);
@@ -482,13 +537,17 @@
n->rate[2] = n->gL/n->C;
}
-void tNeuron_free(tNeuron* const n)
+void tNeuron_free(tNeuron* const nr)
{
+ _tNeuron* n = *nr;
+
tPoleZero_free(&n->f);
+ leaf_free(n);
}
-void tNeuron_reset(tNeuron* const n)
+void tNeuron_reset(tNeuron* const nr)
{
+ _tNeuron* n = *nr;
tPoleZero_setBlockZero(&n->f, 0.99f);
@@ -516,51 +575,61 @@
}
-void tNeuron_setV1(tNeuron* const n, float V1)
+void tNeuron_setV1(tNeuron* const nr, float V1)
{
+ _tNeuron* n = *nr;
n->V[0] = V1;
}
-void tNeuron_setV2(tNeuron* const n, float V2)
+void tNeuron_setV2(tNeuron* const nr, float V2)
{
+ _tNeuron* n = *nr;
n->V[1] = V2;
}
-void tNeuron_setV3(tNeuron* const n, float V3)
+void tNeuron_setV3(tNeuron* const nr, float V3)
{
+ _tNeuron* n = *nr;
n->V[2] = V3;
}
-void tNeuron_setTimeStep(tNeuron* const n, float timeStep)
+void tNeuron_setTimeStep(tNeuron* const nr, float timeStep)
{
+ _tNeuron* n = *nr;
n->timeStep = timeStep;
}
-void tNeuron_setK(tNeuron* const n, float K)
+void tNeuron_setK(tNeuron* const nr, float K)
{
+ _tNeuron* n = *nr;
n->gK = K;
}
-void tNeuron_setL(tNeuron* const n, float L)
+void tNeuron_setL(tNeuron* const nr, float L)
{
+ _tNeuron* n = *nr;
n->gL = L;
n->rate[2] = n->gL/n->C;
}
-void tNeuron_setN(tNeuron* const n, float N)
+void tNeuron_setN(tNeuron* const nr, float N)
{
+ _tNeuron* n = *nr;
n->gN = N;
}
-void tNeuron_setC(tNeuron* const n, float C)
+void tNeuron_setC(tNeuron* const nr, float C)
{
+ _tNeuron* n = *nr;
n->C = C;
n->rate[2] = n->gL/n->C;
}
-float tNeuron_tick(tNeuron* const n)
+float tNeuron_tick(tNeuron* const nr)
{
+ _tNeuron* n = *nr;
+
float output = 0.0f;
float voltage = n->voltage;
@@ -633,12 +702,14 @@
}
-void tNeuron_setMode (tNeuron* const n, NeuronMode mode)
+void tNeuron_setMode (tNeuron* const nr, NeuronMode mode)
{
+ _tNeuron* n = *nr;
n->mode = mode;
}
-void tNeuron_setCurrent (tNeuron* const n, float current)
+void tNeuron_setCurrent (tNeuron* const nr, float current)
{
+ _tNeuron* n = *nr;
n->current = current;
}
--- a/LEAF/Src/leaf-physical.c
+++ b/LEAF/Src/leaf-physical.c
@@ -17,8 +17,10 @@
#endif
/* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ tPluck ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ */
-void tPluck_init (tPluck* const p, float lowestFrequency)
+void tPluck_init (tPluck* const pl, float lowestFrequency)
{
+ _tPluck* p = *pl = (_tPluck*) leaf_alloc(sizeof(_tPluck));
+
if ( lowestFrequency <= 0.0f ) lowestFrequency = 10.0f;
tNoise_init(&p->noise, WhiteNoise);
@@ -29,29 +31,37 @@
tAllpassDelay_init(&p->delayLine, 0.0f, leaf.sampleRate * 2);
- tPluck_setFrequency(p, 220.0f);
+ tPluck_setFrequency(pl, 220.0f);
}
-void tPluck_free (tPluck* const p)
+void tPluck_free (tPluck* const pl)
{
+ _tPluck* p = *pl;
+
tNoise_free(&p->noise);
tOnePole_free(&p->pickFilter);
tOneZero_free(&p->loopFilter);
tAllpassDelay_free(&p->delayLine);
+
+ leaf_free(p);
}
-float tPluck_getLastOut (tPluck *p)
+float tPluck_getLastOut (tPluck* const pl)
{
+ _tPluck* p = *pl;
return p->lastOut;
}
-float tPluck_tick (tPluck *p)
+float tPluck_tick (tPluck* const pl)
{
+ _tPluck* p = *pl;
return (p->lastOut = 3.0f * tAllpassDelay_tick(&p->delayLine, tOneZero_tick(&p->loopFilter, tAllpassDelay_getLastOut(&p->delayLine) * p->loopGain ) ));
}
-void tPluck_pluck (tPluck* const p, float amplitude)
+void tPluck_pluck (tPluck* const pl, float amplitude)
{
+ _tPluck* p = *pl;
+
if ( amplitude < 0.0f) amplitude = 0.0f;
else if (amplitude > 1.0f) amplitude = 1.0f;
@@ -64,16 +74,19 @@
}
// Start a note with the given frequency and amplitude.;
-void tPluck_noteOn (tPluck* const p, float frequency, float amplitude )
+void tPluck_noteOn (tPluck* const pl, float frequency, float amplitude )
{
+ _tPluck* p = *pl;
p->lastFreq = frequency;
- tPluck_setFrequency( p, frequency );
- tPluck_pluck( p, amplitude );
+ tPluck_setFrequency( pl, frequency );
+ tPluck_pluck( pl, amplitude );
}
// Stop a note with the given amplitude (speed of decay).
-void tPluck_noteOff (tPluck* const p, float amplitude )
+void tPluck_noteOff (tPluck* const pl, float amplitude )
{
+ _tPluck* p = *pl;
+
if ( amplitude < 0.0f) amplitude = 0.0f;
else if (amplitude > 1.0f) amplitude = 1.0f;
@@ -81,8 +94,10 @@
}
// Set instrument parameters for a particular frequency.
-void tPluck_setFrequency (tPluck* const p, float frequency )
+void tPluck_setFrequency (tPluck* const pl, float frequency )
{
+ _tPluck* p = *pl;
+
if ( frequency <= 0.0f ) frequency = 0.001f;
// Delay = length - filter delay.
@@ -97,19 +112,22 @@
}
// Perform the control change specified by \e number and \e value (0.0 - 128.0).
-void tPluck_controlChange (tPluck* const p, int number, float value)
+void tPluck_controlChange (tPluck* const pl, int number, float value)
{
return;
}
-void tPluckSampleRateChanged(tPluck* const p)
+void tPluckSampleRateChanged(tPluck* const pl)
{
- //tPluckSetFrequency(p, p->lastFreq);
+ _tPluck* p = *pl;
+ tPluck_setFrequency(pl, p->lastFreq);
}
/* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ tKarplusStrong ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ */
-void tKarplusStrong_init (tKarplusStrong* const p, float lowestFrequency)
+void tKarplusStrong_init (tKarplusStrong* const pl, float lowestFrequency)
{
+ _tKarplusStrong* p = *pl = (_tKarplusStrong*) leaf_alloc(sizeof(_tKarplusStrong));
+
if ( lowestFrequency <= 0.0f ) lowestFrequency = 8.0f;
tAllpassDelay_init(&p->delayLine, 0.0f, leaf.sampleRate * 2);
@@ -132,12 +150,14 @@
p->baseLoopGain = 0.995f;
p->loopGain = 0.999f;
- tKarplusStrong_setFrequency( p, 220.0f );
+ tKarplusStrong_setFrequency( pl, 220.0f );
}
-void tKarplusStrong_free (tKarplusStrong* const p)
+void tKarplusStrong_free (tKarplusStrong* const pl)
{
+ _tKarplusStrong* p = *pl;
+
tAllpassDelay_free(&p->delayLine);
tLinearDelay_free(&p->combDelay);
tOneZero_free(&p->filter);
@@ -147,15 +167,20 @@
{
tBiQuad_free(&p->biquad[i]);
}
+
+ leaf_free(p);
}
-float tKarplusStrong_getLastOut (tKarplusStrong* const p)
+float tKarplusStrong_getLastOut (tKarplusStrong* const pl)
{
+ _tKarplusStrong* p = *pl;
return p->lastOut;
}
-float tKarplusStrong_tick (tKarplusStrong* const p)
+float tKarplusStrong_tick (tKarplusStrong* const pl)
{
+ _tKarplusStrong* p = *pl;
+
float temp = tAllpassDelay_getLastOut(&p->delayLine) * p->loopGain;
// Calculate allpass stretching.
@@ -171,8 +196,10 @@
return p->lastOut;
}
-void tKarplusStrong_pluck (tKarplusStrong* const p, float amplitude)
+void tKarplusStrong_pluck (tKarplusStrong* const pl, float amplitude)
{
+ _tKarplusStrong* p = *pl;
+
if ( amplitude < 0.0f) amplitude = 0.0f;
else if (amplitude > 1.0f) amplitude = 1.0f;
@@ -187,15 +214,17 @@
}
// Start a note with the given frequency and amplitude.;
-void tKarplusStrong_noteOn (tKarplusStrong* const p, float frequency, float amplitude )
+void tKarplusStrong_noteOn (tKarplusStrong* const pl, float frequency, float amplitude )
{
- tKarplusStrong_setFrequency( p, frequency );
- tKarplusStrong_pluck( p, amplitude );
+ tKarplusStrong_setFrequency( pl, frequency );
+ tKarplusStrong_pluck( pl, amplitude );
}
// Stop a note with the given amplitude (speed of decay).
-void tKarplusStrong_noteOff (tKarplusStrong* const p, float amplitude )
+void tKarplusStrong_noteOff (tKarplusStrong* const pl, float amplitude )
{
+ _tKarplusStrong* p = *pl;
+
if ( amplitude < 0.0f) amplitude = 0.0f;
else if (amplitude > 1.0f) amplitude = 1.0f;
@@ -203,8 +232,10 @@
}
// Set instrument parameters for a particular frequency.
-void tKarplusStrong_setFrequency (tKarplusStrong* const p, float frequency )
+void tKarplusStrong_setFrequency (tKarplusStrong* const pl, float frequency )
{
+ _tKarplusStrong* p = *pl;
+
if ( frequency <= 0.0f ) frequency = 0.001f;
p->lastFrequency = frequency;
@@ -216,7 +247,7 @@
p->loopGain = p->baseLoopGain + (frequency * 0.000005f);
if (p->loopGain >= 1.0f) p->loopGain = 0.99999f;
- tKarplusStrong_setStretch(p, p->stretching);
+ tKarplusStrong_setStretch(pl, p->stretching);
tLinearDelay_setDelay(&p->combDelay, 0.5f * p->pickupPosition * p->lastLength );
@@ -223,8 +254,10 @@
}
// Set the stretch "factor" of the string (0.0 - 1.0).
-void tKarplusStrong_setStretch (tKarplusStrong* const p, float stretch )
+void tKarplusStrong_setStretch (tKarplusStrong* const pl, float stretch )
{
+ _tKarplusStrong* p = *pl;
+
p->stretching = stretch;
float coefficient;
float freq = p->lastFrequency * 2.0f;
@@ -248,8 +281,10 @@
}
// Set the pluck or "excitation" position along the string (0.0 - 1.0).
-void tKarplusStrong_setPickupPosition (tKarplusStrong* const p, float position )
+void tKarplusStrong_setPickupPosition (tKarplusStrong* const pl, float position )
{
+ _tKarplusStrong* p = *pl;
+
if (position < 0.0f) p->pickupPosition = 0.0f;
else if (position <= 1.0f) p->pickupPosition = position;
else p->pickupPosition = 1.0f;
@@ -258,8 +293,10 @@
}
// Set the base loop gain.
-void tKarplusStrong_setBaseLoopGain (tKarplusStrong* const p, float aGain )
+void tKarplusStrong_setBaseLoopGain (tKarplusStrong* const pl, float aGain )
{
+ _tKarplusStrong* p = *pl;
+
p->baseLoopGain = aGain;
p->loopGain = p->baseLoopGain + (p->lastFrequency * 0.000005f);
if ( p->loopGain > 0.99999f ) p->loopGain = 0.99999f;
@@ -266,7 +303,7 @@
}
// Perform the control change specified by \e number and \e value (0.0 - 128.0).
-void tKarplusStrong_controlChange (tKarplusStrong* const p, SKControlType type, float value)
+void tKarplusStrong_controlChange (tKarplusStrong* const pl, SKControlType type, float value)
{
if ( value < 0.0f ) value = 0.0f;
else if (value > 128.0f) value = 128.0f;
@@ -274,27 +311,30 @@
float normalizedValue = value * INV_128;
if (type == SKPickPosition) // 4
- tKarplusStrong_setPickupPosition( p, normalizedValue );
+ tKarplusStrong_setPickupPosition( pl, normalizedValue );
else if (type == SKStringDamping) // 11
- tKarplusStrong_setBaseLoopGain( p, 0.97f + (normalizedValue * 0.03f) );
+ tKarplusStrong_setBaseLoopGain( pl, 0.97f + (normalizedValue * 0.03f) );
else if (type == SKDetune) // 1
- tKarplusStrong_setStretch( p, 0.91f + (0.09f * (1.0f - normalizedValue)) );
-
+ tKarplusStrong_setStretch( pl, 0.91f + (0.09f * (1.0f - normalizedValue)) );
}
-void tKarplusStrongSampleRateChanged (tKarplusStrong* const c)
+void tKarplusStrongSampleRateChanged (tKarplusStrong* const pl)
{
- tKarplusStrong_setFrequency(c, c->lastFrequency);
- tKarplusStrong_setStretch(c, c->stretching);
+ _tKarplusStrong* p = *pl;
+
+ tKarplusStrong_setFrequency(pl, p->lastFrequency);
+ tKarplusStrong_setStretch(pl, p->stretching);
}
/* Simple Living String*/
-void tSimpleLivingString_init(tSimpleLivingString* const p, float freq, float dampFreq, float decay, float targetLev, float levSmoothFactor, float levStrength, int levMode)
+void tSimpleLivingString_init(tSimpleLivingString* const pl, float freq, float dampFreq, float decay, float targetLev, float levSmoothFactor, float levStrength, int levMode)
{
+ _tSimpleLivingString* p = *pl = (_tSimpleLivingString*) leaf_alloc(sizeof(_tSimpleLivingString));
+
p->curr=0.0f;
tExpSmooth_init(&p->wlSmooth, leaf.sampleRate/freq, 0.01); // smoother for string wavelength (not freq, to avoid expensive divisions)
- tSimpleLivingString_setFreq(p, freq);
+ tSimpleLivingString_setFreq(pl, freq);
tLinearDelay_init(&p->delayLine,p->waveLengthInSamples, 2400);
tOnePole_init(&p->bridgeFilter, dampFreq);
tHighpass_init(&p->DCblocker,13);
@@ -303,72 +343,80 @@
p->levMode=levMode;
}
-void tSimpleLivingString_free(tSimpleLivingString* const p)
+void tSimpleLivingString_free(tSimpleLivingString* const pl)
{
+ _tSimpleLivingString* p = *pl;
+
tExpSmooth_free(&p->wlSmooth);
tLinearDelay_free(&p->delayLine);
tOnePole_free(&p->bridgeFilter);
tHighpass_free(&p->DCblocker);
tFeedbackLeveler_free(&p->fbLev);
+
+ leaf_free(p);
}
-int tSimpleLivingString_setFreq(tSimpleLivingString* const p, float freq)
+void tSimpleLivingString_setFreq(tSimpleLivingString* const pl, float freq)
{
+ _tSimpleLivingString* p = *pl;
+
if (freq<20) freq=20;
else if (freq>10000) freq=10000;
p->waveLengthInSamples = leaf.sampleRate/freq;
tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
- return 0;
}
-int tSimpleLivingString_setWaveLength(tSimpleLivingString* const p, float waveLength)
+void tSimpleLivingString_setWaveLength(tSimpleLivingString* const pl, float waveLength)
{
+ _tSimpleLivingString* p = *pl;
+
if (waveLength<4.8) waveLength=4.8;
else if (waveLength>2400) waveLength=2400;
p->waveLengthInSamples = waveLength;
tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
- return 0;
}
-int tSimpleLivingString_setDampFreq(tSimpleLivingString* const p, float dampFreq)
+void tSimpleLivingString_setDampFreq(tSimpleLivingString* const pl, float dampFreq)
{
+ _tSimpleLivingString* p = *pl;
tOnePole_setFreq(&p->bridgeFilter, dampFreq);
- return 0;
}
-int tSimpleLivingString_setDecay(tSimpleLivingString* const p, float decay)
+void tSimpleLivingString_setDecay(tSimpleLivingString* const pl, float decay)
{
+ _tSimpleLivingString* p = *pl;
p->decay=decay;
- return 0;
}
-int tSimpleLivingString_setTargetLev(tSimpleLivingString* const p, float targetLev)
+void tSimpleLivingString_setTargetLev(tSimpleLivingString* const pl, float targetLev)
{
+ _tSimpleLivingString* p = *pl;
tFeedbackLeveler_setTargetLevel(&p->fbLev, targetLev);
- return 0;
}
-int tSimpleLivingString_setLevSmoothFactor(tSimpleLivingString* const p, float levSmoothFactor)
+void tSimpleLivingString_setLevSmoothFactor(tSimpleLivingString* const pl, float levSmoothFactor)
{
+ _tSimpleLivingString* p = *pl;
tFeedbackLeveler_setFactor(&p->fbLev, levSmoothFactor);
- return 0;
}
-int tSimpleLivingString_setLevStrength(tSimpleLivingString* const p, float levStrength)
+void tSimpleLivingString_setLevStrength(tSimpleLivingString* const pl, float levStrength)
{
+ _tSimpleLivingString* p = *pl;
tFeedbackLeveler_setStrength(&p->fbLev, levStrength);
- return 0;
}
-int tSimpleLivingString_setLevMode(tSimpleLivingString* const p, int levMode)
+void tSimpleLivingString_setLevMode(tSimpleLivingString* const pl, int levMode)
{
+ _tSimpleLivingString* p = *pl;
tFeedbackLeveler_setMode(&p->fbLev, levMode);
p->levMode=levMode;
- return 0;
}
-float tSimpleLivingString_tick(tSimpleLivingString* const p, float input)
+float tSimpleLivingString_tick(tSimpleLivingString* const pl, float input)
{
+ _tSimpleLivingString* p = *pl;
+
float stringOut=tOnePole_tick(&p->bridgeFilter,tLinearDelay_tickOut(&p->delayLine));
float stringInput=tHighpass_tick(&p->DCblocker, tFeedbackLeveler_tick(&p->fbLev, (p->levMode==0?p->decay*stringOut:stringOut)+input));
tLinearDelay_tickIn(&p->delayLine, stringInput);
@@ -377,20 +425,23 @@
return p->curr;
}
-float tSimpleLivingString_sample(tSimpleLivingString* const p)
+float tSimpleLivingString_sample(tSimpleLivingString* const pl)
{
+ _tSimpleLivingString* p = *pl;
return p->curr;
}
/* Living String*/
-void tLivingString_init(tLivingString* const p, float freq, float pickPos, float prepIndex, float dampFreq, float decay, float targetLev, float levSmoothFactor, float levStrength, int levMode)
+void tLivingString_init(tLivingString* const pl, float freq, float pickPos, float prepIndex, float dampFreq, float decay, float targetLev, float levSmoothFactor, float levStrength, int levMode)
{
+ _tLivingString* p = *pl = (_tLivingString*) leaf_alloc(sizeof(_tLivingString));
+
p->curr=0.0f;
tExpSmooth_init(&p->wlSmooth, leaf.sampleRate/freq, 0.01); // smoother for string wavelength (not freq, to avoid expensive divisions)
- tLivingString_setFreq(p, freq);
+ tLivingString_setFreq(pl, freq);
tExpSmooth_init(&p->ppSmooth, pickPos, 0.01); // smoother for pick position
- tLivingString_setPickPos(p, pickPos);
+ tLivingString_setPickPos(pl, pickPos);
p->prepIndex=prepIndex;
tLinearDelay_init(&p->delLF,p->waveLengthInSamples, 2400);
tLinearDelay_init(&p->delUF,p->waveLengthInSamples, 2400);
@@ -408,8 +459,10 @@
p->levMode=levMode;
}
-void tLivingString_free(tLivingString* const p)
+void tLivingString_free(tLivingString* const pl)
{
+ _tLivingString* p = *pl;
+
tExpSmooth_free(&p->wlSmooth);
tExpSmooth_free(&p->ppSmooth);
tLinearDelay_free(&p->delLF);
@@ -424,89 +477,93 @@
tHighpass_free(&p->DCblockerL);
tFeedbackLeveler_free(&p->fbLevU);
tFeedbackLeveler_free(&p->fbLevL);
+
+ leaf_free(p);
}
-int tLivingString_setFreq(tLivingString* const p, float freq)
+void tLivingString_setFreq(tLivingString* const pl, float freq)
{ // NOTE: It is faster to set wavelength in samples directly
+ _tLivingString* p = *pl;
if (freq<20) freq=20;
else if (freq>10000) freq=10000;
p->waveLengthInSamples = leaf.sampleRate/freq;
tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
- return 0;
}
-int tLivingString_setWaveLength(tLivingString* const p, float waveLength)
+void tLivingString_setWaveLength(tLivingString* const pl, float waveLength)
{
+ _tLivingString* p = *pl;
if (waveLength<4.8) waveLength=4.8;
else if (waveLength>2400) waveLength=2400;
p->waveLengthInSamples = waveLength;
tExpSmooth_setDest(&p->wlSmooth, p->waveLengthInSamples);
- return 0;
}
-int tLivingString_setPickPos(tLivingString* const p, float pickPos)
+void tLivingString_setPickPos(tLivingString* const pl, float pickPos)
{ // between 0 and 1
+ _tLivingString* p = *pl;
if (pickPos<0.f) pickPos=0.f;
else if (pickPos>1.f) pickPos=1.f;
p->pickPos = pickPos;
tExpSmooth_setDest(&p->ppSmooth, p->pickPos);
- return 0;
}
-int tLivingString_setPrepIndex(tLivingString* const p, float prepIndex)
+void tLivingString_setPrepIndex(tLivingString* const pl, float prepIndex)
{ // between 0 and 1
+ _tLivingString* p = *pl;
if (prepIndex<0.f) prepIndex=0.f;
else if (prepIndex>1.f) prepIndex=1.f;
p->prepIndex = prepIndex;
- return 0;
}
-int tLivingString_setDampFreq(tLivingString* const p, float dampFreq)
+void tLivingString_setDampFreq(tLivingString* const pl, float dampFreq)
{
+ _tLivingString* p = *pl;
tOnePole_setFreq(&p->bridgeFilter, dampFreq);
tOnePole_setFreq(&p->nutFilter, dampFreq);
tOnePole_setFreq(&p->prepFilterU, dampFreq);
tOnePole_setFreq(&p->prepFilterL, dampFreq);
- return 0;
}
-int tLivingString_setDecay(tLivingString* const p, float decay)
+void tLivingString_setDecay(tLivingString* const pl, float decay)
{
+ _tLivingString* p = *pl;
p->decay=decay;
- return 0;
}
-int tLivingString_setTargetLev(tLivingString* const p, float targetLev)
+void tLivingString_setTargetLev(tLivingString* const pl, float targetLev)
{
+ _tLivingString* p = *pl;
tFeedbackLeveler_setTargetLevel(&p->fbLevU, targetLev);
tFeedbackLeveler_setTargetLevel(&p->fbLevL, targetLev);
- return 0;
}
-int tLivingString_setLevSmoothFactor(tLivingString* const p, float levSmoothFactor)
+void tLivingString_setLevSmoothFactor(tLivingString* const pl, float levSmoothFactor)
{
+ _tLivingString* p = *pl;
tFeedbackLeveler_setFactor(&p->fbLevU, levSmoothFactor);
tFeedbackLeveler_setFactor(&p->fbLevL, levSmoothFactor);
- return 0;
}
-int tLivingString_setLevStrength(tLivingString* const p, float levStrength)
+void tLivingString_setLevStrength(tLivingString* const pl, float levStrength)
{
+ _tLivingString* p = *pl;
tFeedbackLeveler_setStrength(&p->fbLevU, levStrength);
tFeedbackLeveler_setStrength(&p->fbLevL, levStrength);
- return 0;
}
-int tLivingString_setLevMode(tLivingString* const p, int levMode)
+void tLivingString_setLevMode(tLivingString* const pl, int levMode)
{
+ _tLivingString* p = *pl;
tFeedbackLeveler_setMode(&p->fbLevU, levMode);
tFeedbackLeveler_setMode(&p->fbLevL, levMode);
p->levMode=levMode;
- return 0;
}
-float tLivingString_tick(tLivingString* const p, float input)
+float tLivingString_tick(tLivingString* const pl, float input)
{
+ _tLivingString* p = *pl;
+
// from pickPos upwards=forwards
float fromLF=tLinearDelay_tickOut(&p->delLF);
float fromUF=tLinearDelay_tickOut(&p->delUF);
@@ -539,8 +596,9 @@
return p->curr;
}
-float tLivingString_sample(tLivingString* const p)
+float tLivingString_sample(tLivingString* const pl)
{
+ _tLivingString* p = *pl;
return p->curr;
}
@@ -547,19 +605,25 @@
///Reed Table model
//default values from STK are 0.6 offset and -0.8 slope
-void tReedTable_init (tReedTable* const p, float offset, float slope)
+void tReedTable_init (tReedTable* const pm, float offset, float slope)
{
+ _tReedTable* p = *pm = (_tReedTable*) leaf_alloc(sizeof(_tReedTable));
+
p->offset = offset;
p->slope = slope;
}
-void tReedTable_free (tReedTable* const p)
+void tReedTable_free (tReedTable* const pm)
{
- ;
+ _tReedTable* p = *pm;
+
+ leaf_free(p);
}
-float tReedTable_tick (tReedTable* const p, float input)
+float tReedTable_tick (tReedTable* const pm, float input)
{
+ _tReedTable* p = *pm;
+
// The input is differential pressure across the reed.
float output = p->offset + (p->slope * input);
@@ -575,8 +639,10 @@
return output;
}
-float tReedTable_tanh_tick (tReedTable* const p, float input)
+float tReedTable_tanh_tick (tReedTable* const pm, float input)
{
+ _tReedTable* p = *pm;
+
// The input is differential pressure across the reed.
float output = p->offset + (p->slope * input);
@@ -585,12 +651,14 @@
return tanhf(output);
}
-void tReedTable_setOffset (tReedTable* const p, float offset)
+void tReedTable_setOffset (tReedTable* const pm, float offset)
{
+ _tReedTable* p = *pm;
p->offset = offset;
}
-void tReedTable_setSlope (tReedTable* const p, float slope)
+void tReedTable_setSlope (tReedTable* const pm, float slope)
{
+ _tReedTable* p = *pm;
p->slope = slope;
}
--- a/LEAF/Src/leaf-reverb.c
+++ b/LEAF/Src/leaf-reverb.c
@@ -19,8 +19,10 @@
#endif
// ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ PRCReverb ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ //
-void tPRCReverb_init(tPRCReverb* const r, float t60)
+void tPRCReverb_init(tPRCReverb* const rev, float t60)
{
+ _tPRCReverb* r = *rev = (_tPRCReverb*) leaf_alloc(sizeof(_tPRCReverb));
+
if (t60 <= 0.0f) t60 = 0.001f;
r->inv_441 = 1.0f/44100.0f;
@@ -47,21 +49,26 @@
tDelay_init(&r->allpassDelays[1], lengths[1], lengths[1] * 2);
tDelay_init(&r->combDelay, lengths[2], lengths[2] * 2);
- tPRCReverb_setT60(r, t60);
+ tPRCReverb_setT60(rev, t60);
r->allpassCoeff = 0.7f;
r->mix = 0.5f;
}
-void tPRCReverb_free(tPRCReverb* const r)
+void tPRCReverb_free(tPRCReverb* const rev)
{
+ _tPRCReverb* r = *rev;
+
tDelay_free(&r->allpassDelays[0]);
tDelay_free(&r->allpassDelays[1]);
tDelay_free(&r->combDelay);
+ leaf_free(r);
}
-void tPRCReverb_setT60(tPRCReverb* const r, float t60)
+void tPRCReverb_setT60(tPRCReverb* const rev, float t60)
{
+ _tPRCReverb* r = *rev;
+
if ( t60 <= 0.0f ) t60 = 0.001f;
r->t60 = t60;
@@ -70,13 +77,16 @@
}
-void tPRCReverb_setMix(tPRCReverb* const r, float mix)
+void tPRCReverb_setMix(tPRCReverb* const rev, float mix)
{
+ _tPRCReverb* r = *rev;
r->mix = mix;
}
-float tPRCReverb_tick(tPRCReverb* const r, float input)
+float tPRCReverb_tick(tPRCReverb* const rev, float input)
{
+ _tPRCReverb* r = *rev;
+
float temp, temp0, temp1, temp2;
float out;
@@ -107,14 +117,17 @@
return out;
}
-void tPRCReverbSampleRateChanged (tPRCReverb* const r)
+void tPRCReverbSampleRateChanged (tPRCReverb* const rev)
{
+ _tPRCReverb* r = *rev;
r->combCoeff = pow(10.0f, (-3.0f * tDelay_getDelay(&r->combDelay) * leaf.invSampleRate / r->t60 ));
}
/* ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ NReverb ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ */
-void tNReverb_init(tNReverb* const r, float t60)
+void tNReverb_init(tNReverb* const rev, float t60)
{
+ _tNReverb* r = *rev = (_tNReverb*) leaf_alloc(sizeof(_tNReverb));
+
if (t60 <= 0.0f) t60 = 0.001f;
r->inv_441 = 1.0f/44100.0f;
@@ -150,13 +163,15 @@
tDelay_setDelay(&r->combDelays[i], lengths[i+2]);
}
- tNReverb_setT60(r, t60);
+ tNReverb_setT60(rev, t60);
r->allpassCoeff = 0.7f;
r->mix = 0.3f;
}
-void tNReverb_free(tNReverb* const r)
+void tNReverb_free(tNReverb* const rev)
{
+ _tNReverb* r = *rev;
+
for (int i = 0; i < 6; i++)
{
tDelay_free(&r->combDelays[i]);
@@ -166,10 +181,14 @@
{
tDelay_free(&r->allpassDelays[i]);
}
+
+ leaf_free(r);
}
-void tNReverb_setT60(tNReverb* const r, float t60)
+void tNReverb_setT60(tNReverb* const rev, float t60)
{
+ _tNReverb* r = *rev;
+
if (t60 <= 0.0f) t60 = 0.001f;
r->t60 = t60;
@@ -178,13 +197,15 @@
}
-void tNReverb_setMix(tNReverb* const r, float mix)
+void tNReverb_setMix(tNReverb* const rev, float mix)
{
+ _tNReverb* r = *rev;
r->mix = mix;
}
-float tNReverb_tick(tNReverb* const r, float input)
+float tNReverb_tick(tNReverb* const rev, float input)
{
+ _tNReverb* r = *rev;
r->lastIn = input;
float temp, temp0, temp1, temp2, out;
@@ -237,8 +258,9 @@
return out;
}
-void tNReverbSampleRateChanged (tNReverb* const r)
+void tNReverbSampleRateChanged (tNReverb* const rev)
{
+ _tNReverb* r = *rev;
for (int i=0; i<6; i++) r->combCoeffs[i] = pow(10.0, (-3.0 * tDelay_getDelay(&r->combDelays[i]) * leaf.invSampleRate / r->t60 ));
}
@@ -250,8 +272,10 @@
float in_allpass_gains[4] = { 0.75f, 0.75f, 0.625f, 0.625f };
-void tDattorroReverb_init (tDattorroReverb* const r)
+void tDattorroReverb_init (tDattorroReverb* const rev)
{
+ _tDattorroReverb* r = *rev = (_tDattorroReverb*) leaf_alloc(sizeof(_tDattorroReverb));
+
r->size_max = 2.0f;
r->size = 1.f;
r->t = r->size * leaf.sampleRate * 0.001f;
@@ -298,21 +322,23 @@
// PARAMETERS
- tDattorroReverb_setMix(r, 0.5f);
+ tDattorroReverb_setMix(rev, 0.5f);
- tDattorroReverb_setInputDelay(r, 0.f);
+ tDattorroReverb_setInputDelay(rev, 0.f);
- tDattorroReverb_setInputFilter(r, 10000.f);
+ tDattorroReverb_setInputFilter(rev, 10000.f);
- tDattorroReverb_setFeedbackFilter(r, 5000.f);
+ tDattorroReverb_setFeedbackFilter(rev, 5000.f);
- tDattorroReverb_setFeedbackGain(r, 0.4f);
+ tDattorroReverb_setFeedbackGain(rev, 0.4f);
}
-void tDattorroReverb_free (tDattorroReverb* const r)
+void tDattorroReverb_free (tDattorroReverb* const rev)
{
+ _tDattorroReverb* r = *rev;
+
// INPUT
tTapeDelay_free(&r->in_delay);
tOnePole_free(&r->in_filter);
@@ -347,10 +373,14 @@
tHighpass_free(&r->f2_hp);
tCycle_free(&r->f2_lfo);
+
+ leaf_free(r);
}
-float tDattorroReverb_tick (tDattorroReverb* const r, float input)
+float tDattorroReverb_tick (tDattorroReverb* const rev, float input)
{
+ _tDattorroReverb* r = *rev;
+
// INPUT
float in_sample = tTapeDelay_tick(&r->in_delay, input);
@@ -449,13 +479,16 @@
return (input * (1.0f - r->mix) + sample * r->mix);
}
-void tDattorroReverb_setMix (tDattorroReverb* const r, float mix)
+void tDattorroReverb_setMix (tDattorroReverb* const rev, float mix)
{
+ _tDattorroReverb* r = *rev;
r->mix = LEAF_clip(0.0f, mix, 1.0f);
}
-void tDattorroReverb_setSize (tDattorroReverb* const r, float size)
+void tDattorroReverb_setSize (tDattorroReverb* const rev, float size)
{
+ _tDattorroReverb* r = *rev;
+
r->size = LEAF_clip(0.01f, size*r->size_max, r->size_max);
r->t = r->size * leaf.sampleRate * 0.001f;
@@ -483,22 +516,28 @@
tTapeDelay_setDelay(&r->f2_delay_3, SAMP(106.28f));
}
-void tDattorroReverb_setInputDelay (tDattorroReverb* const r, float preDelay)
+void tDattorroReverb_setInputDelay (tDattorroReverb* const rev, float preDelay)
{
+ _tDattorroReverb* r = *rev;
+
r->predelay = LEAF_clip(0.0f, preDelay, 200.0f);
tTapeDelay_setDelay(&r->in_delay, SAMP(r->predelay));
}
-void tDattorroReverb_setInputFilter (tDattorroReverb* const r, float freq)
+void tDattorroReverb_setInputFilter (tDattorroReverb* const rev, float freq)
{
+ _tDattorroReverb* r = *rev;
+
r->input_filter = LEAF_clip(0.0f, freq, 20000.0f);
tOnePole_setFreq(&r->in_filter, r->input_filter);
}
-void tDattorroReverb_setFeedbackFilter (tDattorroReverb* const r, float freq)
+void tDattorroReverb_setFeedbackFilter (tDattorroReverb* const rev, float freq)
{
+ _tDattorroReverb* r = *rev;
+
r->feedback_filter = LEAF_clip(0.0f, freq, 20000.0f);
tOnePole_setFreq(&r->f1_filter, r->feedback_filter);
@@ -505,7 +544,8 @@
tOnePole_setFreq(&r->f2_filter, r->feedback_filter);
}
-void tDattorroReverb_setFeedbackGain (tDattorroReverb* const r, float gain)
+void tDattorroReverb_setFeedbackGain (tDattorroReverb* const rev, float gain)
{
+ _tDattorroReverb* r = *rev;
r->feedback_gain = gain;
}
--- a/LEAF/Src/leaf-sampling.c
+++ b/LEAF/Src/leaf-sampling.c
@@ -23,26 +23,32 @@
//==============================================================================
-void tBuffer_init (tBuffer* const s, uint32_t length)
+void tBuffer_init (tBuffer* const sb, uint32_t length)
{
+ _tBuffer* s = *sb = (_tBuffer*) leaf_alloc(sizeof(_tBuffer));
+
s->buff = (float*) leaf_alloc( sizeof(float) * length);
-
s->length = length;
s->active = 0;
s->idx = 0;
s->mode = RecordOneShot;
- tBuffer_clear(s);
+ tBuffer_clear(sb);
}
-void tBuffer_free (tBuffer* const s)
+void tBuffer_free (tBuffer* const sb)
{
+ _tBuffer* s = *sb;
+
leaf_free(s->buff);
+ leaf_free(s);
}
-void tBuffer_tick (tBuffer* const s, float sample)
+void tBuffer_tick (tBuffer* const sb, float sample)
{
+ _tBuffer* s = *sb;
+
if (s->active == 1)
{
s->buff[s->idx] = sample;
@@ -53,7 +59,7 @@
{
if (s->mode == RecordOneShot)
{
- tBuffer_stop(s);
+ tBuffer_stop(sb);
}
else if (s->mode == RecordLoop)
{
@@ -63,8 +69,9 @@
}
}
-void tBuffer_read(tBuffer* const s, float* buff, uint32_t len)
+void tBuffer_read(tBuffer* const sb, float* buff, uint32_t len)
{
+ _tBuffer* s = *sb;
for (int i = 0; i < s->length; i++)
{
if (i < len) s->buff[i] = buff[i];
@@ -72,31 +79,35 @@
}
}
-float tBuffer_get (tBuffer* const s, int idx)
+float tBuffer_get (tBuffer* const sb, int idx)
{
+ _tBuffer* s = *sb;
if ((idx < 0) || (idx >= s->length)) return 0.f;
-
return s->buff[idx];
}
-void tBuffer_record(tBuffer* const s)
+void tBuffer_record(tBuffer* const sb)
{
+ _tBuffer* s = *sb;
s->active = 1;
s->idx = 0;
}
-void tBuffer_stop(tBuffer* const s)
+void tBuffer_stop(tBuffer* const sb)
{
+ _tBuffer* s = *sb;
s->active = 0;
}
-void tBuffer_setRecordMode (tBuffer* const s, RecordMode mode)
+void tBuffer_setRecordMode (tBuffer* const sb, RecordMode mode)
{
+ _tBuffer* s = *sb;
s->mode = mode;
}
-void tBuffer_clear (tBuffer* const s)
+void tBuffer_clear (tBuffer* const sb)
{
+ _tBuffer* s = *sb;
for (int i = 0; i < s->length; i++)
{
s->buff[i] = 0.f;
@@ -103,12 +114,20 @@
}
}
+uint32_t tBuffe_getLength(tBuffer* const sb)
+{
+ _tBuffer* s = *sb;
+ return s->length;
+}
+
//================================tSampler=====================================
-void tSampler_init(tSampler* const p, tBuffer* const s)
+void tSampler_init(tSampler* const sp, uint32_t length)
{
- p->samp = s;
+ _tSampler* p = *sp = (_tSampler*) leaf_alloc(sizeof(_tSampler));
+ tBuffer_init(&p->samp, length);
+
p->active = 0;
p->start = 0;
@@ -132,13 +151,24 @@
tRamp_setVal(&p->gain, 0.f);
}
-void tSampler_free (tSampler* const p)
+void tSampler_free (tSampler* const sp)
{
+ _tSampler* p = *sp;
tRamp_free(&p->gain);
+
+ leaf_free(p);
}
-float tSampler_tick (tSampler* const p)
+tBuffer tSampler_getBuffer (tSampler* const sp)
{
+ _tSampler* p = *sp;
+ return p->samp;
+}
+
+float tSampler_tick (tSampler* const sp)
+{
+ _tSampler* p = *sp;
+
if (p->active == 0) return 0.f;
if ((p->inc == 0.0f) || (p->len < 4))
@@ -331,18 +361,16 @@
return p->last;
}
-void tSampler_setSample (tSampler* const p, tBuffer* s)
+void tSampler_setMode (tSampler* const sp, PlayMode mode)
{
- p->samp = s;
-}
-
-void tSampler_setMode (tSampler* const p, PlayMode mode)
-{
+ _tSampler* p = *sp;
p->mode = mode;
}
-void tSampler_setCrossfadeLength (tSampler* const p, uint32_t length)
+void tSampler_setCrossfadeLength (tSampler* const sp, uint32_t length)
{
+ _tSampler* p = *sp;
+
uint32_t cfxlen = LEAF_clip(0, length, 1000);
//if (cfxlen > p->len) cfxlen = p->len * 0.25f;
@@ -350,8 +378,10 @@
p->cfxlen = cfxlen;
}
-void tSampler_play (tSampler* const p)
+void tSampler_play (tSampler* const sp)
{
+ _tSampler* p = *sp;
+
if (p->active != 0)
{
p->active = -1;
@@ -379,15 +409,19 @@
}
}
-void tSampler_stop (tSampler* const p)
+void tSampler_stop (tSampler* const sp)
{
+ _tSampler* p = *sp;
+
p->active = -1;
tRamp_setDest(&p->gain, 0.f);
}
-static void handleStartEndChange(tSampler* const p)
+static void handleStartEndChange(tSampler* const sp)
{
+ _tSampler* p = *sp;
+
p->len = abs(p->end - p->start);
//if (p->len < p->cfxlen) p->cfxlen = p->len * 0.9f;
@@ -402,22 +436,28 @@
}
}
-void tSampler_setStart (tSampler* const p, int32_t start)
+void tSampler_setStart (tSampler* const sp, int32_t start)
{
+ _tSampler* p = *sp;
+
p->start = LEAF_clipInt(0, start, (p->samp->length - 1));
- handleStartEndChange(p);
+ handleStartEndChange(sp);
}
-void tSampler_setEnd (tSampler* const p, int32_t end)
+void tSampler_setEnd (tSampler* const sp, int32_t end)
{
+ _tSampler* p = *sp;
+
p->end = LEAF_clipInt(0, end, (p->samp->length - 1));
- handleStartEndChange(p);
+ handleStartEndChange(sp);
}
-void tSampler_setRate (tSampler* const p, float rate)
+void tSampler_setRate (tSampler* const sp, float rate)
{
+ _tSampler* p = *sp;
+
if (rate < 0.f)
{
rate = -rate;
--- a/LEAF_JUCEPlugin/LEAF.jucer
+++ b/LEAF_JUCEPlugin/LEAF.jucer
@@ -16,8 +16,6 @@
<GROUP id="{14C5E2CD-5D51-3FD3-5677-28BECA29E95E}" name="Source">
<GROUP id="{C9F79DF0-2C57-F2B0-7B1B-78A14937E038}" name="LEAF">
<GROUP id="{B591B686-9726-94F1-28CD-B08349461C76}" name="Externals">
- <FILE id="oBE37z" name="atkdetect.c" compile="1" resource="0" file="../LEAF/Externals/atkdetect.c"/>
- <FILE id="MchITp" name="atkdetect.h" compile="0" resource="0" file="../LEAF/Externals/atkdetect.h"/>
<FILE id="O0YJRY" name="d_fft_mayer.c" compile="1" resource="0" file="../LEAF/Externals/d_fft_mayer.c"/>
<FILE id="HdG3WV" name="d_fft_mayer.h" compile="0" resource="0" file="../LEAF/Externals/d_fft_mayer.h"/>
<FILE id="Hu4b98" name="trigtbl.h" compile="0" resource="0" file="../LEAF/Externals/trigtbl.h"/>
--- a/LEAF_JUCEPlugin/Source/LEAFLink.cpp
+++ b/LEAF_JUCEPlugin/Source/LEAFLink.cpp
@@ -94,6 +94,7 @@
return cComboBoxStates[i];
}
}
+ return -1;
}
void setComboBoxState(String name, int idx)