shithub: leaf

Download patch

ref: 7b343b9827a89ed1856aff78fd21a4f792a49462
parent: d407705c944d54e7655ae15773af8a2034db048c
author: Matthew Wang <Matthew@nat-oitwireless-inside-vapornet100-10-9-8-255.princeton.edu>
date: Thu Aug 22 10:21:47 EDT 2019

fixed oscillator crash, removed Poly and improved MPoly and renamed to Poly

binary files a/.DS_Store b/.DS_Store differ
binary files a/LEAF/.DS_Store b/LEAF/.DS_Store differ
--- a/LEAF/Inc/leaf-mempool.h
+++ b/LEAF/Inc/leaf-mempool.h
@@ -51,7 +51,7 @@
 //==============================================================================
 
 
-#define MPOOL_POOL_SIZE   50000
+#define MPOOL_POOL_SIZE   500000
 
 #define MPOOL_ALIGN_SIZE (8)
 
--- a/LEAF/Inc/leaf-midi.h
+++ b/LEAF/Inc/leaf-midi.h
@@ -4,16 +4,16 @@
     Created: 30 Nov 2018 11:29:26am
     Author:  airship
 
-==============================================================================*/
-
-#ifndef LEAF_MIDI_H_INCLUDED
-#define LEAF_MIDI_H_INCLUDED
+==============================================================================*/
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+#ifndef LEAF_MIDI_H_INCLUDED
+#define LEAF_MIDI_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
     
-//==============================================================================
+//==============================================================================
     
 #include "leaf-globals.h"
 #include "leaf-math.h"
@@ -20,60 +20,23 @@
 
 #include "leaf-utilities.h"
 
-//==============================================================================
+//==============================================================================
     
-typedef struct _tMidiNote
-{
-    uint8_t pitch;
-    uint8_t velocity;
-    oBool on;
-} tMidiNote;
-
-typedef struct _tMidiNode tMidiNode;
-
-typedef struct _tMidiNode
-{
-    tMidiNode* prev;
-    tMidiNode* next;
-    tMidiNote midiNote;
-    
-} tMidiNode;
-
-//==============================================================================
-    
-/* Polyphonic Handler */
+/* tPoly */
 typedef struct _tPoly
 {
-    tMidiNode midiNodes[128];
-    tMidiNode* onListFirst;
-    tMidiNode* offListFirst;
-    
-} tPoly;
-
-void        tPoly_init(tPoly* const);
-void        tPoly_free(tPoly* const);
-
-tMidiNote*  tPoly_getMidiNote(tPoly* const, int8_t voiceIndex);
-void        tPoly_noteOn(tPoly* poly, int midiNoteNumber, float velocity);
-void        tPoly_noteOff(tPoly* poly, int midiNoteNumber);
-
-//==============================================================================
-    
-/* tMPoly */
-typedef struct _tMPoly
-{
     tStack* stack;
     tStack* orderStack;
     
-    tRamp* ramp[MPOLY_NUM_MAX_VOICES];
-    
-    float rampVals[MPOLY_NUM_MAX_VOICES];
-    uint8_t firstReceived[MPOLY_NUM_MAX_VOICES];
+    tRamp* ramp[POLY_NUM_MAX_VOICES];
+    float rampVals[POLY_NUM_MAX_VOICES];
+    oBool firstReceived[POLY_NUM_MAX_VOICES];
     float glideTime;
+    oBool pitchGlideIsActive;
     
     int numVoices;
     
-    int voices[MPOLY_NUM_MAX_VOICES][2];
+    int voices[POLY_NUM_MAX_VOICES][2];
     
     int notes[128][2];
     
@@ -83,8 +46,8 @@
     
     int lastVoiceToChange;
     
-    int32_t pitchBend;
-    float pitchBendAmount;
+    float pitchBend;
+    tRamp* pitchBendRamp;
     
     int currentNote;
     int currentVoice;
@@ -91,33 +54,38 @@
     int currentVelocity;
     int maxLength;
     
-} tMPoly;
+} tPoly;
 
 /* MPoly*/
