Abel Zatarain / Mbed 2 deprecated FMSynthCSUSM

Dependencies:   mbed

Revision:
15:34ba7c2ef718
Parent:
14:0fcc949310b7
Child:
16:c2f912cdd919
--- a/main.cpp	Fri Dec 08 00:33:19 2017 +0000
+++ b/main.cpp	Fri Dec 08 02:15:05 2017 +0000
@@ -38,7 +38,7 @@
     180, 190, 202, 214, 227, 240, 254, 270, 286, 303, 321, 340, 360, 381, 404, 
     428, 454, 481, 509, 540, 572, 606, 642, 680, 720, 763, 809, 857, 908, 962, 
     1019, 1080, 1144, 1212, 1284, 1360, 1441, 1527, 1618, 1714};
-const int attackLimit = (0x1 << 16) - 1;
+#define attackLimit 0xFFFF
 #define U_PI 3.14159265358979
 //non-constants
 //Most of these will be recalculated or reset on every input cycle of the main
@@ -94,68 +94,79 @@
 }
 
 void synthesize(){
-    int volumeSum = 0;//starting from silence
-    int CenvAmp, MenvAmp;
-    bool keypressed;
-    int tempPhase, modVal, carVal;
+    int wave = 0;
+    int subsignal;
+    int64_t keymask;
     
-    testTone = (testTone + carrierIncrements[25]) & 0xffff;
+    testTone = testTone + carrierIncrements[25] & 0xffff;
     
-    for(int i = 0; i < numKeys; ++i){//for all keys
-        int64_t keymask = 0x00000001 << (long long)i;
-        keypressed = (keyboard & keymask) != 0;
-        CenvAmp = envelopeAmpsC[i];
-        MenvAmp = envelopeAmpsM[i];
-        
-        if(!keypressed){
-            carattack |= keymask;//re-enable attack
+    for(int64_t i = 0; i < numKeys; ++i){
+        subsignal = 0;
+        keymask = 1ll << i;
+                
+        if(!(keymask & keyboard)){
+            carattack |= keymask;
             modattack |= keymask;
-            CenvAmp = (CenvAmp > 0) ? CenvAmp - carR : CenvAmp;
-            MenvAmp = (MenvAmp > 0) ? MenvAmp - modR : CenvAmp;
+            
+            if(envelopeAmpsC[i] > 0){
+                envelopeAmpsC[i] -= carR;
+            }
+            if(envelopeAmpsM[i] > 0){
+                envelopeAmpsM[i] -= carR;
+            }
         }else{
-            if(carattack & keymask){//if in carrier attack
-                CenvAmp = (CenvAmp < attackLimit) ? CenvAmp + carA : attackLimit;
-            }else{
-                CenvAmp = (CenvAmp > carS) ? CenvAmp - carD : carS;
+            if(envelopeAmpsC[i] <= 0){
+                carrierPhases[i] = 0;
+                modulatorPhases[i] = 0;
             }
             
-            if(modattack * keymask){//if in modulator attack
-                MenvAmp = (MenvAmp < attackLimit) ? MenvAmp + modA : attackLimit;
+            if(keymask & carattack){
+                if(envelopeAmpsC[i] < attackLimit ){
+                    envelopeAmpsC[i] += carA;
+                }else{
+                    envelopeAmpsC[i] = attackLimit;
+                    carattack &= ~keymask;
+                }
             }else{
-                MenvAmp = (MenvAmp > modS) ? MenvAmp - modD : modS;
+                if(envelopeAmpsC[i] > carS){
+                    envelopeAmpsC[i] -= carD;
+                }
+            }
+            
+            if(keymask & modattack){
+                if(envelopeAmpsM[i] < attackLimit){
+                    envelopeAmpsM[i] += modA;
+                }else{
+                    envelopeAmpsM[i] = attackLimit;
+                    carattack &= ~keymask;
+                }
+            }else{
+                if(envelopeAmpsM[i] > modS){
+                    envelopeAmpsM[i] -= modD;
+                }
+            }
+            
+            if(envelopeAmpsC[i] > 0){
+                modulatorPhases[i] += (carrierIncrements[i] * FMmult)>> 16;
+                int modulation = (fastSin(modulatorPhases[i]) * envelopeAmpsM[i])>>16;
+                modulation = (modulation * modVol) >> 16;
+                carrierPhases[i] += carrierIncrements[i] + modulation;
+                subsignal = (fastSin(carrierPhases[i]) * envelopeAmpsC[i])>>16;
             }
         }
+        
+        wave += subsignal;
+    }
+    //if(keyboard)
+    //    wave += fastSin(testTone);
+    
+    wave = wave * Volume >> 16;
+    wave = wave << 3;
 
-        CenvAmp = (CenvAmp < 0) ? 0 : CenvAmp;
-        MenvAmp = (MenvAmp < 0) ? 0 : MenvAmp;
-        if(CenvAmp >= attackLimit){
-            CenvAmp = attackLimit;
-            carattack &= ~keymask; // disable attack on this key
-        }
-        if(MenvAmp >= attackLimit){
-            MenvAmp = attackLimit;
-            modattack &= ~keymask;
-        }
-        if(CenvAmp == 0)
-            carrierPhases[i] = 0;
-        if(MenvAmp == 0)
-            modulatorPhases[i] = 0;
-            
-        envelopeAmpsC[i] = CenvAmp;
-        envelopeAmpsM[i]= MenvAmp;
-        
-        volumeSum += carVal;
-    }
-    if(keyboard != 0ll)
-        volumeSum += fastSin(testTone);
-    volumeSum = volumeSum / numKeys;
-    volumeSum = (volumeSum * Volume) >> 16;
-    volumeSum *= 8 * numKeys;
-    volumeSum = (volumeSum > 32767) ? 32767 : volumeSum;
-    volumeSum = (volumeSum < -32768) ? -32768 : volumeSum;
-    volumeSum = volumeSum + 32768;
-    
-    outMono.write_u16(volumeSum);
+    wave = (wave > 32767) ? 32767 : wave;
+    wave = (wave < -32768) ? - 32768 : wave;
+    wave += 32768;
+    outMono.write_u16(wave);
 }