Browse Source

MSynth header. Fix-Saw,square. Squarewave Optimizations

akshaycadambi 5 years ago
parent
commit
9dd00bea4d
7 changed files with 83 additions and 38 deletions
  1. 8 0
      MSynth.h
  2. 11 7
      synth.cpp
  3. 4 1
      synth.h
  4. 18 21
      table.cpp
  5. 22 6
      table.h
  6. 13 3
      ugens.cpp
  7. 7 0
      ugens.h

+ 8 - 0
MSynth.h

@@ -0,0 +1,8 @@
+#ifndef MSYNTH
+#define MSYNTH
+
+#include "ugens.h"
+
+using namespace ugen;
+
+#endif // MSYNTH

+ 11 - 7
synth.cpp

@@ -7,12 +7,21 @@ synth::WavetableSynth::WavetableSynth()
     tbl = NULL;
 }
 
-sample synth::WavetableSynth::freqMod(float freq)
+// TODO: freqMod and setFreq inline. Or any other speed optimization.
+void synth::WavetableSynth::setFreq(float freq)
 {
+    frequency = freq;
     phase_inc = floor( frequency * (double) Tables::length() / SystemSR );
-    return this->tick();
+
+    //     //Frequency division (for control rate)
+//    phase_inc = floor( frequency * (double) Tables::length() / ( SystemSR >> ( (LFState & 0x1) | LF_FREQ_DIV)) );
 }
 
+sample synth::WavetableSynth::freqMod(float freq)
+{
+    setFreq( (frequency + freq) * 0.5);
+    return this->tick();
+}
 
 inline sample synth::WavetableSynth::tick()
 {
@@ -28,10 +37,5 @@ inline sample synth::WavetableSynth::tick()
     return outValue;
 }
 
-void synth::WavetableSynth::setFreq(float freq)
-{
-    frequency = freq;
-    phase_inc = lrint( frequency * (double) Tables::length() / SystemSR );
-}
 
 

+ 4 - 1
synth.h

@@ -3,8 +3,11 @@
 
 #include "table.h"
 
+
 namespace synth{
 
+//const float MIN_WAVETABLE_FREQ = SystemSR/Tables::length();
+
 class WavetableSynth
     {
     public:
@@ -17,7 +20,7 @@ class WavetableSynth
         WavetableSynth();
         void setFreq(float freq);
         sample freqMod(float freq);
-        virtual inline sample tick();
+        virtual sample tick();
 
 protected:
     };

+ 18 - 21
table.cpp

@@ -33,40 +33,37 @@ sample * gen::tri(int len)
 
 sample * gen::saw(int len)
 {
-    /* Square doesn't *really* have a wavetable. It simple does a comparison between
-     * the current phase and 0.5*table_length and returns either a 1 or 0.
-     *
-     * To avoid an extra division step, 0.5*table_length is stored in the table.
-     */
-    sample *SawTable = (sample* ) malloc(sizeof(sample));
-    *SawTable = len/2.0;
+    sample *SawTable = (sample* ) malloc(sizeof(sample) * len);
+    for (int i=0; i<len; i++)
+    {
+        *(SawTable+i) = 255.0/len * i ;
+    }
     return SawTable;
 }
 
 sample * gen::square(int len)
 {
-    // NOT USED
     sample *SquareTable = (sample* ) malloc(sizeof(sample) * len);
-    for (int i=0; i<len/2.0; i++)
+    for(int i=0; i<len; i++)
     {
-        *SquareTable = sin(2*M_PI*i/len);
+        *(SquareTable+i) = (i<len/2.0) & 255;
     }
     return SquareTable;
 }
 
 //*****************************************************
 
-int Tables::length(void)
-{
-    static int table_length = DEFAULT_TABLE_LENGTH;
-    return table_length;
-}
-
-int Tables::phase_mask(void)
-{
-    static int table_length = DEFAULT_PHASE_MASK;
-    return table_length;
-}
+//inline int Tables::length(void)
+//{
+//    static int table_length = DEFAULT_TABLE_LENGTH;
+//    return table_length;
+//}
+
+//inline int Tables::phase_mask(void)
+//{
+//    static int phase_mask = DEFAULT_PHASE_MASK;
+//    return phase_mask;
+//}
 
 sample * Tables::sine()
 {

+ 22 - 6
table.h

@@ -7,10 +7,13 @@
 #define DEFAULT_TABLE_LENGTH 1024
 #define DEFAULT_PHASE_MASK DEFAULT_TABLE_LENGTH-1
 
-typedef unsigned int sample;
+// TODO: Frequency division of sample rate (for control rate) - Comments in synth and ugens.
+#define LF_FREQ_DIV 2
 
 // Global Sample Rate
-#define SystemSR 44100
+#define SystemSR 16000
+
+typedef unsigned int sample;
 
 namespace gen {
     // Table filling functions
@@ -22,10 +25,23 @@ namespace gen {
 
 namespace Tables{
 
-    // Table containers
-    //  These funcitons return singletons of a table
-    int length(void);
-    int phase_mask(void);
+    // These return table parameters. (inlined for optimization)
+
+    inline int length(void)
+    {
+        static int table_length = DEFAULT_TABLE_LENGTH;
+        return table_length;
+    }
+
+    inline int phase_mask(void)
+    {
+        static int phase_mask = DEFAULT_PHASE_MASK;
+        return phase_mask;
+    }
+
+    // Table containers:
+    // These funcitons return singletons of a table
+
     sample * sine();
     sample * tri();
     sample * saw();

+ 13 - 3
ugens.cpp

@@ -67,14 +67,24 @@ sample ugen::ReverseSaw::operator()(void)
 ugen::Square::Square(float freq)
 {
     setFreq(freq);
-    // Note. This is optimized. See tables.cpp for details on saw table.
-    tbl = Tables::saw();
+    // Note. This is optimized. See table.cpp for details.
+#if SQUAREWAVE_MEMORY_OPTIMIZATION == 1
+    tbl = NULL;
+    half_length = Tables::length()/2;
+#else
+    tbl = Tables::square();
+#endif
 }
 
 sample ugen::Square::operator()(void)
 {
-    sample outValue = ( current_phase <= *tbl );
+#if SQUAREWAVE_MEMORY_OPTIMIZATION == 1
+    sample outValue = ( current_phase <= half_length );
     current_phase += phase_inc;
     current_phase = current_phase & Tables::phase_mask();
     return outValue;
+#else
+    return tick();
+#endif
+
 }

+ 7 - 0
ugens.h

@@ -3,6 +3,9 @@
 
 #include "synth.h"
 
+// Optimizes square-wave ugen to use lesser memory
+#define SQUAREWAVE_MEMORY_OPTIMIZATION 1
+
 namespace ugen{
 
 class Sine : public synth::WavetableSynth
@@ -36,6 +39,10 @@ class ReverseSaw: public synth::WavetableSynth
 class Square: public synth::WavetableSynth
     {
     public:
+
+#if SQUAREWAVE_MEMORY_OPTIMIZATION == 1
+        int half_length;
+#endif
         Square(float freq);
         sample operator()(void);
     };