shithub: leaf

Download patch

ref: 9862cbb37265bedd87834d358376b47553d33162
parent: fdb31244751d90b1a6f869215769ac049da15936
author: Matthew Wang <mjw7@princeton.edu>
date: Thu Jul 16 10:03:45 EDT 2020

wavetable oscillator

--- a/leaf/Inc/leaf-oscillators.h
+++ b/leaf/Inc/leaf-oscillators.h
@@ -25,7 +25,69 @@
      @example basic-oscillators.c
      An example.
      */
+    
+    //==============================================================================
+    
+    /*!
+     @defgroup ttable tTable
+     @ingroup oscillators
+     @brief A general wavetable oscillator.
+     @{
+     */
+    
+    /*!
+     @fn void    tTable_init         (tTable* const osc)
+     @brief Initialize a tTable to the default LEAF mempool.
+     @param osc A pointer to the tTable to be initialized.
+     */
+    
+    /*!
+     @fn void    tTable_initToPool   (tTable* const osc, tMempool* const mempool)
+     @brief Initialize a tTable to a specified mempool.
+     @param osc A pointer to the tTable to be initialized.
+     @param pool A pointer to the tMempool to which the tTable should be initialized.
+     */
+    
+    /*!
+     @fn void    tTable_free         (tTable* const osc)
+     @brief Free a tTable from the default LEAF mempool.
+     @param osc A pointer to the tTable to be freed.
+     */
+    
+    /*!
+     @fn float   tTable_tick         (tTable* const osc)
+     @brief Tick a tTable oscillator.
+     @param osc A pointer to the relevant tTable.
+     @return The ticked sample as a float from -1 to 1.
+     */
+    
+    /*!
+     @fn void    tTable_setFreq      (tTable* const osc, float freq)
+     @brief Set the frequency of a tTable oscillator.
+     @param osc A pointer to the relevant tTable.
+     @param freq The frequency to set the oscillator to.
+     */
+    
+    /*! @} */
+    
+    typedef struct _tTable
+    {
+        tMempool mempool;
+        
+        float* waveTable;
+        int size;
+        float inc, freq;
+        float phase;
+    } _tTable;
+    
+    typedef _tTable* tTable;
 
+     void    tTable_init(tTable* const osc, float* waveTable, int size);
+     void    tTable_initToPool(tTable* const osc, float* waveTable, int size, tMempool* const mempool);
+     void    tTable_free(tTable* const osc);
+    
+     float   tTable_tick(tTable* const osc);
+     void    tTable_setFreq(tTable* const osc, float freq);
     
     //==============================================================================
     
--- a/leaf/Src/leaf-oscillators.c
+++ b/leaf/Src/leaf-oscillators.c
@@ -16,6 +16,73 @@
 
 #endif
 
+// WaveTable
+void    tTable_init(tTable* const cy, float* waveTable, int size)
+{
+    tTable_initToPool(cy, waveTable, size, &leaf.mempool);
+}
+
+void    tTable_initToPool(tTable* const cy, float* waveTable, int size, tMempool* const mp)
+{
+    _tMempool* m = *mp;
+    _tTable* c = *cy = (_tTable*)mpool_alloc(sizeof(_tTable), m);
+    c->mempool = m;
+    
+    c->waveTable = waveTable;
+    c->size = size;
+    c->inc = 0.0f;
+    c->phase = 0.0f;
+}
+
+void    tTable_free(tTable* const cy)
+{
+    _tTable* c = *cy;
+    
+    mpool_free((char*)c, c->mempool);
+}
+
+void     tTable_setFreq(tTable* const cy, float freq)
+{
+    _tTable* c = *cy;
+    
+    c->freq = freq;
+    c->inc = freq * leaf.invSampleRate;
+}
+
+float   tTable_tick(tTable* const cy)
+{
+    _tTable* c = *cy;
+    float temp;
+    int intPart;
+    float fracPart;
+    float samp0;
+    float samp1;
+    
+    // Phasor increment
+    c->phase += c->inc;
+    while (c->phase >= 1.0f) c->phase -= 1.0f;
+    while (c->phase < 0.0f) c->phase += 1.0f;
+    
+    // Wavetable synthesis
+    
+    temp = c->size * c->phase;
+    intPart = (int)temp;
+    fracPart = temp - (float)intPart;
+    samp0 = c->waveTable[intPart];
+    if (++intPart >= c->size) intPart = 0;
+    samp1 = c->waveTable[intPart];
+    
+    return (samp0 + (samp1 - samp0) * fracPart);
+    
+}
+
+void     tTableSampleRateChanged(tTable* const cy)
+{
+    _tTable* c = *cy;
+    
+    c->inc = c->freq * leaf.invSampleRate;
+}
+
 // Cycle
 void    tCycle_init(tCycle* const cy)
 {