-void    tMPoly_init(tMPoly* const, int numVoices);
-void    tMPoly_free(tMPoly* const);
+void    tPoly_init(tPoly* const, int numVoices);
+void    tPoly_free(tPoly* const);
 
-void    tMPoly_tick(tMPoly* const);
-
 //ADDING A NOTE
-int     tMPoly_noteOn(tMPoly* const, int note, uint8_t vel);
-int     tMPoly_noteOff(tMPoly* const, uint8_t note);
-void    tMPoly_orderedAddToStack(tMPoly* const, uint8_t noteVal);
-void    tMPoly_pitchBend(tMPoly* const, int pitchBend);
-void    tMPoly_setNumVoices(tMPoly* const, uint8_t numVoices);
-void    tMPoly_setPitchGlideTime(tMPoly* const, float t);
-int     tMPoly_getNumVoices(tMPoly* const);
-float   tMPoly_getPitch(tMPoly* const, uint8_t voice);
-int     tMPoly_getVelocity(tMPoly* const, uint8_t voice);
-int     tMPoly_isOn(tMPoly* const, uint8_t voice);
+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);
 
-//==============================================================================
-    
-#ifdef __cplusplus
-}
-#endif
-
-#endif // LEAF_MIDI_H_INCLUDED
-
+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
+
+#endif // LEAF_MIDI_H_INCLUDED
+
 //==============================================================================
 
--- a/LEAF/Src/leaf-midi.c
+++ b/LEAF/Src/leaf-midi.c
@@ -16,152 +16,9 @@
 
 #endif
 
