ref: 579b819f8416248abe1bda1eb27d14cda3c91b7e
parent: 9179bd92e043cbd585ce50acb0caa7cb96d6fd16
author: mulshine <mulshine@princeton.edu>
date: Fri Feb 15 06:54:19 EST 2019
First viable granular re-synthesiser.
--- a/LEAF/Inc/leaf-crusher.h
+++ b/LEAF/Inc/leaf-crusher.h
@@ -21,37 +21,37 @@
#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, 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 _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.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);
//==============================================================================
--- a/LEAF/Inc/leaf-math.h
+++ b/LEAF/Inc/leaf-math.h
@@ -76,10 +76,10 @@
// Jones shaper
float LEAF_shaper (float input, float m_drive);
-float LEAF_reedTable (float input, float offset, float slope);
-
-float LEAF_reduct (float input, float ratio);
-float LEAF_round (float input, float rnd);
+float LEAF_reedTable (float input, float offset, float slope);
+
+float LEAF_reduct (float input, float ratio);
+float LEAF_round (float input, float rnd);
float LEAF_bitwise_xor(float input, uint32_t op);
float LEAF_clip (float min, float val, float max);
--- a/LEAF/Inc/leaf-mempool.h
+++ b/LEAF/Inc/leaf-mempool.h
@@ -50,7 +50,7 @@
//==============================================================================
-#define MPOOL_POOL_SIZE 500000
+#define MPOOL_POOL_SIZE 3000000
#define MPOOL_ALIGN_SIZE (8)
//#define size_t unsigned long
--- a/LEAF/Inc/leaf-sample.h
+++ b/LEAF/Inc/leaf-sample.h
@@ -61,13 +61,13 @@
//==============================================================================
- typedef enum Mode
+ typedef enum PlayMode
{
- Normal,
- Loop,
- BackAndForth,
- SampleModeNil
- } Mode;
+ PlayNormal,
+ PlayLoop,
+ PlayBackAndForth,
+ PlayModeNil
+ } PlayMode;
typedef struct _tSampler
{
@@ -87,7 +87,7 @@
uint32_t len;
uint32_t cfxlen;
- Mode mode;
+ PlayMode mode;
int retrigger;
int active;
@@ -101,7 +101,7 @@
void tSampler_setSample (tSampler* const, tBuffer* s);
- void tSampler_setMode (tSampler* const, Mode mode);
+ void tSampler_setMode (tSampler* const, PlayMode mode);
void tSampler_play (tSampler* const);
void tSampler_stop (tSampler* const);
--- a/LEAF/Src/leaf-crusher.c
+++ b/LEAF/Src/leaf-crusher.c
@@ -6,79 +6,79 @@
==============================================================================*/
-#if _WIN32 || _WIN64
-
-#include "..\Inc\leaf-crusher.h"
-
-#else
-
-#include "../Inc/leaf-crusher.h"
-
-#endif
+#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 = (int32_t) sample;
-
- sample /= c->div;
-
- sample = LEAF_bitwise_xor(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, float op)
+
+#define SCALAR 5000.f
+
+void tCrusher_init (tCrusher* const c)
{
- c->op = (uint32_t) (op * 8.0f);
-}
-
-// 0.0 - 1.0
-void tCrusher_setQuality (tCrusher* const c, float val)
+ 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)
{
- 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;
+ leaf_free(c);
+}
+
+float tCrusher_tick (tCrusher* const c, float input)
+{
+ float sample = input;
+
+ sample *= SCALAR; // SCALAR is 5000 by default
+
+ sample = (int32_t) sample;
+
+ sample /= c->div;
+
+ sample = LEAF_bitwise_xor(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, float op)
+{
+ c->op = (uint32_t) (op * 8.0f);
+}
+
+// 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-sample.c
+++ b/LEAF/Src/leaf-sample.c
@@ -125,9 +125,9 @@
p->flip = 1;
p->bnf = 1;
- p->mode = Normal;
+ p->mode = PlayNormal;
- p->cfxlen = 300; // default 300 sample crossfade
+ p->cfxlen = 500; // default 300 sample crossfade
tRamp_init(&p->gain, 7.0f, 1);
tRamp_setVal(&p->gain, 0.f);
@@ -191,7 +191,7 @@
numsamps = (dir > 0) ? (end - idx) : (idx - start);
numsamps *= p->iinc;
- if (p->mode == Loop)
+ if (p->mode == PlayLoop)
{
if (numsamps <= p->cfxlen)
{
@@ -228,7 +228,7 @@
numsamps = (idx - start) / p->inc;
- if (p->mode == Loop)
+ if (p->mode == PlayLoop)
{
if (numsamps <= p->cfxlen)
{
@@ -254,7 +254,7 @@
p->idx += (dir * p->inc);
- if (p->mode == Normal)
+ if (p->mode == PlayNormal)
{
if (numsamps < (0.007f * leaf.sampleRate))
{
@@ -262,7 +262,7 @@
p->active = -1;
}
}
- else if (p->mode == Loop ) // == Normal or Loop
+ else if (p->mode == PlayLoop )
{
if (idx <= start)
{
@@ -273,7 +273,7 @@
p->idx -= (float)(p->len);
}
}
- else // == BackAndForth
+ else // == PlayBackAndForth
{
if (p->idx < start)
{
@@ -330,7 +330,7 @@
p->samp = s;
}
-void tSampler_setMode (tSampler* const p, Mode mode)
+void tSampler_setMode (tSampler* const p, PlayMode mode)
{
p->mode = mode;
}
--- a/LEAF_JUCEPlugin/Source/LEAFLink.cpp
+++ b/LEAF_JUCEPlugin/Source/LEAFLink.cpp
@@ -20,10 +20,8 @@
std::vector<juce::String> cSliderNames = std::vector<juce::String>
{
- "sr",
- "rnd",
- "qual",
- "op",
+ "delay",
+ "feedback",
"mix"
};
@@ -139,7 +137,7 @@
return value;
}
-float randomNumberGenerator(void)
+float getRandomFloat(void)
{
return ((float)rand()/RAND_MAX);
}
--- a/LEAF_JUCEPlugin/Source/LEAFLink.h
+++ b/LEAF_JUCEPlugin/Source/LEAFLink.h
@@ -47,6 +47,6 @@
void setSliderModelValue(String name, float val);
void setSliderValue(String name, float val);
float getSliderValue(String name);
-float randomNumberGenerator(void);
+float getRandomFloat(void);
#endif // UTILITIES_H_INCLUDED
--- a/LEAF_JUCEPlugin/Source/MyTest.cpp
+++ b/LEAF_JUCEPlugin/Source/MyTest.cpp
@@ -16,29 +16,75 @@
static void leaf_pool_dump(void);
static void run_pool_test(void);
-float mix = 0.f;
-float fx = 1.f;
-
-tCrusher crusher;
+float mix = 0.f;
+float fx = 1.f;
+#define NUM_GRAINS 20
+
+tBuffer buff;
+tSampler samp[NUM_GRAINS];
+
+tTapeDelay delay;
+
+float feedback = 0.f;
+
+
void LEAFTest_init (float sampleRate, int blockSize)
{
- LEAF_init(sampleRate, blockSize, &randomNumberGenerator);
-
- tCrusher_init(&crusher);
+ LEAF_init(sampleRate, blockSize, &getRandomFloat);
+ // Init and set record loop
+ tBuffer_init (&buff, leaf.sampleRate * 1.f); // 0.5-second buffers
+ tBuffer_setRecordMode (&buff, RecordLoop);
+ tBuffer_record(&buff);
+
+ for (int i = 0; i < NUM_GRAINS; i++)
+ {
+ // Init and set play loop
+ tSampler_init (&samp[i], &buff);
+ tSampler_setMode (&samp[i], PlayLoop);
+
+ /*
+ float speed = ((getRandomFloat() < 0.5f) ? 0.5f : 1.f);
+ float dir = (getRandomFloat() < 0.5f) ? -1 : 1;
+
+ tSampler_setRate(&samp[i], speed * dir);
+ */
+
+ tSampler_setRate(&samp[i], 1.f);
+
+ // Record and play
+ tSampler_play(&samp[i]);
+ }
+
+ tTapeDelay_init(&delay, leaf.sampleRate * 0.05f, leaf.sampleRate * 1.f); // 1 second delay, starts out at 50 ms
+
leaf_pool_report();
}
int timer = 0;
+float lastOut;
+
float LEAFTest_tick (float input)
-{
- float sample = 0.f;
-
- sample = (mix * tCrusher_tick(&crusher, input)) + ((1.f - mix) * input);
+{
+ float sample = 0.f;
- return sample;
+ tBuffer_tick(&buff, input);
+
+ for (int i = 0; i < NUM_GRAINS; i++)
+ {
+ sample += tSampler_tick(&samp[i]);
+ }
+
+ sample /= NUM_GRAINS;
+
+ sample = tTapeDelay_tick(&delay, (1.f - feedback) * sample + feedback * lastOut);
+
+ lastOut = sample;
+
+ return (sample * mix) +
+ (input * (1.f - mix));
}
bool lastState = false, lastPlayState = false;
@@ -46,44 +92,28 @@
{
float val = getSliderValue("mix");
- mix = val;
+ mix = val;
+
+ val = getSliderValue("delay");
+
+ tTapeDelay_setDelay(&delay, val * leaf.sampleRate);
+
+ val = getSliderValue("feedback");
+
+ feedback = val;
- val = getSliderValue("sr");
-
- tCrusher_setSamplingRatio(&crusher, val * 3.99f + 0.01f);
-
- val = getSliderValue("rnd");
-
- tCrusher_setRound(&crusher, val);
-
- val = getSliderValue("qual");
-
- tCrusher_setQuality(&crusher, val);
-
- val = getSliderValue("op");
-
- tCrusher_setOperation(&crusher, val);
-
- /*
- float samp = -1.f + 2.f * val;
-
- 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));
- */
+ for (int i = 0; i < NUM_GRAINS; i++)
+ {
+ if (getRandomFloat() < 0.01f)
+ {
+ tSampler_setStart(&samp[i], leaf.sampleRate * 0.05f + leaf.sampleRate * getRandomFloat() * 0.95f);
+
+ uint64_t end = (leaf.sampleRate * 0.05f + getRandomFloat() * leaf.sampleRate * 0.45f + samp[i].start);
+
+ tSampler_setEnd(&samp[i], end % buff.length); // 10 - 1010 ms
+ }
+ }
+
}
void LEAFTest_controllerInput (int cnum, float cval)