Abel Zatarain / Mbed 2 deprecated FMSynthCSUSM

Dependencies:   mbed

Revision:
11:286386c0db40
Parent:
10:59c829586a4f
Child:
12:3a1e7fde5040
--- a/main.cpp	Thu Dec 07 19:19:17 2017 +0000
+++ b/main.cpp	Thu Dec 07 20:42:13 2017 +0000
@@ -42,6 +42,14 @@
 #define U_PI 3.14159265358979
 const int fixed2pi = (2.0 * U_PI) * (0x1 << 16l);
 
+enum envPhase {
+    attack = 4,
+    decay = 3,
+    sustain = 2,
+    release = 1,
+    off = 0
+};
+
 //non-constants
 //Most of these will be recalculated or reset on every input cycle of the main
 //  loop, as appropriate
@@ -53,8 +61,8 @@
 int64_t keyboard;
 int carrierPhases[numKeys];
 int modulatorPhases[numKeys];
-short envelopeStatesC[numKeys];
-short envelopeStatesM[numKeys];
+envPhase envelopeStatesC[numKeys];
+envPhase envelopeStatesM[numKeys];
 int envelopeAmpsC[numKeys];
 int envelopeAmpsM[numKeys];
 
@@ -96,62 +104,74 @@
 }
 
 void synthesize(){
-    carAmpS = 0;
-    for(int i = 0; i < numKeys; ++i){
-        if(keyboard & (0x1 << i)){
-            if(envelopeStatesC[i] < 2)
-                envelopeStatesC[i] = 4;
-            if(envelopeStatesM[i] < 2)
-                envelopeStatesM[i] = 4;
+    carAmpS = 0;//sum of all key waveforms
+    
+    for(int i = 0; i < numKeys; ++i){//for all keys
+        carrierPhases[i] &= 0xFFFF;
+        modulatorPhases[i] &= 0xFFFF;
+
+        if(keyboard & (0x1ll << (long long)i)){//i key is pushed
+            if(envelopeStatesC[i] == off){
+                carrierPhases[i] = 0;
+            }
+            if(envelopeStatesM[i] == off){
+                modulatorPhases[i] = 0;
+            }
+        
+        
+            if(envelopeStatesC[i] < release)
+                envelopeStatesC[i] = attack;
+            if(envelopeStatesM[i] < release)
+                envelopeStatesM[i] = attack;
             
-            if(envelopeStatesC[i] == 4){
+            if(envelopeStatesC[i] == attack){
                 envelopeAmpsC[i] += carA;
                 if(envelopeAmpsC[i] >= attackLimit){
                     envelopeAmpsC[i] = attackLimit;
-                    envelopeStatesC[i] = 3;
-                }
-            }
-            
-            if(envelopeStatesM[i] == 4){
-                envelopeAmpsM[i] += modA;
-                if(envelopeAmpsM[i] >= attackLimit){
-                    envelopeAmpsM[i] = attackLimit;
-                    envelopeStatesM[i] = 3;
+                    envelopeStatesC[i] = decay;
                 }
             }
             
-            if(envelopeStatesC[i] == 3){
-                envelopeAmpsC[i] += carD;
+            if(envelopeStatesM[i] == attack){
+                envelopeAmpsM[i] += modA;
+                if(envelopeAmpsM[i] >= attackLimit){
+                    envelopeAmpsM[i] = attackLimit;
+                    envelopeStatesM[i] = decay;
+                }
+            }
+            
+            if(envelopeStatesC[i] == decay){
+                envelopeAmpsC[i] -= carD;
                 if(envelopeAmpsC[i] <= carS){
                     envelopeAmpsC[i] = carS;
-                    envelopeStatesC[i] = 2;
+                    envelopeStatesC[i] = sustain;
                 }
             }
 
-            if(envelopeStatesM[i] == 3){
-                envelopeAmpsM[i] += modD;
+            if(envelopeStatesM[i] == decay){
+                envelopeAmpsM[i] -= modD;
                 if(envelopeAmpsM[i] <= modS){
                     envelopeAmpsM[i] = modS;
-                    envelopeStatesM[i] = 2;
+                    envelopeStatesM[i] = sustain;
                 }
             }
         }else{
-            if(envelopeStatesC[i] > 1)
-                envelopeStatesC[i] = 1;
-            if(envelopeStatesM[i] > 1)
-                envelopeStatesM[i] = 1;
+            if(envelopeStatesC[i] > release)
+                envelopeStatesC[i] = release;
+            if(envelopeStatesM[i] > release)
+                envelopeStatesM[i] = release;
                 
-            if(envelopeStatesC[i] == 1){
+            if(envelopeStatesC[i] == release){
                 if(envelopeAmpsC[i] <= 0){
-                    envelopeStatesC[i] = 0;
+                    envelopeStatesC[i] = off;
                     envelopeAmpsC[i] = 0;
                 }else{
                     envelopeAmpsC[i] -= carR;
                 }
             }
-            if(envelopeStatesM[i] == 1){
+            if(envelopeStatesM[i] == release){
                 if(envelopeAmpsM[i] <= 0){
-                    envelopeStatesM[i] = 0;
+                    envelopeStatesM[i] = off;
                     envelopeAmpsM[i] = 0;
                 }else{
                     envelopeAmpsM[i] -= modR;
@@ -160,10 +180,19 @@
         }
         
         if(envelopeAmpsC[i] > 0){
-            modulatorPhases[i] += (FMmult * carrierIncrements[i]) >> 16;
+            int tempMPI = (FMmult * carrierIncrements[i]) >> 16;
+            int tempCPI;
+            
+            tempMPI = (tempMPI > 32767) ? 32767 : tempMPI;
+            tempMPI = (tempMPI < -32767) ? -32767 : tempMPI;
+            modulatorPhases[i] += tempMPI;
             modAmpI = fastSin((((modulatorPhases[i] * envelopeAmpsM[i]) >> 16)
                 * modVol) >> 16);
-            carrierPhases[i] += ((carrierIncrements[i] + modAmpI) * fixed2pi) >> 16;
+            
+            tempCPI = (carrierIncrements[i] + modAmpI);
+            tempCPI = (tempCPI > 32767) ? 32767 : tempCPI;
+            tempCPI = (tempCPI < -32767) ? -32767 : tempCPI;
+            carrierPhases[i] += tempCPI;
             carAmpS += (fastSin(carrierPhases[i]) * envelopeAmpsC[i]) >> 16;
         }
     }
@@ -186,8 +215,8 @@
     for(int i = 0; i < numKeys; ++i){
         carrierPhases[i] = 0;
         modulatorPhases[i] = 0;
-        envelopeStatesC[i] = 0;
-        envelopeStatesM[i] = 0;
+        envelopeStatesC[i] = off;
+        envelopeStatesM[i] = off;
         envelopeAmpsC[i] = 0;
         envelopeAmpsM[i] = 0;
     }