-
-/* Poly Handler */
-static void nodeListInit(tPoly* poly)
+// POLY
+void tPoly_init(tPoly* const poly, int numVoices)
 {
-    for (int16_t i = 0; i < 128; i++)
-    {
-        poly->midiNodes[i].midiNote.pitch = i;
-        poly->midiNodes[i].midiNote.velocity = 0;
-        poly->midiNodes[i].midiNote.on = OFALSE;
-    }
-}
-
-// Initially everything is off, init as such
-static void offListInit(tPoly* poly)
-{
-    tMidiNode* prevNode = NULL;
-    tMidiNode* curNode = &poly->midiNodes[0];
-    poly->offListFirst = curNode;
-    
-    for (int16_t i = 1; i < 128; i++)
-    {
-        curNode->prev = prevNode;
-        curNode->next = &poly->midiNodes[i];
-        
-        prevNode = curNode;
-        curNode = &poly->midiNodes[i];
-    }
-    // Set the final node
-    curNode->prev = prevNode;
-    curNode->next = NULL;
-}
-
-static void onListInit(tPoly* poly)
-{
-    poly->onListFirst = NULL;
-}
-
-void    tPoly_init(tPoly* const poly)
-{
-    nodeListInit(poly);
-    offListInit(poly);
-    onListInit(poly);
-}
-
-
-tMidiNote* tPoly_getMidiNote(tPoly* const poly, int8_t voiceIndex)
-{
-    tMidiNote* midiNote = NULL;
-    
-    tMidiNode* currNode = poly->onListFirst;
-    
-    int8_t i = 0;
-    while (i < voiceIndex && currNode != NULL)
-    {
-        currNode = currNode->next;
-        i++;
-    }
-    
-    if (currNode != NULL)
-        midiNote = &(currNode->midiNote);
-    
-    return midiNote;
-}
-
-static void removeNoteFromOffList(tPoly* const poly, int8_t midiNoteNumber)
-{
-    // If this has no prev, this is the first node on the OFF list
-    if (poly->midiNodes[midiNoteNumber].prev == NULL)
-        poly->offListFirst = poly->midiNodes[midiNoteNumber].next;
-    
-    // Awkward handling to avoid deref null pointers
-    if (poly->midiNodes[midiNoteNumber].prev != NULL)
-        poly->midiNodes[midiNoteNumber].prev->next = poly->midiNodes[midiNoteNumber].next;
-    
-    if (poly->midiNodes[midiNoteNumber].next != NULL)
-        poly->midiNodes[midiNoteNumber].next->prev = poly->midiNodes[midiNoteNumber].prev;
-    
-    poly->midiNodes[midiNoteNumber].next = NULL;
-    poly->midiNodes[midiNoteNumber].prev = NULL;
-}
-
-static void prependNoteToOnList(tPoly* poly, int midiNoteNumber)
-{
-    if (poly->onListFirst != NULL)
-    {
-        poly->midiNodes[midiNoteNumber].next = poly->onListFirst;
-        poly->onListFirst->prev = &poly->midiNodes[midiNoteNumber];
-    }
-    poly->onListFirst = &poly->midiNodes[midiNoteNumber];
-}
-
-
-// TODO: Fail gracefully on odd MIDI situations
-//       For example, getting a note off for an already on note and vice-versa
-void tPoly_noteOn(tPoly* const poly, int midiNoteNumber, float velocity)
-{
-    removeNoteFromOffList(poly, midiNoteNumber);
-    // Set the MIDI note on accordingly
-    poly->midiNodes[midiNoteNumber].midiNote.velocity = velocity;
-    poly->midiNodes[midiNoteNumber].midiNote.on = OTRUE;
-    prependNoteToOnList(poly, midiNoteNumber);
-}
-
-// Unfortunately similar code to removeNoteFromOffList without any clear way of factoring out to a helper function
-static void removeNoteFromOnList(tPoly* const poly, int8_t midiNoteNumber)
-{
-    // If this has no prev, this is the first node on the OFF list
-    if (poly->midiNodes[midiNoteNumber].prev == NULL)
-        poly->onListFirst = poly->midiNodes[midiNoteNumber].next;
-    
-    // Awkward handling to avoid deref null pointers
-    if (poly->midiNodes[midiNoteNumber].prev != NULL)
-        poly->midiNodes[midiNoteNumber].prev->next = poly->midiNodes[midiNoteNumber].next;
-    
-    if (poly->midiNodes[midiNoteNumber].next != NULL)
-        poly->midiNodes[midiNoteNumber].next->prev = poly->midiNodes[midiNoteNumber].prev;
-    
-    poly->midiNodes[midiNoteNumber].next = NULL;
-    poly->midiNodes[midiNoteNumber].prev = NULL;
-}
-
-// Unfortunately similar code to prependNoteToOnList without any clear way of factoring out to a helper function
-static void prependNoteToOffList(tPoly* const poly, int midiNoteNumber)
-{
-    if (poly->offListFirst != NULL)
-    {
-        poly->midiNodes[midiNoteNumber].next = poly->offListFirst;
-        poly->offListFirst->prev = &poly->midiNodes[midiNoteNumber];
-    }
-    poly->offListFirst = &poly->midiNodes[midiNoteNumber];
-}
-
-
-void tPoly_noteOff(tPoly* const poly, int midiNoteNumber)
-{
-    removeNoteFromOnList(poly, midiNoteNumber);
-    // Set the MIDI note on accordingly
-    poly->midiNodes[midiNoteNumber].midiNote.velocity = 0;
-    poly->midiNodes[midiNoteNumber].midiNote.on = OFALSE;
-    prependNoteToOffList(poly, midiNoteNumber);
-}
-
-
-// MPOLY
-void tMPoly_init(tMPoly* const poly, int numVoices)
-{
     poly->numVoices = numVoices;
     poly->lastVoiceToChange = 0;
     
@@ -177,50 +34,63 @@
         poly->notes[i][1] = -1;
     }
     
