ref: 3ada2d4f41e83ac618dfb102955a5dee643f0b8e
parent: b0cf3f1d2e39f686651aca1129c7be482c877216
author: mulshine <mulshine@princeton.edu>
date: Thu Feb 7 12:53:23 EST 2019
Cleaned up some file headers. Implemented tCrusher, bit/sample reduction bitcrusher / shaper.
--- a/LEAF/Inc/leaf-808.h
+++ b/LEAF/Inc/leaf-808.h
@@ -1,6 +1,6 @@
/*==============================================================================
- leaf_808.h
+ leaf-808.h
Created: 30 Nov 2018 10:24:44am
Author: airship
--- /dev/null
+++ b/LEAF/Inc/leaf-crusher.h
@@ -1,0 +1,64 @@
+/*
+ ==============================================================================
+
+ leaf-crusher.h
+ Created: 7 Feb 2019 10:58:22am
+ Author: airship
+
+ ==============================================================================
+*/
+
+#ifndef LEAF_CRUSHER_H_INCLUDED
+#define LEAF_CRUSHER_H_INCLUDED
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//==============================================================================
+
+#include "leaf-globals.h"
+#include "leaf-math.h"
+
+//==============================================================================
+
+typedef struct _tCrusher
+{
+ float srr;
+ float mult, div;
+ float rnd;
+
+ uint32_t op; //which bitwise operation (0-7)
+
+ float gain;
+
+} tCrusher;
+
+
+void tCrusher_init (tCrusher* const);
+void tCrusher_free (tCrusher* const);
+
+float tCrusher_tick (tCrusher* const, float input);
+
+// 0-7
+void tCrusher_setOperation (tCrusher* const, uint32_t 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);
+
+//==============================================================================
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LEAF_WAVEFOLDER_H_INCLUDED
+
+//==============================================================================
--- a/LEAF/Inc/leaf-delay.h
+++ b/LEAF/Inc/leaf-delay.h
@@ -1,6 +1,6 @@
/*==============================================================================
- LEAFDelay.h
+ leaf-delay.h
Created: 20 Jan 2017 12:01:24pm
Author: Michael R Mulshine
--- a/LEAF/Inc/leaf-filter.h
+++ b/LEAF/Inc/leaf-filter.h
@@ -1,6 +1,6 @@
/*==============================================================================
- LEAFFilter.h
+ leaf-filter.h
Created: 20 Jan 2017 12:01:10pm
Author: Michael R Mulshine
--- a/LEAF/Inc/leaf-globals.h
+++ b/LEAF/Inc/leaf-globals.h
@@ -60,6 +60,11 @@
#define TALKBOX_BUFFER_LENGTH 1600 // Every talkbox instance introduces 5 buffers of this size
+union unholy_t { /* a union between a float and an integer */
+ float f;
+ int i;
+};
+
//==============================================================================
#ifdef __cplusplus
--- a/LEAF/Inc/leaf-math.h
+++ b/LEAF/Inc/leaf-math.h
@@ -1,6 +1,6 @@
/*==============================================================================
- LEAFMath.h
+ leaf-math.h
Created: 22 Jan 2017 7:02:56pm
Author: Michael R Mulshine
@@ -7,16 +7,16 @@
==============================================================================*/
#ifndef LEAF_MATH_H_INCLUDED
-#define LEAF_MATH_H_INCLUDED
-
-#ifdef __cplusplus
-extern "C" {
+#define LEAF_MATH_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
#endif
#include "math.h"
#include "stdint.h"
-#include "stdlib.h"
-
+#include "stdlib.h"
+
//==============================================================================
typedef enum oBool
@@ -76,47 +76,51 @@
// Jones shaper
float LEAF_shaper (float input, float m_drive);
-float LEAF_reedTable (float input, float offset, float slope);
+float LEAF_reedTable (float input, float offset, float slope);
+
+float LEAF_reduct (float input, float srr);
+float LEAF_round (float input, float rnd);
+float LEAF_bitwise_or(float input, uint32_t op);
-float LEAF_clip (float min, float val, float max);
+float LEAF_clip (float min, float val, float max);
int LEAF_clipInt (int min, int val, int max);
float LEAF_softClip (float val, float thresh);
-oBool LEAF_isPrime (uint64_t number );
+oBool LEAF_isPrime (uint64_t number );
-float LEAF_midiToFrequency (float f);
-float LEAF_frequencyToMidi(float f);
-
-void LEAF_generate_sine (float* buffer, int size);
-void LEAF_generate_sawtooth (float* buffer, float basefreq, int size);
-void LEAF_generate_triangle (float* buffer, float basefreq, int size);
+float LEAF_midiToFrequency (float f);
+float LEAF_frequencyToMidi(float f);
+
+void LEAF_generate_sine (float* buffer, int size);
+void LEAF_generate_sawtooth (float* buffer, float basefreq, int size);
+void LEAF_generate_triangle (float* buffer, float basefreq, int size);
void LEAF_generate_square (float* buffer, float basefreq, int size);
// dope af
float LEAF_chebyshevT(float in, int n);
float LEAF_CompoundChebyshevT(float in, int n, float* amps);
-
-
-// Hermite interpolation
-float LEAF_interpolate_hermite (float A, float B, float C, float D, float t);
-float LEAF_interpolation_linear (float A, float B, float t);
-float interpolate3max(float *buf, const int peakindex);
-float interpolate3phase(float *buf, const int peakindex);
-
-// alternative implementation for abs()
-// REQUIRES: 32 bit integers
-int fastabs_int(int in);
-
-// alternative implementation for abs()
-// REQUIRES: 32 bit floats
-float fastabs(float f);
-
-//==============================================================================
-
-#ifdef __cplusplus
-}
-#endif
-#endif // LEAF_MATH_H_INCLUDED
-
+// Hermite interpolation
+float LEAF_interpolate_hermite (float A, float B, float C, float D, float t);
+float LEAF_interpolation_linear (float A, float B, float t);
+
+float interpolate3max(float *buf, const int peakindex);
+float interpolate3phase(float *buf, const int peakindex);
+
+// alternative implementation for abs()
+// REQUIRES: 32 bit integers
+int fastabs_int(int in);
+
+// alternative implementation for abs()
+// REQUIRES: 32 bit floats
+float fastabs(float f);
+
+//==============================================================================
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LEAF_MATH_H_INCLUDED
+
//==============================================================================
--- a/LEAF/Inc/leaf-oscillator.h
+++ b/LEAF/Inc/leaf-oscillator.h
@@ -1,6 +1,6 @@
/*==============================================================================
- LEAFOscillator.h
+ leaf-oscillator.h
Created: 20 Jan 2017 12:00:58pm
Author: Michael R Mulshine
--- a/LEAF/Inc/leaf-reverb.h
+++ b/LEAF/Inc/leaf-reverb.h
@@ -1,6 +1,6 @@
/*==============================================================================
- LEAFReverb.h
+ leaf-reverb.h
Created: 20 Jan 2017 12:02:04pm
Author: Michael R Mulshine
--- a/LEAF/Inc/leaf-sample.h
+++ b/LEAF/Inc/leaf-sample.h
@@ -17,8 +17,8 @@
//==============================================================================
#include "leaf-globals.h"
-#include "leaf-math.h"
-
+#include "leaf-math.h"
+
#include "leaf-utilities.h"
//==============================================================================
@@ -34,11 +34,11 @@
{
float* buff;
- uint32_t idx;
+ uint32_t idx;
uint32_t length;
- RecordMode mode;
-
+ RecordMode mode;
+
int active;
} tBuffer;
@@ -46,72 +46,72 @@
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_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 Mode
- {
- Normal,
- Loop,
- BackAndForth,
- SampleModeNil
- } Mode;
-
- typedef struct _tSampler
- {
- tBuffer* samp;
-
- tRamp gain;
-
- float idx;
- float inc;
- float iinc;
- int8_t dir;
- int8_t flip;
- int8_t bnf;
-
- int32_t start;
- int32_t end;
- uint32_t len;
- uint32_t cfxlen;
-
- Mode mode;
- int retrigger;
-
- int active;
-
- } tSampler;
-
- void tSampler_init (tSampler* const, tBuffer* s);
- void tSampler_free (tSampler* const);
-
- float tSampler_tick (tSampler* const);
-
- void tSampler_setSample (tSampler* const, tBuffer* s);
-
- void tSampler_setMode (tSampler* const, Mode 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);
+ void tBuffer_setRecordMode (tBuffer* const, RecordMode mode);
+
+ void tBuffer_clear (tBuffer* const);
+
+//==============================================================================
+
+ typedef enum Mode
+ {
+ Normal,
+ Loop,
+ BackAndForth,
+ SampleModeNil
+ } Mode;
+
+ typedef struct _tSampler
+ {
+ tBuffer* samp;
+
+ tRamp gain;
+
+ float idx;
+ float inc;
+ float iinc;
+ int8_t dir;
+ int8_t flip;
+ int8_t bnf;
+
+ int32_t start;
+ int32_t end;
+ uint32_t len;
+ uint32_t cfxlen;
+
+ Mode mode;
+ int retrigger;
+
+ int active;
+
+ } tSampler;
+
+ void tSampler_init (tSampler* const, tBuffer* s);
+ void tSampler_free (tSampler* const);
+
+ float tSampler_tick (tSampler* const);
+
+ void tSampler_setSample (tSampler* const, tBuffer* s);
+
+ void tSampler_setMode (tSampler* const, Mode 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);
//==============================================================================
--- a/LEAF/Inc/leaf-utilities.h
+++ b/LEAF/Inc/leaf-utilities.h
@@ -1,6 +1,6 @@
/*==============================================================================
- LEAFUtilities.h
+ leaf-utilities.h
Created: 20 Jan 2017 12:02:17pm
Author: Michael R Mulshine
--- a/LEAF/Inc/leaf-vocoder.h
+++ b/LEAF/Inc/leaf-vocoder.h
@@ -1,6 +1,6 @@
/*==============================================================================
- LEAFInstrument.h
+ leaf-vocoder.h
Created: 20 Jan 2017 12:01:54pm
Author: Michael R Mulshine
--- a/LEAF/Inc/leaf-wavefolder.h
+++ b/LEAF/Inc/leaf-wavefolder.h
@@ -4,14 +4,14 @@
Created: 30 Nov 2018 11:57:05am
Author: airship
-==============================================================================*/
-
-#ifndef LEAF_WAVEFOLDER_H_INCLUDED
-#define LEAF_WAVEFOLDER_H_INCLUDED
-
-
-#ifdef __cplusplus
-extern "C" {
+==============================================================================*/
+
+#ifndef LEAF_WAVEFOLDER_H_INCLUDED
+#define LEAF_WAVEFOLDER_H_INCLUDED
+
+
+#ifdef __cplusplus
+extern "C" {
#endif
//==============================================================================
@@ -45,14 +45,14 @@
void tLockhartWavefolder_free (tLockhartWavefolder* const);
float tLockhartWavefolder_tick (tLockhartWavefolder* const, float samp);
-
-
-//==============================================================================
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // LEAF_WAVEFOLDER_H_INCLUDED
-
+
+
+//==============================================================================
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LEAF_WAVEFOLDER_H_INCLUDED
+
//==============================================================================
--- a/LEAF/Inc/leaf-wavetables.h
+++ b/LEAF/Inc/leaf-wavetables.h
@@ -1,6 +1,6 @@
/*==============================================================================
- LEAFWavetables.h
+ leaf-wavetables.h
Created: 4 Dec 2016 9:42:41pm
Author: Michael R Mulshine
--- a/LEAF/Src/leaf-808.c
+++ b/LEAF/Src/leaf-808.c
@@ -1,12 +1,10 @@
-/*
- ==============================================================================
+/*==============================================================================
- leaf_808.cpp
+ leaf-808.c
Created: 30 Nov 2018 10:24:21am
Author: airship
- ==============================================================================
-*/
+==============================================================================*/
#if _WIN32 || _WIN64
--- /dev/null
+++ b/LEAF/Src/leaf-crusher.c
@@ -1,0 +1,84 @@
+/*==============================================================================
+
+ leaf-crusher.c
+ Created: 30 Nov 2018 11:56:49am
+ Author: airship
+
+==============================================================================*/
+
+#if _WIN32 || _WIN64
+
+#include "..\Inc\leaf-crusher.h"
+
+#else
+
+#include "../Inc/leaf-crusher.h"
+
+#endif
+
+//==============================================================================
+
+#define SCALAR 5000.f
+
+void tCrusher_init (tCrusher* const c)
+{
+ c->op = 4;
+ c->div = SCALAR;
+ c->rnd = 0.25f;
+ c->srr = 0.25f;
+
+ c->gain = (c->div / SCALAR) * 0.7f + 0.3f;
+}
+
+void tCrusher_free (tCrusher* const c)
+{
+ leaf_free(c);
+}
+
+float tCrusher_tick (tCrusher* const c, float input)
+{
+ float sample = input;
+
+ sample *= SCALAR; // SCALAR is 5000 by default
+
+ sample = floorf(sample);
+
+ sample /= c->div;
+
+ sample = LEAF_bitwise_or(sample, c->op << 23);
+
+ sample = LEAF_clip(-1.f, sample, 1.f);
+
+ sample = LEAF_round(sample, c->rnd);
+
+ sample = LEAF_reduct(sample, c->srr);
+
+ return sample * c->gain;
+
+}
+
+void tCrusher_setOperation (tCrusher* const c, uint32_t op)
+{
+ c->op = op % 8;
+}
+
+// 0.0 - 1.0
+void tCrusher_setQuality (tCrusher* const c, float val)
+{
+ val = LEAF_clip(0.0f, val, 1.0f);
+
+ c->div = 0.01f + val * SCALAR;
+
+ c->gain = (c->div / SCALAR) * 0.7f + 0.3f;
+}
+
+// what decimal to round to
+void tCrusher_setRound (tCrusher* const c, float rnd)
+{
+ c->rnd = fabsf(rnd);
+}
+
+void tCrusher_setSamplingRatio (tCrusher* const c, float ratio)
+{
+ c->srr = ratio;
+}
--- a/LEAF/Src/leaf-delay.c
+++ b/LEAF/Src/leaf-delay.c
@@ -1,12 +1,10 @@
-/*
- ==============================================================================
+/*==============================================================================
- LEAFDelay.c
+ leaf-delay.c
Created: 20 Jan 2017 12:01:24pm
Author: Michael R Mulshine
- ==============================================================================
-*/
+==============================================================================*/
#if _WIN32 || _WIN64
--- a/LEAF/Src/leaf-filter.c
+++ b/LEAF/Src/leaf-filter.c
@@ -1,12 +1,10 @@
-/*
- ==============================================================================
+/*==============================================================================
- LEAFFilter.c
+ leaf-filter.c
Created: 20 Jan 2017 12:01:10pm
Author: Michael R Mulshine
- ==============================================================================
-*/
+==============================================================================*/
#if _WIN32 || _WIN64
--- a/LEAF/Src/leaf-formant.c
+++ b/LEAF/Src/leaf-formant.c
@@ -1,12 +1,10 @@
-/*
- ==============================================================================
+/*==============================================================================
- leaf-formant.cpp
+ leaf-formant.c
Created: 30 Nov 2018 11:03:30am
Author: airship
- ==============================================================================
-*/
+==============================================================================*/
#if _WIN32 || _WIN64
--- a/LEAF/Src/leaf-math.c
+++ b/LEAF/Src/leaf-math.c
@@ -1,12 +1,10 @@
-/*
- ==============================================================================
+/*==============================================================================
- LEAFMath.c
+ leaf-math.c
Created: 22 Jan 2017 7:02:56pm
Author: Michael R Mulshine
- ==============================================================================
-*/
+==============================================================================*/
#if _WIN32 || _WIN64
@@ -24,8 +22,8 @@
#define TWO_TO_16 65536.f
#define EXPONENTIAL_TABLE_SIZE 65536
-
+
float interpolate3max(float *buf, const int peakindex)
{
float a = buf[peakindex-1];
@@ -119,6 +117,50 @@
float shaperOut = w*(c+ 0.05f*xc2)*(m_drive + 0.75f);
shaperOut *= 0.5f; // post_scale
return shaperOut;
+}
+
+// reduce sample resolution
+float LEAF_reduct (float input, float sr)
+{
+ float samp = input;
+
+ samp *= sr;
+
+ // method 1
+ samp = ceilf(samp);
+
+ samp /= sr;
+
+ /*
+ // method 2
+ samp = floorf(samp + 0.5f) - 0.5f;
+
+ samp /= srr;
+ */
+
+ return samp;
+}
+
+// round input to nearest rnd
+float LEAF_round (float input, float rnd)
+{
+ rnd = fabsf(rnd);
+
+ if (rnd <= 0.0000001f) return input;
+
+ float scale = 1.f / rnd;
+
+ return roundf(input * scale) / scale;
+}
+
+union unholy_t unholy;
+
+float LEAF_bitwise_or(float input, uint32_t op)
+{
+ unholy.f = input;
+ unholy.i = (unholy.i | op);
+
+ return unholy.f;
}
float LEAF_reedTable(float input, float offset, float slope)
--- a/LEAF/Src/leaf-midi.c
+++ b/LEAF/Src/leaf-midi.c
@@ -1,12 +1,10 @@
-/*
- ==============================================================================
+/*==============================================================================
- leaf-midi.cpp
+ leaf-midi.c
Created: 30 Nov 2018 11:29:16am
Author: airship
- ==============================================================================
-*/
+==============================================================================*/
#if _WIN32 || _WIN64
--- a/LEAF/Src/leaf-oscillator.c
+++ b/LEAF/Src/leaf-oscillator.c
@@ -1,12 +1,10 @@
-/*
- ==============================================================================
+/*==============================================================================
- LEAFOscillator.c
+ leaf-oscillator.c
Created: 20 Jan 2017 12:00:58pm
Author: Michael R Mulshine
- ==============================================================================
-*/
+==============================================================================*/
#if _WIN32 || _WIN64
--- a/LEAF/Src/leaf-pitch.c
+++ b/LEAF/Src/leaf-pitch.c
@@ -1,12 +1,10 @@
-/*
- ==============================================================================
+/*==============================================================================
- leaf-pitch.cpp
+ leaf-pitch.c
Created: 30 Nov 2018 11:02:59am
Author: airship
- ==============================================================================
-*/
+==============================================================================*/
#if _WIN32 || _WIN64
--- a/LEAF/Src/leaf-reverb.c
+++ b/LEAF/Src/leaf-reverb.c
@@ -1,12 +1,10 @@
-/*
- ==============================================================================
+/*==============================================================================
- LEAFReverb.c
+ leaf-reverb.c
Created: 20 Jan 2017 12:02:04pm
Author: Michael R Mulshine
- ==============================================================================
-*/
+==============================================================================*/
#if _WIN32 || _WIN64
--- a/LEAF/Src/leaf-sample.c
+++ b/LEAF/Src/leaf-sample.c
@@ -1,7 +1,7 @@
/*
==============================================================================
- LEAFUtilities.c
+ leaf-sample.c
Created: 20 Jan 2017 12:02:17pm
Author: Michael R Mulshine
@@ -10,7 +10,7 @@
#if _WIN32 || _WIN64
-
+
#include "..\Inc\leaf-sample.h"
#include "..\leaf.h"
@@ -19,412 +19,412 @@
#include "../Inc/leaf-sample.h"
#include "../leaf.h"
-#endif
-
-//==============================================================================
-
-void tBuffer_init (tBuffer* const s, uint32_t length)
-{
- s->buff = (float*) leaf_alloc( sizeof(float) * length);
-
-
- s->length = length;
- s->active = 0;
- s->idx = 0;
- s->mode = RecordOneShot;
-
- tBuffer_clear(s);
-}
-
-void tBuffer_free (tBuffer* const s)
-{
- leaf_free(s->buff);
- leaf_free(s);
-}
-
-void tBuffer_tick (tBuffer* const s, float sample)
-{
- if (s->active == 1)
- {
- s->buff[s->idx] = sample;
-
- s->idx += 1;
-
- if (s->idx >= s->length)
- {
- if (s->mode == RecordOneShot)
- {
- tBuffer_stop(s);
- }
- else if (s->mode == RecordLoop)
- {
- s->idx = 0;
- }
- }
- }
-}
-
-void tBuffer_read(tBuffer* const s, float* buff, uint32_t len)
-{
- for (int i = 0; i < s->length; i++)
- {
- if (i < len) s->buff[i] = buff[i];
- else s->buff[i] = 0.f;
- }
-}
-
-float tBuffer_get (tBuffer* const s, int idx)
-{
- if ((idx < 0) || (idx >= s->length)) return 0.f;
-
- return s->buff[idx];
-}
-
-void tBuffer_record(tBuffer* const s)
-{
- s->active = 1;
- s->idx = 0;
-}
-
-void tBuffer_stop(tBuffer* const s)
-{
- s->active = 0;
-}
-
-void tBuffer_setRecordMode (tBuffer* const s, RecordMode mode)
-{
- s->mode = mode;
-}
-
-void tBuffer_clear (tBuffer* const s)
-{
- for (int i = 0; i < s->length; i++)
- {
- s->buff[i] = 0.f;
- }
-}
-
-//================================tSampler=====================================
+#endif
-void tSampler_init (tSampler* const p, tBuffer* s)
-{
- p->samp = s;
-
- p->active = 0;
-
- p->start = 0;
- p->end = p->samp->length - 1;
-
- p->len = p->end - p->start;
-
- p->idx = 0.f;
- p->inc = 1.f;
- p->iinc = 1.f;
-
- p->dir = 1;
- p->flip = 1;
- p->bnf = 1;
-
- p->mode = Normal;
-
- p->cfxlen = 300; // default 300 sample crossfade
-
- tRamp_init(&p->gain, 7.0f, 1);
- tRamp_setVal(&p->gain, 0.f);
-}
-
-void tSampler_free (tSampler* const p)
-{
- leaf_free(p->samp);
- leaf_free(p);
-}
-
-float tSampler_tick (tSampler* const p)
-{
- if (p->active == 0 || (p->len < 4)) return 0.f;
-
- float sample = 0.f;
- float cfxsample = 0.f;
- int numsamps;
- float g1 = 1.f, g2 = 0.f;
-
- float* buff = p->samp->buff;
-
- int dir = p->bnf * p->dir * p->flip;
-
+//==============================================================================
+
+void tBuffer_init (tBuffer* const s, uint32_t length)
+{
+ s->buff = (float*) leaf_alloc( sizeof(float) * length);
+
+
+ s->length = length;
+ s->active = 0;
+ s->idx = 0;
+ s->mode = RecordOneShot;
+
+ tBuffer_clear(s);
+}
+
+void tBuffer_free (tBuffer* const s)
+{
+ leaf_free(s->buff);
+ leaf_free(s);
+}
+
+void tBuffer_tick (tBuffer* const s, float sample)
+{
+ if (s->active == 1)
+ {
+ s->buff[s->idx] = sample;
+
+ s->idx += 1;
+
+ if (s->idx >= s->length)
+ {
+ if (s->mode == RecordOneShot)
+ {
+ tBuffer_stop(s);
+ }
+ else if (s->mode == RecordLoop)
+ {
+ s->idx = 0;
+ }
+ }
+ }
+}
+
+void tBuffer_read(tBuffer* const s, float* buff, uint32_t len)
+{
+ for (int i = 0; i < s->length; i++)
+ {
+ if (i < len) s->buff[i] = buff[i];
+ else s->buff[i] = 0.f;
+ }
+}
+
+float tBuffer_get (tBuffer* const s, int idx)
+{
+ if ((idx < 0) || (idx >= s->length)) return 0.f;
+
+ return s->buff[idx];
+}
+
+void tBuffer_record(tBuffer* const s)
+{
+ s->active = 1;
+ s->idx = 0;
+}
+
+void tBuffer_stop(tBuffer* const s)
+{
+ s->active = 0;
+}
+
+void tBuffer_setRecordMode (tBuffer* const s, RecordMode mode)
+{
+ s->mode = mode;
+}
+
+void tBuffer_clear (tBuffer* const s)
+{
+ for (int i = 0; i < s->length; i++)
+ {
+ s->buff[i] = 0.f;
+ }
+}
+
+//================================tSampler=====================================
+
+void tSampler_init (tSampler* const p, tBuffer* s)
+{
+ p->samp = s;
+
+ p->active = 0;
+
+ p->start = 0;
+ p->end = p->samp->length - 1;
+
+ p->len = p->end - p->start;
+
+ p->idx = 0.f;
+ p->inc = 1.f;
+ p->iinc = 1.f;
+
+ p->dir = 1;
+ p->flip = 1;
+ p->bnf = 1;
+
+ p->mode = Normal;
+
+ p->cfxlen = 300; // default 300 sample crossfade
+
+ tRamp_init(&p->gain, 7.0f, 1);
+ tRamp_setVal(&p->gain, 0.f);
+}
+
+void tSampler_free (tSampler* const p)
+{
+ leaf_free(p->samp);
+ leaf_free(p);
+}
+
+float tSampler_tick (tSampler* const p)
+{
+ if (p->active == 0 || (p->len < 4)) return 0.f;
+
+ float sample = 0.f;
+ float cfxsample = 0.f;
+ int numsamps;
+ float g1 = 1.f, g2 = 0.f;
+
+ float* buff = p->samp->buff;
+
+ int dir = p->bnf * p->dir * p->flip;
+
int idx;
float alpha;
-
- if (dir > 0)
- {
+
+ if (dir > 0)
+ {
idx = (int) p->idx;
alpha = p->idx - idx;
- }
- else
- {
- idx = (int) (p->idx + 1.f); // we think this is because flooring on int works different when reading backwards
- alpha = (p->idx+1.f) - idx;
- }
-
- int32_t start = p->start, end = p->end;
- if (p->flip < 0)
- {
- start = p->end;
- end = p->start;
- }
-
- // Check dir (direction) to interpolate properly
- if (dir > 0)
- {
- // FORWARD NORMAL SAMPLE
- int i1 = idx-1;
- int i3 = idx+1;
- int i4 = idx+2;
-
- sample = LEAF_interpolate_hermite (buff[i1],
- buff[idx],
- buff[i3],
- buff[i4],
- alpha);
-
- // num samples to end of loop
- numsamps = (dir > 0) ? (end - idx) : (idx - start);
- numsamps *= p->iinc;
-
- if (p->mode == Loop)
- {
- if (numsamps <= p->cfxlen)
- {
- // CROSSFADE SAMPLE
- float idxx = p->idx - p->len;
- int cdx = (int)(idxx);
-
- i1 = cdx-1;
- i3 = cdx+1;
- i4 = cdx+2;
-
- cfxsample = LEAF_interpolate_hermite (buff[i1],
- buff[cdx],
- buff[i3],
- buff[i4],
- alpha);
-
- g2 = (float) (p->cfxlen - numsamps) / (float) p->cfxlen;
- }
- }
- }
- else
- {
- // REVERSE
- int i1 = idx+1;
- int i3 = idx-1;
- int i4 = idx-2;
-
- sample = LEAF_interpolate_hermite (buff[i1],
- buff[idx],
- buff[i3],
- buff[i4],
- 1.0f-alpha);
-
- numsamps = (idx - start) / p->inc;
-
- if (p->mode == Loop)
- {
- if (numsamps <= p->cfxlen)
- {
- // CROSSFADE SAMPLE
- float idxx = p->idx + p->len + 1.f;
- int cdx = (int)(idxx);
- alpha = idxx - cdx;
-
- i1 = cdx+1;
- i3 = cdx-1;
- i4 = cdx-2;
-
- cfxsample = LEAF_interpolate_hermite (buff[i1],
- buff[cdx],
- buff[i3],
- buff[i4],
- 1.f-alpha);
-
- g2 = (float) (p->cfxlen - numsamps) / (float) p->cfxlen;
- }
- }
- }
-
- p->idx += (dir * p->inc);
-
- if (p->mode == Normal)
- {
- if (numsamps < (0.007f * leaf.sampleRate))
- {
- tRamp_setDest(&p->gain, 0.f);
- p->active = -1;
- }
- }
- else if (p->mode == Loop ) // == Normal or Loop
- {
- if (idx <= start)
- {
- p->idx += (float)(p->len);
- }
- else if (idx >= end)
- {
- p->idx -= (float)(p->len);
- }
- }
- else // == BackAndForth
- {
- if (p->idx < start)
- {
- p->bnf = -p->bnf;
- p->idx = start;
- }
- else if (p->idx > end)
- {
- p->bnf = -p->bnf;
- p->idx = end;
- }
- }
-
- g1 = 1.f - g2;
-
- sample = sample * g1 + cfxsample * g2;
-
- sample = sample * tRamp_tick(&p->gain);
-
- if (p->active < 0)
- {
- if (tRamp_sample(&p->gain) <= 0.00001f)
- {
- if (p->retrigger == 1)
- {
- p->active = 1;
- p->retrigger = 0;
- tRamp_setDest(&p->gain, 1.f);
-
- if (p->dir > 0)
- {
- if (p->flip > 0) p->idx = p->start;
- else p->idx = p->end;
- }
- else
- {
- if (p->flip > 0) p->idx = p->end;
- else p->idx = p->start;
- }
- }
- else
- {
- p->active = 0;
- }
-
- }
- }
-
- return sample;
-}
-
-void tSampler_setSample (tSampler* const p, tBuffer* s)
-{
- p->samp = s;
-}
-
-void tSampler_setMode (tSampler* const p, Mode mode)
-{
- p->mode = mode;
-}
-
-void tSampler_setCrossfadeLength (tSampler* const p, uint32_t length)
-{
- uint32_t cfxlen = LEAF_clip(0, length, 1000);
-
- //if (cfxlen > p->len) cfxlen = p->len * 0.25f;
-
- p->cfxlen = cfxlen;
-}
-
-void tSampler_play (tSampler* const p)
-{
- if (p->active != 0)
- {
- p->active = -1;
- p->retrigger = 1;
-
- tRamp_setDest(&p->gain, 0.f);
- }
- else
- {
- p->active = 1;
- p->retrigger = 0;
-
- tRamp_setDest(&p->gain, 1.f);
-
- if (p->dir > 0)
- {
- if (p->flip > 0) p->idx = p->start;
- else p->idx = p->end;
- }
- else
- {
- if (p->flip > 0) p->idx = p->end;
- else p->idx = p->start;
- }
- }
-}
-
-void tSampler_stop (tSampler* const p)
-{
- p->active = -1;
-
- tRamp_setDest(&p->gain, 0.f);
-}
-
-static void handleStartEndChange(tSampler* const p)
-{
- p->len = abs(p->end - p->start);
-
- //if (p->len < p->cfxlen) p->cfxlen = p->len * 0.9f;
-
- if (p->start > p->end)
- {
- p->flip = -1;
- }
- else
- {
- p->flip = 1;
- }
-}
-
-void tSampler_setStart (tSampler* const p, int32_t start)
-{
- p->start = LEAF_clipInt(0, start, (p->samp->length - 1));
-
- handleStartEndChange(p);
-}
-
-void tSampler_setEnd (tSampler* const p, int32_t end)
-{
- p->end = LEAF_clipInt(0, end, (p->samp->length - 1));
-
- handleStartEndChange(p);
-}
-
-void tSampler_setRate (tSampler* const p, float rate)
-{
- if (rate < 0.f)
- {
- rate = -rate;
- p->dir = -1;
- }
- else
- {
- p->dir = 1;
- }
-
- p->inc = LEAF_clip(0.f, rate, 8.0f);
- p->iinc = 1.f / p->inc;
-}
-
-
+ }
+ else
+ {
+ idx = (int) (p->idx + 1.f); // we think this is because flooring on int works different when reading backwards
+ alpha = (p->idx+1.f) - idx;
+ }
+
+ int32_t start = p->start, end = p->end;
+ if (p->flip < 0)
+ {
+ start = p->end;
+ end = p->start;
+ }
+
+ // Check dir (direction) to interpolate properly
+ if (dir > 0)
+ {
+ // FORWARD NORMAL SAMPLE
+ int i1 = idx-1;
+ int i3 = idx+1;
+ int i4 = idx+2;
+
+ sample = LEAF_interpolate_hermite (buff[i1],
+ buff[idx],
+ buff[i3],
+ buff[i4],
+ alpha);
+
+ // num samples to end of loop
+ numsamps = (dir > 0) ? (end - idx) : (idx - start);
+ numsamps *= p->iinc;
+
+ if (p->mode == Loop)
+ {
+ if (numsamps <= p->cfxlen)
+ {
+ // CROSSFADE SAMPLE
+ float idxx = p->idx - p->len;
+ int cdx = (int)(idxx);
+
+ i1 = cdx-1;
+ i3 = cdx+1;
+ i4 = cdx+2;
+
+ cfxsample = LEAF_interpolate_hermite (buff[i1],
+ buff[cdx],
+ buff[i3],
+ buff[i4],
+ alpha);
+
+ g2 = (float) (p->cfxlen - numsamps) / (float) p->cfxlen;
+ }
+ }
+ }
+ else
+ {
+ // REVERSE
+ int i1 = idx+1;
+ int i3 = idx-1;
+ int i4 = idx-2;
+
+ sample = LEAF_interpolate_hermite (buff[i1],
+ buff[idx],
+ buff[i3],
+ buff[i4],
+ 1.0f-alpha);
+
+ numsamps = (idx - start) / p->inc;
+
+ if (p->mode == Loop)
+ {
+ if (numsamps <= p->cfxlen)
+ {
+ // CROSSFADE SAMPLE
+ float idxx = p->idx + p->len + 1.f;
+ int cdx = (int)(idxx);
+ alpha = idxx - cdx;
+
+ i1 = cdx+1;
+ i3 = cdx-1;
+ i4 = cdx-2;
+
+ cfxsample = LEAF_interpolate_hermite (buff[i1],
+ buff[cdx],
+ buff[i3],
+ buff[i4],
+ 1.f-alpha);
+
+ g2 = (float) (p->cfxlen - numsamps) / (float) p->cfxlen;
+ }
+ }
+ }
+
+ p->idx += (dir * p->inc);
+
+ if (p->mode == Normal)
+ {
+ if (numsamps < (0.007f * leaf.sampleRate))
+ {
+ tRamp_setDest(&p->gain, 0.f);
+ p->active = -1;
+ }
+ }
+ else if (p->mode == Loop ) // == Normal or Loop
+ {
+ if (idx <= start)
+ {
+ p->idx += (float)(p->len);
+ }
+ else if (idx >= end)
+ {
+ p->idx -= (float)(p->len);
+ }
+ }
+ else // == BackAndForth
+ {
+ if (p->idx < start)
+ {
+ p->bnf = -p->bnf;
+ p->idx = start;
+ }
+ else if (p->idx > end)
+ {
+ p->bnf = -p->bnf;
+ p->idx = end;
+ }
+ }
+
+ g1 = 1.f - g2;
+
+ sample = sample * g1 + cfxsample * g2;
+
+ sample = sample * tRamp_tick(&p->gain);
+
+ if (p->active < 0)
+ {
+ if (tRamp_sample(&p->gain) <= 0.00001f)
+ {
+ if (p->retrigger == 1)
+ {
+ p->active = 1;
+ p->retrigger = 0;
+ tRamp_setDest(&p->gain, 1.f);
+
+ if (p->dir > 0)
+ {
+ if (p->flip > 0) p->idx = p->start;
+ else p->idx = p->end;
+ }
+ else
+ {
+ if (p->flip > 0) p->idx = p->end;
+ else p->idx = p->start;
+ }
+ }
+ else
+ {
+ p->active = 0;
+ }
+
+ }
+ }
+
+ return sample;
+}
+
+void tSampler_setSample (tSampler* const p, tBuffer* s)
+{
+ p->samp = s;
+}
+
+void tSampler_setMode (tSampler* const p, Mode mode)
+{
+ p->mode = mode;
+}
+
+void tSampler_setCrossfadeLength (tSampler* const p, uint32_t length)
+{
+ uint32_t cfxlen = LEAF_clip(0, length, 1000);
+
+ //if (cfxlen > p->len) cfxlen = p->len * 0.25f;
+
+ p->cfxlen = cfxlen;
+}
+
+void tSampler_play (tSampler* const p)
+{
+ if (p->active != 0)
+ {
+ p->active = -1;
+ p->retrigger = 1;
+
+ tRamp_setDest(&p->gain, 0.f);
+ }
+ else
+ {
+ p->active = 1;
+ p->retrigger = 0;
+
+ tRamp_setDest(&p->gain, 1.f);
+
+ if (p->dir > 0)
+ {
+ if (p->flip > 0) p->idx = p->start;
+ else p->idx = p->end;
+ }
+ else
+ {
+ if (p->flip > 0) p->idx = p->end;
+ else p->idx = p->start;
+ }
+ }
+}
+
+void tSampler_stop (tSampler* const p)
+{
+ p->active = -1;
+
+ tRamp_setDest(&p->gain, 0.f);
+}
+
+static void handleStartEndChange(tSampler* const p)
+{
+ p->len = abs(p->end - p->start);
+
+ //if (p->len < p->cfxlen) p->cfxlen = p->len * 0.9f;
+
+ if (p->start > p->end)
+ {
+ p->flip = -1;
+ }
+ else
+ {
+ p->flip = 1;
+ }
+}
+
+void tSampler_setStart (tSampler* const p, int32_t start)
+{
+ p->start = LEAF_clipInt(0, start, (p->samp->length - 1));
+
+ handleStartEndChange(p);
+}
+
+void tSampler_setEnd (tSampler* const p, int32_t end)
+{
+ p->end = LEAF_clipInt(0, end, (p->samp->length - 1));
+
+ handleStartEndChange(p);
+}
+
+void tSampler_setRate (tSampler* const p, float rate)
+{
+ if (rate < 0.f)
+ {
+ rate = -rate;
+ p->dir = -1;
+ }
+ else
+ {
+ p->dir = 1;
+ }
+
+ p->inc = LEAF_clip(0.f, rate, 8.0f);
+ p->iinc = 1.f / p->inc;
+}
+
+
//==============================================================================
--- a/LEAF/Src/leaf-string.c
+++ b/LEAF/Src/leaf-string.c
@@ -1,12 +1,10 @@
-/*
- ==============================================================================
+/*==============================================================================
- leaf-string.cpp
+ leaf-string.c
Created: 30 Nov 2018 10:41:42am
Author: airship
- ==============================================================================
-*/
+==============================================================================*/
#if _WIN32 || _WIN64
--- a/LEAF/Src/leaf-utilities.c
+++ b/LEAF/Src/leaf-utilities.c
@@ -1,12 +1,10 @@
-/*
- ==============================================================================
+/*==============================================================================
- LEAFUtilities.c
+ leaf-utilities.c
Created: 20 Jan 2017 12:02:17pm
Author: Michael R Mulshine
- ==============================================================================
-*/
+==============================================================================*/
#if _WIN32 || _WIN64
--- a/LEAF/Src/leaf-vocoder.c
+++ b/LEAF/Src/leaf-vocoder.c
@@ -1,12 +1,10 @@
-/*
- ==============================================================================
+/*==============================================================================
- LEAFInstrument.c
+ leaf-vocoder.c
Created: 20 Jan 2017 12:01:54pm
Author: Michael R Mulshine
- ==============================================================================
-*/
+==============================================================================*/
#if _WIN32 || _WIN64
--- a/LEAF/Src/leaf-wavefolder.c
+++ b/LEAF/Src/leaf-wavefolder.c
@@ -1,12 +1,10 @@
-/*
- ==============================================================================
+/*==============================================================================
- leaf-wavefolder.cpp
+ leaf-wavefolder.c
Created: 30 Nov 2018 11:56:49am
Author: airship
- ==============================================================================
-*/
+==============================================================================*/
#if _WIN32 || _WIN64
--- a/LEAF/leaf.h
+++ b/LEAF/leaf.h
@@ -32,7 +32,8 @@
#include ".\Inc\leaf-pitch.h"
#include ".\Inc\leaf-formant.h"
#include ".\Inc\leaf-midi.h"
-#include ".\Inc\leaf-sample.h"
+#include ".\Inc\leaf-sample.h"
+#include ".\Inc\leaf-crusher.h"
#include ".\Inc\leaf-wavefolder.h"
#include ".\Inc\leaf-wavetables.h"
@@ -51,7 +52,8 @@
#include "./Inc/leaf-pitch.h"
#include "./Inc/leaf-formant.h"
#include "./Inc/leaf-midi.h"
-#include "./Inc/leaf-sample.h"
+#include "./Inc/leaf-sample.h"
+#include "./Inc/leaf-crusher.h"
#include "./Inc/leaf-wavefolder.h"
#include "./Inc/leaf-wavetables.h"
--- a/LEAF_JUCEPlugin/LEAF.jucer
+++ b/LEAF_JUCEPlugin/LEAF.jucer
@@ -40,6 +40,7 @@
file="../LEAF/Inc/leaf-utilities.h"/>
<FILE id="Szb5LP" name="leaf-vocoder.h" compile="0" resource="0" file="../LEAF/Inc/leaf-vocoder.h"/>
<FILE id="T6KXi7" name="leaf-sample.h" compile="0" resource="0" file="../LEAF/Inc/leaf-sample.h"/>
+ <FILE id="bpUZCA" name="leaf-crusher.h" compile="0" resource="0" file="../LEAF/Inc/leaf-crusher.h"/>
<FILE id="PRkOp2" name="leaf-wavefolder.h" compile="0" resource="0"
file="../LEAF/Inc/leaf-wavefolder.h"/>
<FILE id="KpGzKv" name="leaf-wavetables.h" compile="0" resource="0"
@@ -62,6 +63,7 @@
file="../LEAF/Src/leaf-utilities.c"/>
<FILE id="u1aLLR" name="leaf-vocoder.c" compile="1" resource="0" file="../LEAF/Src/leaf-vocoder.c"/>
<FILE id="nmtoFJ" name="leaf-sample.c" compile="1" resource="0" file="../LEAF/Src/leaf-sample.c"/>
+ <FILE id="Oymcac" name="leaf-crusher.c" compile="1" resource="0" file="../LEAF/Src/leaf-crusher.c"/>
<FILE id="LVoaGm" name="leaf-wavefolder.c" compile="1" resource="0"
file="../LEAF/Src/leaf-wavefolder.c"/>
<FILE id="HRk07h" name="leaf-wavetables.c" compile="1" resource="0"
--- a/LEAF_JUCEPlugin/Source/LEAFLink.cpp
+++ b/LEAF_JUCEPlugin/Source/LEAFLink.cpp
@@ -15,16 +15,16 @@
std::vector<juce::String> cButtonNames = std::vector<juce::String>
{
- "sample",
- "play"
+
};
std::vector<juce::String> cSliderNames = std::vector<juce::String>
{
- "rate",
- "start",
- "end",
- "cfxlen"
+ "sr",
+ "rnd",
+ "qual",
+ "op",
+ "mix"
};
std::vector<juce::String> cComboBoxNames = std::vector<juce::String>
--- a/LEAF_JUCEPlugin/Source/MyTest.cpp
+++ b/LEAF_JUCEPlugin/Source/MyTest.cpp
@@ -14,24 +14,20 @@
static void leaf_pool_report(void);
static void leaf_pool_dump(void);
-static void run_pool_test(void);
+static void run_pool_test(void);
+
+float mix = 0.f;
+float fx = 1.f;
-tBuffer sample;
-
-tSampler player;
+tCrusher crusher;
void LEAFTest_init (float sampleRate, int blockSize)
{
- LEAF_init(sampleRate, blockSize, &randomNumberGenerator);
-
- tBuffer_init(&sample, leaf.sampleRate * 2);
-
- tSampler_init(&player, &sample);
- tSampler_setMode(&player, Normal);
-
- leaf_pool_report();
-
- tBuffer_record(&sample);
+ LEAF_init(sampleRate, blockSize, &randomNumberGenerator);
+
+ tCrusher_init(&crusher);
+
+ leaf_pool_report();
}
int timer = 0;
@@ -38,53 +34,56 @@
float LEAFTest_tick (float input)
{
- tBuffer_tick(&sample, input);
+ float sample = 0.f;
- return tSampler_tick(&player);
+ sample = (mix * tCrusher_tick(&crusher, input)) + ((1.f - mix) * input);
+
+ return sample;
}
-
+
bool lastState = false, lastPlayState = false;
void LEAFTest_block (void)
-{
- float val = getSliderValue("rate");
+{
+ float val = getSliderValue("mix");
+
+ mix = val;
- float rate = val * 16.0f - 8.0f;
- tSampler_setRate(&player, rate);
- //DBG("rate: " + String(rate));
+ val = getSliderValue("sr");
- val = getSliderValue("start");
- float start = val * sample.length;
- tSampler_setStart(&player, start);
- //DBG("start: " + String(start));
+ tCrusher_setSamplingRatio(&crusher, val * 3.99f + 0.01f);
- val = getSliderValue("end");
- float end = val * sample.length;
- tSampler_setEnd(&player, end);
- //DBG("end: " + String(end));
+ val = getSliderValue("rnd");
- val = getSliderValue("cfxlen");
- uint32_t cfxlen = val * 500;
- tSampler_setCrossfadeLength(&player, cfxlen);
- DBG("cfxlen: " + String(cfxlen));
+ tCrusher_setRound(&crusher, val);
- bool state = getButtonState("sample");
+ val = getSliderValue("qual");
- if (state && !lastState)
- {
- timer = 0;
- tBuffer_record(&sample);
- }
+ tCrusher_setQuality(&crusher, val);
- lastState = state;
+ val = getSliderValue("op");
- state = getButtonState("play");
+ tCrusher_setOperation(&crusher, (int)(val * 8.0f));
- if (state && !lastPlayState)
- {
- tSampler_play(&player);
- }
+ /*
+ float samp = -1.f + 2.f * val;
- lastPlayState = state;
+ union unholy_t bw;
+ bw.f = samp;
+ bw.i = (bw.i | (op << 23));
+
+ DBG(String(samp) + " " + String(bw.f));
+ */
+
+ // rounding test
+ /*
+ val = getSliderValue("rnd");
+
+ float to_rnd = -1.f + 2.f * val;
+
+ float rnd = LEAF_round(to_rnd, 0.3f);
+
+ DBG("to_rnd: " + String(to_rnd) + " rnd: " + String(rnd));
+ */
}
void LEAFTest_controllerInput (int cnum, float cval)
@@ -148,7 +147,7 @@
}
leaf_pool_report();
-
+
DBG("ALLOC BUFFER 2");
size = 25;