shithub: leaf

Download patch

ref: a45c028fd591d15d011fff515a6c022c5cc62359
parent: 19e38692f2280878603bfb5dc6c562791667da2e
author: Davis Polito <davispolito1@gmail.com>
date: Tue Apr 12 12:13:20 EDT 2022

Add Gain and BW fixes for electrobass

--- a/leaf/Inc/leaf-filters.h
+++ b/leaf/Inc/leaf-filters.h
@@ -1070,6 +1070,7 @@
     void    tVZFilter_setResonance                (tVZFilter* const vf, float res);
     void    tVZFilter_setFrequencyAndResonance (tVZFilter* const vf, float freq, float res);
     void    tVZFilter_setFrequencyAndResonanceAndGain (tVZFilter* const vf, float freq, float res, float gains);
+    void    tVZFilter_setFrequencyAndBandwidthAndGain (tVZFilter* const vf, float freq, float BW, float gain);
     void    tVZFilter_setFrequencyAndResonanceAndMorph (tVZFilter* const vf, float freq, float res, float morph);
     void    tVZFilter_setMorphOnly               (tVZFilter* const vf, float morph);
     void    tVZFilter_setMorph               (tVZFilter* const vf, float morph);
--- /dev/null
+++ b/leaf/Inc/leaf-midi copy.h
@@ -1,0 +1,443 @@
+/*==============================================================================
+ 
+ leaf-midi.h
+ Created: 30 Nov 2018 11:29:26am
+ Author:  airship
+ 
+ ==============================================================================*/
+
+#ifndef LEAF_MIDI_H_INCLUDED
+#define LEAF_MIDI_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+    
+    //==============================================================================
+    
+#include "leaf-global.h"
+#include "leaf-mempool.h"
+#include "leaf-math.h"
+#include "leaf-envelopes.h"
+    
+    /*!
+     * @internal
+     * Header.
+     * @include basic-oscillators.h
+     * @example basic-oscillators.c
+     * An example.
+     */
+    
+    //==============================================================================
+    
+    // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
+    /*!
+     @defgroup tstack tStack
+     @ingroup midi
+     @brief A basic stack of integers with a fixed capacity of 128, used by tPoly to keep track of MIDI notes.
+     @{
+     
+     @fn void    tStack_init                 (tStack* const stack, LEAF* const leaf)
+     @brief Initialize a tStack to the default mempool of a LEAF instance.
+     @param stack A pointer to the tStack to initialize.
+     @param leaf A pointer to the leaf instance.
+     
+     @fn void    tStack_initToPool           (tStack* const stack, tMempool* const mempool)
+     @brief Initialize a tStack to a specified mempool.
+     @param stack A pointer to the tStack to initialize.
+     @param mempool A pointer to the tMempool to use.
+     
+     @fn void    tStack_free                 (tStack* const stack)
+     @brief Free a tStack from its mempool.
+     @param stack A pointer to the tStack to free.
+     
+     @fn void    tStack_setCapacity          (tStack* const stack, uint16_t cap)
+     @brief Set the capacity of the stack.
+     @param stack A pointer to the relevant tStack.
+     @param cap The new capacity.
+     
+     @fn int     tStack_addIfNotAlreadyThere (tStack* const stack, uint16_t item)
+     @brief Add a value to the stack only if that value is not already in the stack.
+     @param stack A pointer to the relevant tStack.
+     @param item The value to be added.
+     
+     @fn void    tStack_add                  (tStack* const stack, uint16_t item)
+     @brief Add a value to the stack.
+     @param stack A pointer to the relevant tStack.
+     @param item The value to be added.
+     
+     @fn int     tStack_remove               (tStack* const stack, uint16_t item)
+     @brief Remove a single instance of a value from the stack.
+     @param stack A pointer to the relevant tStack.
+     @param item The value to be removed.
+     
+     @fn void    tStack_clear                (tStack* const stack)
+     @brief Clear the stack.
+     @param stack A pointer to the relevant tStack.
+     
+     @fn int     tStack_first                (tStack* const stack)
+     @brief Get the first value in the stack.
+     @param stack A pointer to the relevant tStack.
+     @return The first value in the stack.
+     
+     @fn int     tStack_getSize              (tStack* const stack)
+     @brief Get the current size of the stack.
+     @param stack A pointer to the relevant tStack.
+     @return The current size of the stack.
+     
+     @fn int     tStack_contains             (tStack* const stack, uint16_t item)
+     @brief Check if the stack contains a value, and if it does, get the index of that value.
+     @param stack A pointer to the relevant tStack.
+     @param item The value to check against the stack.
+     @return The index of the value or -1 if the stack does not contain the value.
+     
+     @fn int     tStack_next                 (tStack* const stack)
+     @brief Get the next value in the stack, starting from the earliest added values.
+     @param stack A pointer to the relevant tStack.
+     @return The next value in the stack or -1 if there are no values in the stack.
+     
+     @fn int     tStack_get                  (tStack* const stack, int index)
+     @brief Get the value at a given index of the stack.
+     @param stack A pointer to the relevant tStack.
+     @param index The index of the stack from which to get a value.
+     @return The value at the given index.
+     
+     @} */
+    
+#define STACK_SIZE 128
+    typedef struct _tStack
+    {
+        
+        tMempool mempool;
+        int data[STACK_SIZE];
+        uint16_t pos;
+        uint16_t size;
+        uint16_t capacity;
+        int ordered;
+    } _tStack;
+    
+    typedef _tStack* tStack;
+    
+    void    tStack_init                 (tStack* const stack, LEAF* const leaf);
+    void    tStack_initToPool           (tStack* const stack, tMempool* const pool);
+    void    tStack_free                 (tStack* const stack);
+    
+    void    tStack_setCapacity          (tStack* const stack, uint16_t cap);
+    int     tStack_addIfNotAlreadyThere (tStack* const stack, uint16_t item);
+    void    tStack_add                  (tStack* const stack, uint16_t item);
+    int     tStack_remove               (tStack* const stack, uint16_t item);
+    void    tStack_clear                (tStack* const stack);
+    int     tStack_first                (tStack* const stack);
+    int     tStack_getSize              (tStack* const stack);
+    int     tStack_contains             (tStack* const stack, uint16_t item);
+    int     tStack_next                 (tStack* const stack);
+    int     tStack_get                  (tStack* const stack, int index);
+    
+    /*! @} 
+     @defgroup tpoly tPoly
+     @ingroup midi
+     @brief Polyphony handler with glide and pitch bend options.
+     @{
+     
+     @fn void    tPoly_init                  (tPoly* const poly, int maxNumVoices, LEAF* const leaf)
+     @brief Initialize a tPoly to the default mempool of a LEAF instance.
+     @param poly A pointer to the tPoly to initialize.
+     @param maxNumVoices The maximum number of voices this tPoly can handle at once.
+     @param leaf A pointer to the leaf instance.
+     
+     @fn void    tPoly_initToPool            (tPoly* const poly, int maxNumVoices, tMempool* const pool)
+     @brief Initialize a tPoly to a specified mempool.
+     @param poly A pointer to the tPoly to initialize.
+     @param mempool A pointer to the tMempool to use.
+     
+     @fn void    tPoly_free                  (tPoly* const poly)
+     @brief Free a tPoly from its mempool.
+     @param poly A pointer to the tPoly to free.
+     
+     @fn int     tPoly_noteOn                (tPoly* const poly, int note, uint8_t vel)
+     @brief Add a note with a given velocity to the poly handler.
+     @param poly A pointer to the relevant tPoly.
+     @param note The MIDI note number to add.
+     @param vel The MIDI velocity of the note to add.
+     @return The voice that will play the note.
+     
+     @fn int     tPoly_noteOff               (tPoly* const poly, uint8_t note)
+     @brief Remove a note from the poly handler.
+     @param poly A pointer to the relevant tPoly.
+     @param note The MIDI note number to remove.
+     @return The voice that was playing the removed note.
+     
+     @fn void    tPoly_orderedAddToStack     (tPoly* const poly, uint8_t note)
+     @brief
+     @param
+     
+     @fn void    tPoly_setNumVoices          (tPoly* const poly, uint8_t numVoices)
+     @brief Set the number of voices available to play notes.
+     @param poly A pointer to the relevant tPoly.
+     @param numVoices The new number of available voices. Cannot be greater than the max number voices given in tPoly_init().
+     
+     @fn void    tPoly_setPitchGlideActive   (tPoly* const poly, int isActive)
+     @brief Set whether pitch glide over note changes in voices is active.
+     @param poly A pointer to the relevant tPoly.
+     @param isActive Whether pitch glide should be active or not.
+     
+     @fn void    tPoly_setPitchGlideTime     (tPoly* const poly, float t)
+     @brief Set how long pitch glide over note changes in voices takes.
+     @param poly A pointer to the relevant tPoly.
+     @param t The time to glide in milliseconds.
+     
+     @fn void    tPoly_setPitchBend          (tPoly* const poly, float pitchBend)
+     @brief Set the amount of pitch bend
+     @param poly A pointer to the relevant tPoly.
+     @param pitchBend The new amount of pitch bend.
+     
+     @fn void     tPoly_setBendGlideTime        (tPoly* const poly, float t)
+     @brief
+     @param
+     
+     @fn void     tPoly_setBendSamplesPerTick    (tPoly* const poly, float t)
+     @brief
+     @param
+     
+     @fn void    tPoly_tickPitch             (tPoly* const poly)
+     @brief Execute all tick-rate changes in the poly handler's pitch, including glide and bend.
+     @param poly A pointer to the relevant tPoly.
+     
+     @fn void    tPoly_tickPitchGlide        (tPoly* const poly)
+     @brief Execute the tick-rate change of the poly handler's pitch glide.
+     @param poly A pointer to the relevant tPoly.
+     
+     @fn void    tPoly_tickPitchBend         (tPoly* const poly)
+     @brief Execute the tick-rate change of the poly handler's pitch bend.
+     @param poly A pointer to the relevant tPoly.
+     
+     @fn int     tPoly_getNumVoices          (tPoly* const poly)
+     @brief Get the current number of voices available to play notes.
+     @param poly A pointer to the relevant tPoly.
+     @return The current number of voices available to play notes.
+     
+     @fn int     tPoly_getNumActiveVoices    (tPoly* const poly)
+     @brief Get the number of voices currently playing notes.
+     @param poly A pointer to the relevant tPoly.
+     @return The number of voices currently playing notes.
+     
+     @fn float   tPoly_getPitch              (tPoly* const poly, uint8_t voice)
+     @brief Get the current pitch of a given voice.
+     @param poly A pointer to the relevant tPoly.
+     @param voice The voice to get the pitch of.
+     @return The current pitch of the given voice as a fractional MIDI note number.
+     
+     @fn int     tPoly_getKey                (tPoly* const poly, uint8_t voice)
+     @brief Get the current MIDI note number of a given voice.
+     @param poly A pointer to the relevant tPoly.
+     @param voice The voice to get the MIDI note number of.
+     @return The MIDI note number of the given voice.
+     
+     @fn int     tPoly_getVelocity           (tPoly* const poly, uint8_t voice)
+     @brief Get the current MIDI velocity of a given voice.
+     @param poly A pointer to the relevant tPoly.
+     @param voice The voice to get the MIDI velocity of.
+     @return The current MIDI velocity of the given voice.
+     
+     @fn int     tPoly_isOn                  (tPoly* const poly, uint8_t voice)
+     @brief Get the current play state of a given voice.
+     @param poly A pointer to the relevant tPoly.
+     @param voice The voice to get the state of.
+     @return The current play state of the given voice.
+     
+     @} */
+
+    typedef struct _tPoly
+    {
+        
+        tMempool mempool;
+        
+        tStack stack;
+        tStack orderStack;
+        
+        tRamp* ramps;
+        float* rampVals;
+        int* firstReceived;
+        float glideTime;
+        int 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;
+    
+    typedef _tPoly* tPoly;
+    
+    void    tPoly_init                  (tPoly* const poly, int maxNumVoices, LEAF* const leaf);
+    void    tPoly_initToPool            (tPoly* const poly, int maxNumVoices, tMempool* const pool);
+    void    tPoly_free                  (tPoly* const poly);
+    
+    int     tPoly_noteOn                (tPoly* const poly, int note, uint8_t vel);
+    int     tPoly_noteOff               (tPoly* const poly, uint8_t note);
+    void    tPoly_orderedAddToStack     (tPoly* const poly, uint8_t note);
+    void    tPoly_setNumVoices          (tPoly* const poly, uint8_t numVoices);
+    void    tPoly_setPitchGlideActive   (tPoly* const poly, int isActive);
+    void    tPoly_setPitchGlideTime     (tPoly* const poly, float t);
+    void    tPoly_setPitchBend          (tPoly* const poly, float pitchBend);
+    void 	tPoly_setBendGlideTime		(tPoly* const poly, float t);
+    void 	tPoly_setBendSamplesPerTick	(tPoly* const poly, float t);
+    void    tPoly_tickPitch             (tPoly* const poly);
+    void    tPoly_tickPitchGlide        (tPoly* const poly);
+    void    tPoly_tickPitchBend         (tPoly* const poly);
+    int     tPoly_getNumVoices          (tPoly* const poly);
+    int     tPoly_getNumActiveVoices    (tPoly* const poly);
+    float   tPoly_getPitch              (tPoly* const poly, uint8_t voice);
+    int     tPoly_getKey                (tPoly* const poly, uint8_t voice);
+    int     tPoly_getVelocity           (tPoly* const poly, uint8_t voice);
+    int     tPoly_isOn                  (tPoly* const poly, uint8_t voice);
+    void    tPoly_setSampleRate         (tPoly* const poly, float sr);
+    
+    //==============================================================================
+
+    /*! @}
+     @defgroup tsimplepoly tSimplePoly
+     @ingroup midi
+     @brief Polyphony handler.
+     @{
+     
+     @fn void    tSimplePoly_init                  (tSimplePoly* const poly, int maxNumVoices, LEAF* const leaf)
+     @brief Initialize a tSimplePoly to the default mempool of a LEAF instance.
+     @param poly A pointer to the tSimplePoly to initialize.
+     @param maxNumVoices The maximum number of voices this tSimplePoly can handle at once.
+     @param leaf A pointer to the leaf instance.
+     
+     @fn void    tSimplePoly_initToPool            (tSimplePoly* const poly, int maxNumVoices, tMempool* const pool)
+     @brief Initialize a tSimplePoly to a specified mempool.
+     @param poly A pointer to the tSimplePoly to initialize.
+     @param mempool A pointer to the tMempool to use.
+     
+     @fn void    tSimplePoly_free                  (tSimplePoly* const poly)
+     @brief Free a tSimplePoly from its mempool.
+     @param poly A pointer to the tSimplePoly to free.
+     
+     @fn int     tSimplePoly_noteOn                (tSimplePoly* const poly, int note, uint8_t vel)
+     @brief Add a note with a given velocity to the poly handler.
+     @param poly A pointer to the relevant tSimplePoly.
+     @param note The MIDI note number to add.
+     @param vel The MIDI velocity of the note to add.
+     @return The voice that will play the note.
+     
+     @fn int     tSimplePoly_noteOff               (tSimplePoly* const poly, uint8_t note)
+     @brief Remove a note from the poly handler.
+     @param poly A pointer to the relevant tSimplePoly.
+     @param note The MIDI note number to remove.
+     @return The voice that was playing the removed note.
+     
+     @fn void tSimplePoly_deactivateVoice(tSimplePoly* const polyh, uint8_t voice)
+     @brief
+     @param
+     
+     @fn int tSimplePoly_markPendingNoteOff(tSimplePoly* const polyh, uint8_t note)
+     @brief
+     @param
+     
+     @fn int tSimplePoly_findVoiceAssignedToNote(tSimplePoly* const polyh, uint8_t note)
+     @brief Find if there is a voice with that note -- useful for note offs where you want to wait to remove it from the poly until the release phase of the envelope is finished
+     @param
+     
+     @fn void    tSimplePoly_setNumVoices          (tSimplePoly* const poly, uint8_t numVoices)
+     @brief Set the number of voices available to play notes.
+     @param poly A pointer to the relevant tSimplePoly.
+     @param numVoices The new number of available voices. Cannot be greater than the max number voices given on initialization.
+     
+     @fn int     tSimplePoly_getNumVoices          (tSimplePoly* const poly)
+     @brief Get the current number of voices available to play notes.
+     @param poly A pointer to the relevant tSimplePoly.
+     @return The current number of voices available to play notes.
+     
+     @fn int     tSimplePoly_getNumActiveVoices    (tSimplePoly* const poly)
+     @brief Get the number of voices currently playing notes.
+     @param poly A pointer to the relevant tSimplePoly.
+     @return The number of voices currently playing notes.
+     
+     @fn int   tSimplePoly_getPitch              (tSimplePoly* const poly, uint8_t voice)
+     @brief Get the current MIDI note number of a given voice.
+     @param poly A pointer to the relevant tSimplePoly.
+     @param voice The voice to get the MIDI note number of.
+     @return The MIDI note number of the given voice.
+     
+     @fn int tSimplePoly_getPitchAndCheckActive(tSimplePoly* const polyh, uint8_t voice)
+     @brief Returns negative one if the voice is inactive
+     
+     @fn int     tSimplePoly_getVelocity           (tSimplePoly* const poly, uint8_t voice)
+     @brief Get the current MIDI velocity of a given voice.
+     @param poly A pointer to the relevant tSimplePoly.
+     @param voice The voice to get the MIDI velocity of.
+     @return The current MIDI velocity of the given voice.
+     
+     @fn int     tSimplePoly_isOn                  (tSimplePoly* const poly, uint8_t voice)
+     @brief Get the current play state of a given voice.
+     @param poly A pointer to the relevant tSimplePoly.
+     @param voice The voice to get the state of.
+     @return The current play state of the given voice.
+     
+     @} */
+    typedef struct _tSimplePoly
+    {
+        tMempool mempool;
+        
+        tStack stack;
+
+        int numVoices;
+        int maxNumVoices;
+        int** voices;
+        int stealing_on;
+        int recover_stolen;
+
+        int notes[128][2];
+    } _tSimplePoly;
+
+    typedef _tSimplePoly* tSimplePoly;
+
+    void    tSimplePoly_init                  (tSimplePoly* const poly, int maxNumVoices, LEAF* const leaf);
+    void    tSimplePoly_initToPool            (tSimplePoly* const poly, int maxNumVoices, tMempool* const pool);
+    void    tSimplePoly_free                  (tSimplePoly* const poly);
+    
+    int     tSimplePoly_noteOn                (tSimplePoly* const poly, int note, uint8_t vel);
+    int     tSimplePoly_noteOff               (tSimplePoly* const poly, uint8_t note);
+    void    tSimplePoly_deactivateVoice         (tSimplePoly* const polyh, uint8_t voice);
+    int     tSimplePoly_markPendingNoteOff      (tSimplePoly* const polyh, uint8_t note);
+    int     tSimplePoly_findVoiceAssignedToNote (tSimplePoly* const polyh, uint8_t note);
+    void    tSimplePoly_setNumVoices          (tSimplePoly* const poly, uint8_t numVoices);
+    int     tSimplePoly_getNumVoices          (tSimplePoly* const poly);
+    int     tSimplePoly_getNumActiveVoices    (tSimplePoly* const poly);
+    int     tSimplePoly_getPitch              (tSimplePoly* const poly, uint8_t voice);
+    int     tSimplePoly_getPitchAndCheckActive(tSimplePoly* const polyh, uint8_t voice);
+    int     tSimplePoly_getVelocity           (tSimplePoly* const poly, uint8_t voice);
+    int     tSimplePoly_isOn                  (tSimplePoly* const poly, uint8_t voice);
+
+    //==============================================================================
+    
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LEAF_MIDI_H_INCLUDED
+
+//==============================================================================
+
+
--- a/leaf/Src/leaf-filters.c
+++ b/leaf/Src/leaf-filters.c
@@ -1560,6 +1560,16 @@
     f->invG = 1.0f/f->G;
     tVZFilter_calcCoeffs(vf);
 }
+void tVZFilter_setFrequencyAndBandwidthAndGain (tVZFilter* const vf, float freq, float BW, float gain)
+{
+    _tVZFilter* f = *vf;
+    f->fc = LEAF_clip(0.1f, freq, 0.4f * f->sampleRate);
+    //f->Q = LEAF_clip(0.01f, res, 100.0f);
+    f->B = LEAF_clip(0.01, BW, 100.f);
+    f->G = LEAF_clip(0.000001f, gain, 4000.0f);
+    f->invG = 1.0f/f->G;
+    tVZFilter_calcCoeffs(vf);
+}
 
 void tVZFilter_setFrequencyAndResonanceAndMorph (tVZFilter* const vf, float freq, float res, float morph)
 {