-    for (int i = 0; i < MPOLY_NUM_MAX_VOICES; ++i)
+    poly->glideTime = 5.0f;
+    for (int i = 0; i < POLY_NUM_MAX_VOICES; ++i)
     {
         poly->voices[i][0] = -1;
-        poly->firstReceived[i] = 0;
+        poly->firstReceived[i] = OFALSE;
         
         poly->ramp[i] = (tRamp*) leaf_alloc(sizeof(tRamp));
         
-        tRamp_init(poly->ramp[i], 5.0f, 1);
+        tRamp_init(poly->ramp[i], poly->glideTime, 1);
     }
     
-    poly->glideTime = 5.0f;
+    poly->pitchBend = 0.0f;
+    poly->pitchBendRamp = (tRamp*) leaf_alloc(sizeof(tRamp));
+    tRamp_init(poly->pitchBendRamp, 1.0f, 1);
     
-    poly->pitchBend = 64;
-    poly->pitchBendAmount = 2.0f;
-    
     poly->stack = (tStack*) leaf_alloc(sizeof(tStack));
     tStack_init(poly->stack);
     
     poly->orderStack = (tStack*) leaf_alloc(sizeof(tStack));
     tStack_init(poly->orderStack);
+    
+    poly->pitchGlideIsActive = OFALSE;
 }
 
-// Only needs to be used for pitch glide
-void tMPoly_tick(tMPoly* poly)
+void tPoly_tickPitch(tPoly* poly)
 {
-    for (int i = 0; i < MPOLY_NUM_MAX_VOICES; ++i)
+    tPoly_tickPitchGlide(poly);
+    tPoly_tickPitchBend(poly);
+}
+
+void tPoly_tickPitchGlide(tPoly* poly)
+{
+    for (int i = 0; i < POLY_NUM_MAX_VOICES; ++i)
     {
         tRamp_tick(poly->ramp[i]);
     }
 }
 
