Abel Zatarain / Mbed 2 deprecated FMSynthCSUSM

Dependencies:   mbed

Committer:
davolfman
Date:
Fri Dec 08 03:41:22 2017 +0000
Revision:
16:c2f912cdd919
Parent:
15:34ba7c2ef718
Child:
17:65437c94ab1b
A little glitchy (and very quiet) but it has polyphony.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
davolfman 0:b2f7400596ce 1 #include "mbed.h"
davolfman 3:83ac767f3a63 2 #include "sintable.h"
davolfman 0:b2f7400596ce 3
davolfman 9:86c0035f5321 4 AnalogOut outMono(PA_4);//Not labeled in the docs for the f401, but seems to be for all
davolfman 7:b0cd74923bc6 5 //AnalogOut DAC1(PA_5);
davolfman 0:b2f7400596ce 6
davolfman 9:86c0035f5321 7 AnalogIn inVol(PA_0);
davolfman 7:b0cd74923bc6 8 AnalogIn inModAmt(PA_1);
davolfman 6:9f8c8c3c111d 9 //AnalogIn ADC2(PA_2);//these are the uart pins!!
davolfman 6:9f8c8c3c111d 10 //AnalogIn ADC3(PA_3);//these are the uart pins!!
davolfman 0:b2f7400596ce 11 //AnalogIn ADC4(PA_4);//we're using these for output
davolfman 0:b2f7400596ce 12 //AnalogIn ADC5(PA_5);//we're using these for output
davolfman 9:86c0035f5321 13 AnalogIn inCarA(PA_6);
davolfman 9:86c0035f5321 14 AnalogIn inCarD(PA_7);
davolfman 0:b2f7400596ce 15 //AnalogIn ADC8(PB_0);//lets leave the 2 we aren't using in a single port
davolfman 0:b2f7400596ce 16 //AnalogIn ADC9(PB_1);//that way we know there's not ADCs on one of them
davolfman 9:86c0035f5321 17 AnalogIn inCarS(PC_0);
davolfman 9:86c0035f5321 18 AnalogIn inCarR(PC_1);
davolfman 9:86c0035f5321 19 AnalogIn inModA(PC_2);
davolfman 9:86c0035f5321 20 AnalogIn inModD(PC_3);
davolfman 9:86c0035f5321 21 AnalogIn inModS(PC_4);
davolfman 9:86c0035f5321 22 AnalogIn inModR(PC_5);
davolfman 0:b2f7400596ce 23
lenzi002 8:13b0594510de 24 //BusIn keyBank(PC_10, PC_11, PC_12, PC_13, PD_2, PH_1); old
lenzi002 8:13b0594510de 25 BusIn keyBank(PH_1, PD_2, PC_13, PC_12, PC_11, PC_10);
davolfman 7:b0cd74923bc6 26 BusOut bankSelect(PB_0, PB_1, PB_2, PB_3, PB_4, PB_5, PB_6, PB_7, PB_8);
davolfman 2:5454dee210ed 27 BusIn numerator(PA_8, PA_9, PA_10, PA_11);
davolfman 2:5454dee210ed 28 BusIn denominator(PA_12, PA_13, PA_14, PA_15);
davolfman 2:5454dee210ed 29
davolfman 16:c2f912cdd919 30 //Serial pc(USBTX, USBRX);
lenzi002 8:13b0594510de 31
davolfman 9:86c0035f5321 32 Ticker synthesisClock;
davolfman 0:b2f7400596ce 33
davolfman 2:5454dee210ed 34 #define numKeys 49
davolfman 0:b2f7400596ce 35
davolfman 4:1d2a699c95c7 36 //constants
davolfman 16:c2f912cdd919 37 const int carrierIncrements[] = {214, 227, 240, 254, 270, 286, 303, 321, 340,
davolfman 16:c2f912cdd919 38 360, 381, 404, 428, 454, 481, 509, 540, 572, 606, 642, 680, 720, 763, 809,
davolfman 16:c2f912cdd919 39 857, 908, 962, 1019, 1080, 1144, 1212, 1284, 1360, 1441, 1527, 1618, 1714,
davolfman 16:c2f912cdd919 40 1816, 1924, 2039, 2160, 2288, 2424, 2568, 2721, 2883, 3055, 3236, 3429};
davolfman 15:34ba7c2ef718 41 #define attackLimit 0xFFFF
davolfman 10:59c829586a4f 42 #define U_PI 3.14159265358979
davolfman 0:b2f7400596ce 43 //non-constants
davolfman 1:f3350a372732 44 //Most of these will be recalculated or reset on every input cycle of the main
davolfman 1:f3350a372732 45 // loop, as appropriate
davolfman 0:b2f7400596ce 46 int FMmult;
davolfman 0:b2f7400596ce 47 int Volume;
davolfman 1:f3350a372732 48 int modVol;
davolfman 2:5454dee210ed 49 int64_t keyboard;
davolfman 12:3a1e7fde5040 50 int64_t modattack;
davolfman 12:3a1e7fde5040 51 int64_t carattack;
davolfman 0:b2f7400596ce 52 int carrierPhases[numKeys];
davolfman 0:b2f7400596ce 53 int modulatorPhases[numKeys];
davolfman 0:b2f7400596ce 54 int envelopeAmpsC[numKeys];
davolfman 1:f3350a372732 55 int envelopeAmpsM[numKeys];
davolfman 1:f3350a372732 56
davolfman 12:3a1e7fde5040 57 int testTone = 0;
davolfman 12:3a1e7fde5040 58
davolfman 1:f3350a372732 59 int modA;
davolfman 1:f3350a372732 60 int modD;
davolfman 1:f3350a372732 61 int modS;
davolfman 1:f3350a372732 62 int modR;
davolfman 1:f3350a372732 63 int carA;
davolfman 1:f3350a372732 64 int carD;
davolfman 1:f3350a372732 65 int carS;
davolfman 1:f3350a372732 66 int carR;
davolfman 1:f3350a372732 67
davolfman 1:f3350a372732 68 int fastSin(const int phase){
davolfman 5:ac5c4bd3ef4b 69 int index = (phase & 0x3ffc) >> 2;
davolfman 5:ac5c4bd3ef4b 70 int subindex = phase & 0x3;
davolfman 5:ac5c4bd3ef4b 71 int quadrant = (phase & 0xc000) >> 14;
davolfman 3:83ac767f3a63 72 int sum = 0;
davolfman 5:ac5c4bd3ef4b 73 switch (quadrant) {
davolfman 5:ac5c4bd3ef4b 74 case 0:
davolfman 7:b0cd74923bc6 75 sum += (4 - subindex) * sinTable[index];
davolfman 7:b0cd74923bc6 76 sum += subindex * sinTable[index+1];
davolfman 5:ac5c4bd3ef4b 77 break;
davolfman 5:ac5c4bd3ef4b 78 case 1:
davolfman 7:b0cd74923bc6 79 sum += (4 - subindex) * sinTable[1+4095-index];
davolfman 7:b0cd74923bc6 80 sum += subindex * sinTable[4095-index];
davolfman 5:ac5c4bd3ef4b 81 break;
davolfman 5:ac5c4bd3ef4b 82 case 2:
davolfman 7:b0cd74923bc6 83 sum -= (4 - subindex) * sinTable[index];
davolfman 7:b0cd74923bc6 84 sum -= subindex * sinTable[index+1];
davolfman 5:ac5c4bd3ef4b 85 break;
davolfman 5:ac5c4bd3ef4b 86 case 3:
davolfman 7:b0cd74923bc6 87 sum -= (4 - subindex) * sinTable[1+4095-index];
davolfman 7:b0cd74923bc6 88 sum -= subindex * sinTable[4095-index];
davolfman 5:ac5c4bd3ef4b 89 break;
davolfman 5:ac5c4bd3ef4b 90 }
davolfman 3:83ac767f3a63 91 sum = sum >> 2;
davolfman 3:83ac767f3a63 92
davolfman 3:83ac767f3a63 93 return sum;
davolfman 1:f3350a372732 94 }
davolfman 0:b2f7400596ce 95
davolfman 1:f3350a372732 96 void synthesize(){
davolfman 15:34ba7c2ef718 97 int wave = 0;
davolfman 15:34ba7c2ef718 98 int subsignal;
davolfman 15:34ba7c2ef718 99 int64_t keymask;
davolfman 11:286386c0db40 100
davolfman 15:34ba7c2ef718 101 testTone = testTone + carrierIncrements[25] & 0xffff;
davolfman 12:3a1e7fde5040 102
davolfman 15:34ba7c2ef718 103 for(int64_t i = 0; i < numKeys; ++i){
davolfman 15:34ba7c2ef718 104 subsignal = 0;
davolfman 15:34ba7c2ef718 105 keymask = 1ll << i;
davolfman 15:34ba7c2ef718 106
davolfman 15:34ba7c2ef718 107 if(!(keymask & keyboard)){
davolfman 15:34ba7c2ef718 108 carattack |= keymask;
davolfman 12:3a1e7fde5040 109 modattack |= keymask;
davolfman 15:34ba7c2ef718 110
davolfman 15:34ba7c2ef718 111 if(envelopeAmpsC[i] > 0){
davolfman 15:34ba7c2ef718 112 envelopeAmpsC[i] -= carR;
davolfman 15:34ba7c2ef718 113 }
davolfman 15:34ba7c2ef718 114 if(envelopeAmpsM[i] > 0){
davolfman 15:34ba7c2ef718 115 envelopeAmpsM[i] -= carR;
davolfman 15:34ba7c2ef718 116 }
davolfman 12:3a1e7fde5040 117 }else{
davolfman 15:34ba7c2ef718 118 if(envelopeAmpsC[i] <= 0){
davolfman 15:34ba7c2ef718 119 carrierPhases[i] = 0;
davolfman 15:34ba7c2ef718 120 modulatorPhases[i] = 0;
davolfman 11:286386c0db40 121 }
davolfman 11:286386c0db40 122
davolfman 15:34ba7c2ef718 123 if(keymask & carattack){
davolfman 15:34ba7c2ef718 124 if(envelopeAmpsC[i] < attackLimit ){
davolfman 15:34ba7c2ef718 125 envelopeAmpsC[i] += carA;
davolfman 15:34ba7c2ef718 126 }else{
davolfman 15:34ba7c2ef718 127 envelopeAmpsC[i] = attackLimit;
davolfman 15:34ba7c2ef718 128 carattack &= ~keymask;
davolfman 15:34ba7c2ef718 129 }
davolfman 12:3a1e7fde5040 130 }else{
davolfman 15:34ba7c2ef718 131 if(envelopeAmpsC[i] > carS){
davolfman 15:34ba7c2ef718 132 envelopeAmpsC[i] -= carD;
davolfman 15:34ba7c2ef718 133 }
davolfman 15:34ba7c2ef718 134 }
davolfman 15:34ba7c2ef718 135
davolfman 15:34ba7c2ef718 136 if(keymask & modattack){
davolfman 15:34ba7c2ef718 137 if(envelopeAmpsM[i] < attackLimit){
davolfman 15:34ba7c2ef718 138 envelopeAmpsM[i] += modA;
davolfman 15:34ba7c2ef718 139 }else{
davolfman 15:34ba7c2ef718 140 envelopeAmpsM[i] = attackLimit;
davolfman 15:34ba7c2ef718 141 carattack &= ~keymask;
davolfman 15:34ba7c2ef718 142 }
davolfman 15:34ba7c2ef718 143 }else{
davolfman 15:34ba7c2ef718 144 if(envelopeAmpsM[i] > modS){
davolfman 15:34ba7c2ef718 145 envelopeAmpsM[i] -= modD;
davolfman 15:34ba7c2ef718 146 }
davolfman 15:34ba7c2ef718 147 }
davolfman 15:34ba7c2ef718 148
davolfman 15:34ba7c2ef718 149 if(envelopeAmpsC[i] > 0){
davolfman 15:34ba7c2ef718 150 modulatorPhases[i] += (carrierIncrements[i] * FMmult)>> 16;
davolfman 15:34ba7c2ef718 151 int modulation = (fastSin(modulatorPhases[i]) * envelopeAmpsM[i])>>16;
davolfman 15:34ba7c2ef718 152 modulation = (modulation * modVol) >> 16;
davolfman 15:34ba7c2ef718 153 carrierPhases[i] += carrierIncrements[i] + modulation;
davolfman 15:34ba7c2ef718 154 subsignal = (fastSin(carrierPhases[i]) * envelopeAmpsC[i])>>16;
davolfman 1:f3350a372732 155 }
davolfman 12:3a1e7fde5040 156 }
davolfman 15:34ba7c2ef718 157
davolfman 15:34ba7c2ef718 158 wave += subsignal;
davolfman 15:34ba7c2ef718 159 }
davolfman 15:34ba7c2ef718 160 //if(keyboard)
davolfman 15:34ba7c2ef718 161 // wave += fastSin(testTone);
davolfman 15:34ba7c2ef718 162
davolfman 15:34ba7c2ef718 163 wave = wave * Volume >> 16;
davolfman 16:c2f912cdd919 164 //wave = wave << 3;
davolfman 12:3a1e7fde5040 165
davolfman 15:34ba7c2ef718 166 wave = (wave > 32767) ? 32767 : wave;
davolfman 15:34ba7c2ef718 167 wave = (wave < -32768) ? - 32768 : wave;
davolfman 15:34ba7c2ef718 168 wave += 32768;
davolfman 15:34ba7c2ef718 169 outMono.write_u16(wave);
davolfman 1:f3350a372732 170 }
davolfman 0:b2f7400596ce 171
davolfman 0:b2f7400596ce 172
davolfman 0:b2f7400596ce 173 int main() {
davolfman 2:5454dee210ed 174 int ratNumer;
davolfman 2:5454dee210ed 175 int ratDenom;
davolfman 2:5454dee210ed 176
davolfman 9:86c0035f5321 177 int64_t keytemp = 0;
davolfman 9:86c0035f5321 178
davolfman 16:c2f912cdd919 179 //pc.printf("Starting up...");
davolfman 9:86c0035f5321 180 FMmult = 1;
davolfman 9:86c0035f5321 181 Volume = 0;
davolfman 9:86c0035f5321 182 modVol = 0;
davolfman 9:86c0035f5321 183 keyboard = 0ll;
davolfman 12:3a1e7fde5040 184 modattack = 0x1ffffffffffff;
davolfman 12:3a1e7fde5040 185 carattack = 0x1ffffffffffff;
davolfman 9:86c0035f5321 186 for(int i = 0; i < numKeys; ++i){
davolfman 9:86c0035f5321 187 carrierPhases[i] = 0;
davolfman 9:86c0035f5321 188 modulatorPhases[i] = 0;
davolfman 9:86c0035f5321 189 envelopeAmpsC[i] = 0;
davolfman 9:86c0035f5321 190 envelopeAmpsM[i] = 0;
davolfman 9:86c0035f5321 191 }
davolfman 9:86c0035f5321 192 modA = 0;
davolfman 9:86c0035f5321 193 modD = 0;
davolfman 9:86c0035f5321 194 modS = 0;
davolfman 9:86c0035f5321 195 modR = 0;
davolfman 9:86c0035f5321 196 carA = 0;
davolfman 9:86c0035f5321 197 carD = 0;
davolfman 9:86c0035f5321 198 carS = 0;
davolfman 9:86c0035f5321 199 carR = 0;
davolfman 9:86c0035f5321 200
lenzi002 8:13b0594510de 201 keyBank.mode(PullNone);
davolfman 16:c2f912cdd919 202 synthesisClock.attach(synthesize, 0.00005);//debug
lenzi002 8:13b0594510de 203
davolfman 16:c2f912cdd919 204 //pc.printf("done.\r\n");
davolfman 2:5454dee210ed 205 while(true){
davolfman 2:5454dee210ed 206 ratNumer = 0xf & ~ numerator;
davolfman 7:b0cd74923bc6 207 ratDenom = 0xf & ~ denominator;
davolfman 7:b0cd74923bc6 208 FMmult = (ratNumer << 16) / ratDenom;
davolfman 2:5454dee210ed 209
davolfman 13:29705e6bf718 210 Volume = (int)inVol.read_u16();
davolfman 12:3a1e7fde5040 211
davolfman 2:5454dee210ed 212 modVol = (int)inModAmt.read_u16();
davolfman 2:5454dee210ed 213
davolfman 9:86c0035f5321 214 if(! inCarA.read_u16())
davolfman 9:86c0035f5321 215 carA = 0xffff;
davolfman 9:86c0035f5321 216 else
davolfman 9:86c0035f5321 217 carA = 0xffff / ((int)inCarA.read_u16());
davolfman 9:86c0035f5321 218
davolfman 9:86c0035f5321 219 if(! inCarD.read_u16())
davolfman 9:86c0035f5321 220 carD = 0xffff;
davolfman 9:86c0035f5321 221 else
davolfman 9:86c0035f5321 222 carD = 0xffff / ((int)inCarD.read_u16());
davolfman 9:86c0035f5321 223
davolfman 2:5454dee210ed 224 carS = (int)inCarS.read_u16();
davolfman 9:86c0035f5321 225
davolfman 9:86c0035f5321 226 if(! inCarR.read_u16())
davolfman 9:86c0035f5321 227 carR = 0xffff;
davolfman 9:86c0035f5321 228 else
davolfman 9:86c0035f5321 229 carR = 0xffff / ((int)inCarR.read_u16());
davolfman 2:5454dee210ed 230
davolfman 9:86c0035f5321 231 if(! inModA.read_u16())
davolfman 9:86c0035f5321 232 modA = 0xffff;
davolfman 9:86c0035f5321 233 else
davolfman 9:86c0035f5321 234 modA = 0xffff / ((int)inModA.read_u16());
davolfman 9:86c0035f5321 235
davolfman 9:86c0035f5321 236 if(! inModD.read_u16())
davolfman 9:86c0035f5321 237 modD = 0xffff;
davolfman 9:86c0035f5321 238 else
davolfman 9:86c0035f5321 239 modD = 0xffff / ((int)inModD.read_u16());
davolfman 9:86c0035f5321 240
davolfman 2:5454dee210ed 241 modS = (int)inModS.read_u16();
davolfman 9:86c0035f5321 242
davolfman 9:86c0035f5321 243 if(! inModR.read_u16())
davolfman 9:86c0035f5321 244 modR = 0xffff;
davolfman 9:86c0035f5321 245 else
davolfman 9:86c0035f5321 246 modR = 0xffff / ((int)inModR.read_u16());
davolfman 14:0fcc949310b7 247
davolfman 13:29705e6bf718 248
davolfman 9:86c0035f5321 249 keytemp = 0; //zero the keys before we start ORing on top of everything
davolfman 9:86c0035f5321 250 for(int i = 0; i < 9; ++i) {
davolfman 13:29705e6bf718 251 bankSelect = (~(1 << i)) & bankSelect.mask();
lenzi002 8:13b0594510de 252 wait_us(200);
lenzi002 8:13b0594510de 253 int shiftOffset = 6LL * i;
davolfman 13:29705e6bf718 254
davolfman 9:86c0035f5321 255 keytemp |= ((~(unsigned long long)keyBank) & (unsigned long long)keyBank.mask()) << (unsigned long long)shiftOffset;
davolfman 7:b0cd74923bc6 256 }
davolfman 9:86c0035f5321 257 keytemp >>= 5;
davolfman 9:86c0035f5321 258
davolfman 13:29705e6bf718 259 keyboard = keytemp;
davolfman 13:29705e6bf718 260
davolfman 9:86c0035f5321 261 wait_ms(5);
davolfman 2:5454dee210ed 262 }
davolfman 0:b2f7400596ce 263 }