Abel Zatarain / Mbed 2 deprecated FMSynthCSUSM

Dependencies:   mbed

Revision:
12:3a1e7fde5040
Parent:
11:286386c0db40
Child:
13:29705e6bf718
--- a/main.cpp	Thu Dec 07 20:42:13 2017 +0000
+++ b/main.cpp	Thu Dec 07 22:48:14 2017 +0000
@@ -40,32 +40,22 @@
     1019, 1080, 1144, 1212, 1284, 1360, 1441, 1527, 1618, 1714};
 const int attackLimit = (0x1 << 16) - 1;
 #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
 int FMmult;
 int Volume;
 int modVol;
-int modAmpI;
-int carAmpS;
 int64_t keyboard;
+int64_t modattack;
+int64_t carattack;
 int carrierPhases[numKeys];
 int modulatorPhases[numKeys];
-envPhase envelopeStatesC[numKeys];
-envPhase envelopeStatesM[numKeys];
 int envelopeAmpsC[numKeys];
 int envelopeAmpsM[numKeys];
 
+int testTone = 0;
+
 int modA;
 int modD;
 int modS;
@@ -104,99 +94,83 @@
 }
 
 void synthesize(){
-    carAmpS = 0;//sum of all key waveforms
+    int volumeSum = 0;//starting from silence
+    int CenvAmp, MenvAmp;
+    bool keypressed;
+    int tempPhase, modVal, carVal;
     
-    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;
-            }
-        
+    testTone = (testTone + carrierIncrements[25]) & 0xffff;
+    
+    for(int64_t i; i < numKeys; ++i){//for all keys
+        int64_t keymask = 0x00000001 << i;
+        keypressed = keyboard & keymask;
+        CenvAmp = envelopeAmpsC[i];
+        MenvAmp = envelopeAmpsM[i];
         
-            if(envelopeStatesC[i] < release)
-                envelopeStatesC[i] = attack;
-            if(envelopeStatesM[i] < release)
-                envelopeStatesM[i] = attack;
-            
-            if(envelopeStatesC[i] == attack){
-                envelopeAmpsC[i] += carA;
-                if(envelopeAmpsC[i] >= attackLimit){
-                    envelopeAmpsC[i] = attackLimit;
-                    envelopeStatesC[i] = decay;
-                }
-            }
-            
-            if(envelopeStatesM[i] == attack){
-                envelopeAmpsM[i] += modA;
-                if(envelopeAmpsM[i] >= attackLimit){
-                    envelopeAmpsM[i] = attackLimit;
-                    envelopeStatesM[i] = decay;
-                }
+        if(!keypressed){
+            carattack |= keymask;//re-enable attack
+            modattack |= keymask;
+            CenvAmp = (CenvAmp > 0) ? CenvAmp - carR : CenvAmp;
+            MenvAmp = (MenvAmp > 0) ? MenvAmp - modR : CenvAmp;
+        }else{
+            if(carattack & keymask){//if in carrier attack
+                CenvAmp = (CenvAmp < attackLimit) ? CenvAmp + carA : attackLimit;
+            }else{
+                CenvAmp = (CenvAmp > carS) ? CenvAmp - carD : carS;
             }
             
-            if(envelopeStatesC[i] == decay){
-                envelopeAmpsC[i] -= carD;
-                if(envelopeAmpsC[i] <= carS){
-                    envelopeAmpsC[i] = carS;
-                    envelopeStatesC[i] = sustain;
-                }
-            }
-
-            if(envelopeStatesM[i] == decay){
-                envelopeAmpsM[i] -= modD;
-                if(envelopeAmpsM[i] <= modS){
-                    envelopeAmpsM[i] = modS;
-                    envelopeStatesM[i] = sustain;
-                }
-            }
-        }else{
-            if(envelopeStatesC[i] > release)
-                envelopeStatesC[i] = release;
-            if(envelopeStatesM[i] > release)
-                envelopeStatesM[i] = release;
-                
-            if(envelopeStatesC[i] == release){
-                if(envelopeAmpsC[i] <= 0){
-                    envelopeStatesC[i] = off;
-                    envelopeAmpsC[i] = 0;
-                }else{
-                    envelopeAmpsC[i] -= carR;
-                }
+            if(modattack * keymask){//if in modulator attack
+                MenvAmp = (MenvAmp < attackLimit) ? MenvAmp + modA : attackLimit;
+            }else{
+                MenvAmp = (MenvAmp > modS) ? MenvAmp - modD : modS;
             }
-            if(envelopeStatesM[i] == release){
-                if(envelopeAmpsM[i] <= 0){
-                    envelopeStatesM[i] = off;
-                    envelopeAmpsM[i] = 0;
-                }else{
-                    envelopeAmpsM[i] -= modR;
-                }
-            }            
+        }
+
+        CenvAmp = (CenvAmp < 0) ? 0 : CenvAmp;
+        MenvAmp = (MenvAmp < 0) ? 0 : MenvAmp;
+        if(CenvAmp >= attackLimit){
+            CenvAmp = attackLimit;
+            carattack &= ~keymask; // disable attack on this key
         }
-        
-        if(envelopeAmpsC[i] > 0){
-            int tempMPI = (FMmult * carrierIncrements[i]) >> 16;
-            int tempCPI;
+        if(MenvAmp >= attackLimit){
+            MenvAmp = attackLimit;
+            modattack &= ~keymask;
+        }
+        if(CenvAmp == 0)
+            carrierPhases[i] = 0;
+        if(MenvAmp == 0)
+            modulatorPhases[i] = 0;
             
-            tempMPI = (tempMPI > 32767) ? 32767 : tempMPI;
-            tempMPI = (tempMPI < -32767) ? -32767 : tempMPI;
-            modulatorPhases[i] += tempMPI;
-            modAmpI = fastSin((((modulatorPhases[i] * envelopeAmpsM[i]) >> 16)
-                * modVol) >> 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;
-        }
+        envelopeAmpsC[i] = CenvAmp;
+        envelopeAmpsM[i]= MenvAmp;
+        
+        modulatorPhases[i] = (modulatorPhases[i] + ((carrierIncrements[i] * FMmult) >> 16)) & 0xffff;
+        modVal = fastSin(modulatorPhases[i]) * MenvAmp >> 16;
+        modVal = modVal * modVol >> 16;
+        
+        //debug
+        //modVal = 0;
+        //CenvAmp = keypressed ? 1 : 0;
+        
+        tempPhase = carrierPhases[i] + carrierIncrements[i];
+        tempPhase = (tempPhase + modVal) & 0xffff;
+        carrierPhases[i] = tempPhase;
+        
+        carVal = fastSin(tempPhase) * CenvAmp >> 16;
+        
+        volumeSum += carVal;        
     }
-    outMono.write_u16(((carAmpS / numKeys) * Volume) >> 16);
+    
+    volumeSum = volumeSum / numKeys;
+    volumeSum = (volumeSum * Volume) >> 16;
+    //outMono.write_u16((volumeSum + Volume) > 1);
+    volumeSum = fastSin(testTone) * 8;
+    volumeSum = (volumeSum > 32767) ? 32767 : volumeSum;
+    volumeSum = (volumeSum < -32768) ? -32768 : volumeSum;
+    volumeSum = volumeSum + 32768;
+    
+    
+    outMono.write_u16(volumeSum);
 }
 
 
@@ -209,14 +183,12 @@
     FMmult = 1;
     Volume = 0;
     modVol = 0;
-    modAmpI = 0;
-    carAmpS = 0;
     keyboard = 0ll;
+    modattack = 0x1ffffffffffff;
+    carattack = 0x1ffffffffffff;
     for(int i = 0; i < numKeys; ++i){
         carrierPhases[i] = 0;
         modulatorPhases[i] = 0;
-        envelopeStatesC[i] = off;
-        envelopeStatesM[i] = off;
         envelopeAmpsC[i] = 0;
         envelopeAmpsM[i] = 0;
     }
@@ -237,7 +209,9 @@
         ratDenom = 0xf & ~ denominator;
         FMmult = (ratNumer << 16) / ratDenom;
         
-        Volume = (int)inVol.read_u16();
+        //Volume = (int)inVol.read_u16();
+        Volume = 0xffff;
+        
         modVol = (int)inModAmt.read_u16();
         
         if(! inCarA.read_u16())
@@ -295,7 +269,9 @@
         }
         keytemp >>= 5;
         
-        keyboard = keytemp;
+        //keyboard = keytemp;
+        //debug
+        keyboard = 0x1000000ll;
         wait_ms(5);
     }
 }