+void tPoly_tickPitchBend(tPoly* poly)
+{
+    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 tMPoly_pitchBend(tMPoly* const poly, int pitchBend)
+void tPoly_setPitchBend(tPoly* const poly, float pitchBend)
 {
     poly->pitchBend = pitchBend;
+    tRamp_setDest(poly->pitchBendRamp, poly->pitchBend);
 }
 
-int tMPoly_noteOn(tMPoly* const poly, int note, uint8_t vel)
+int tPoly_noteOn(tPoly* const poly, int note, uint8_t vel)
 {
     // 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
     {
-        tMPoly_orderedAddToStack(poly, note);
+        tPoly_orderedAddToStack(poly, note);
         tStack_add(poly->stack, note);
         
         int alteredVoice = -1;
@@ -229,15 +99,11 @@
         {
             if (poly->voices[i][0] < 0)    // if inactive voice, give this note to voice
             {
-                if (poly->firstReceived[i] == 0)
+                if (!poly->firstReceived[i] || !poly->pitchGlideIsActive)
                 {
-                    tRamp_setVal(poly->ramp[i], note); // can't be 1.0f, causes first note to be off pitch
-                    poly->firstReceived[i] = 1;
+                    tRamp_setVal(poly->ramp[i], note);
+                    poly->firstReceived[i] = OTRUE;
                 }
-                else
-                {
-                    tRamp_setTime(poly->ramp[i], poly->glideTime);
-                }
                 
                 found = OTRUE;
                 
@@ -287,7 +153,7 @@
 
 int16_t noteToTest = -1;
 
-int tMPoly_noteOff(tMPoly* const poly, uint8_t note)
+int tPoly_noteOff(tPoly* const poly, uint8_t note)
 {
     tStack_remove(poly->stack, note);
     tStack_remove(poly->orderStack, note);
@@ -337,7 +203,7 @@
     return deactivatedVoice;
 }
 
-void tMPoly_orderedAddToStack(tMPoly* const poly, uint8_t noteVal)
+void tPoly_orderedAddToStack(tPoly* const poly, uint8_t noteVal)
 {
     
     uint8_t j;
@@ -376,39 +242,46 @@
     
 }
 
-void tMPoly_setNumVoices(tMPoly* const poly, uint8_t numVoices)
+void tPoly_setNumVoices(tPoly* const poly, uint8_t numVoices)
 {
-    poly->numVoices = (numVoices > MPOLY_NUM_MAX_VOICES) ? MPOLY_NUM_MAX_VOICES : numVoices;
+    poly->numVoices = (numVoices > POLY_NUM_MAX_VOICES) ? POLY_NUM_MAX_VOICES : numVoices;
 }
 
-void tMPoly_setPitchGlideTime(tMPoly* const poly, float t)
+void tPoly_setPitchGlideActive(tPoly* const poly, oBool isActive)
 {
-    if (poly->glideTime == t) return;
+    poly->pitchGlideIsActive = isActive;
+}
+
+void tPoly_setPitchGlideTime(tPoly* const poly, float t)
+{
     poly->glideTime = t;
-    for (int i = 0; i < MPOLY_NUM_MAX_VOICES; ++i)
+    for (int i = 0; i < POLY_NUM_MAX_VOICES; ++i)
     {
         tRamp_setTime(poly->ramp[i], poly->glideTime);
     }
 }
 
-int tMPoly_getNumVoices(tMPoly* const poly)
+int tPoly_getNumVoices(tPoly* const poly)
 {
     return poly->numVoices;
 }
 
-float tMPoly_getPitch(tMPoly* const poly, uint8_t voice)
+float tPoly_getPitch(tPoly* const poly, uint8_t voice)
 {
-    //float pitchBend = ((float)(poly->pitchBend - 8192) / 8192.0f) * poly->pitchBendAmount;
-    return tRamp_sample(poly->ramp[voice]);// + pitchBend;
+    return tRamp_sample(poly->ramp[voice]) + tRamp_sample(poly->pitchBendRamp);
+}
+
+int tPoly_getKey(tPoly* const poly, uint8_t voice)
+{
     return poly->voices[voice][0];
 }
 
-int tMPoly_getVelocity(tMPoly* const poly, uint8_t voice)
+int tPoly_getVelocity(tPoly* const poly, uint8_t voice)
 {
     return poly->voices[voice][1];
 }
 
-int tMPoly_isOn(tMPoly* const poly, uint8_t voice)
+int tPoly_isOn(tPoly* const poly, uint8_t voice)
 {
     return (poly->voices[voice][0] > 0) ? 1 : 0;
 }
--- a/LEAF/Src/leaf-oscillator.c
+++ b/LEAF/Src/leaf-oscillator.c
@@ -243,7 +243,7 @@
 {
     // Phasor increment
     c->phase += c->inc;
-    if (c->phase >= 1.0f) c->phase -= 1.0f;
+    while (c->phase >= 1.0f) c->phase -= 1.0f;
     
     // Wavetable synthesis
     float temp = SINE_TABLE_SIZE * c->phase;
@@ -321,7 +321,7 @@
 {
     // Phasor increment
     c->phase += c->inc;
-    if (c->phase >= 1.0f) c->phase -= 1.0f;
+    while (c->phase >= 1.0f) c->phase -= 1.0f;
     
     float out = 0.0f;
     float w;
@@ -428,7 +428,7 @@
 {
     // Phasor increment
     c->phase += c->inc;
-    if (c->phase >= 1.0f) c->phase -= 1.0f;
+    while (c->phase >= 1.0f) c->phase -= 1.0f;
     
     float out = 0.0f;
     float w;
@@ -530,7 +530,7 @@
 {
     // Phasor increment
     c->phase += c->inc;
-    if (c->phase >= 1.0f) c->phase -= 1.0f;
+    while (c->phase >= 1.0f) c->phase -= 1.0f;
     
     float out = 0.0f;
     float w = 0.0f;