Abel Zatarain / Mbed 2 deprecated FMSynthCSUSM

Dependencies:   mbed

Committer:
davolfman
Date:
Thu Dec 07 20:42:13 2017 +0000
Revision:
11:286386c0db40
Parent:
10:59c829586a4f
Child:
12:3a1e7fde5040
Sound was partially working going to rewrite synthesize next

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
lenzi002 8:13b0594510de 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 4:1d2a699c95c7 37 const int carrierIncrements[] = {107, 113, 120, 127, 135, 143, 151, 160, 170,
davolfman 4:1d2a699c95c7 38 180, 190, 202, 214, 227, 240, 254, 270, 286, 303, 321, 340, 360, 381, 404,
davolfman 4:1d2a699c95c7 39 428, 454, 481, 509, 540, 572, 606, 642, 680, 720, 763, 809, 857, 908, 962,
davolfman 4:1d2a699c95c7 40 1019, 1080, 1144, 1212, 1284, 1360, 1441, 1527, 1618, 1714};
davolfman 1:f3350a372732 41 const int attackLimit = (0x1 << 16) - 1;
davolfman 10:59c829586a4f 42 #define U_PI 3.14159265358979
davolfman 9:86c0035f5321 43 const int fixed2pi = (2.0 * U_PI) * (0x1 << 16l);
davolfman 1:f3350a372732 44
davolfman 11:286386c0db40 45 enum envPhase {
davolfman 11:286386c0db40 46 attack = 4,
davolfman 11:286386c0db40 47 decay = 3,
davolfman 11:286386c0db40 48 sustain = 2,
davolfman 11:286386c0db40 49 release = 1,
davolfman 11:286386c0db40 50 off = 0
davolfman 11:286386c0db40 51 };
davolfman 11:286386c0db40 52
davolfman 0:b2f7400596ce 53 //non-constants
davolfman 1:f3350a372732 54 //Most of these will be recalculated or reset on every input cycle of the main
davolfman 1:f3350a372732 55 // loop, as appropriate
davolfman 0:b2f7400596ce 56 int FMmult;
davolfman 0:b2f7400596ce 57 int Volume;
davolfman 1:f3350a372732 58 int modVol;
davolfman 1:f3350a372732 59 int modAmpI;
davolfman 1:f3350a372732 60 int carAmpS;
davolfman 2:5454dee210ed 61 int64_t keyboard;
davolfman 0:b2f7400596ce 62 int carrierPhases[numKeys];
davolfman 0:b2f7400596ce 63 int modulatorPhases[numKeys];
davolfman 11:286386c0db40 64 envPhase envelopeStatesC[numKeys];
davolfman 11:286386c0db40 65 envPhase envelopeStatesM[numKeys];
davolfman 0:b2f7400596ce 66 int envelopeAmpsC[numKeys];
davolfman 1:f3350a372732 67 int envelopeAmpsM[numKeys];
davolfman 1:f3350a372732 68
davolfman 1:f3350a372732 69 int modA;
davolfman 1:f3350a372732 70 int modD;
davolfman 1:f3350a372732 71 int modS;
davolfman 1:f3350a372732 72 int modR;
davolfman 1:f3350a372732 73 int carA;
davolfman 1:f3350a372732 74 int carD;
davolfman 1:f3350a372732 75 int carS;
davolfman 1:f3350a372732 76 int carR;
davolfman 1:f3350a372732 77
davolfman 1:f3350a372732 78 int fastSin(const int phase){
davolfman 5:ac5c4bd3ef4b 79 int index = (phase & 0x3ffc) >> 2;
davolfman 5:ac5c4bd3ef4b 80 int subindex = phase & 0x3;
davolfman 5:ac5c4bd3ef4b 81 int quadrant = (phase & 0xc000) >> 14;
davolfman 3:83ac767f3a63 82 int sum = 0;
davolfman 5:ac5c4bd3ef4b 83 switch (quadrant) {
davolfman 5:ac5c4bd3ef4b 84 case 0:
davolfman 7:b0cd74923bc6 85 sum += (4 - subindex) * sinTable[index];
davolfman 7:b0cd74923bc6 86 sum += subindex * sinTable[index+1];
davolfman 5:ac5c4bd3ef4b 87 break;
davolfman 5:ac5c4bd3ef4b 88 case 1:
davolfman 7:b0cd74923bc6 89 sum += (4 - subindex) * sinTable[1+4095-index];
davolfman 7:b0cd74923bc6 90 sum += subindex * sinTable[4095-index];
davolfman 5:ac5c4bd3ef4b 91 break;
davolfman 5:ac5c4bd3ef4b 92 case 2:
davolfman 7:b0cd74923bc6 93 sum -= (4 - subindex) * sinTable[index];
davolfman 7:b0cd74923bc6 94 sum -= subindex * sinTable[index+1];
davolfman 5:ac5c4bd3ef4b 95 break;
davolfman 5:ac5c4bd3ef4b 96 case 3:
davolfman 7:b0cd74923bc6 97 sum -= (4 - subindex) * sinTable[1+4095-index];
davolfman 7:b0cd74923bc6 98 sum -= subindex * sinTable[4095-index];
davolfman 5:ac5c4bd3ef4b 99 break;
davolfman 5:ac5c4bd3ef4b 100 }
davolfman 3:83ac767f3a63 101 sum = sum >> 2;
davolfman 3:83ac767f3a63 102
davolfman 3:83ac767f3a63 103 return sum;
davolfman 1:f3350a372732 104 }
davolfman 0:b2f7400596ce 105
davolfman 1:f3350a372732 106 void synthesize(){
davolfman 11:286386c0db40 107 carAmpS = 0;//sum of all key waveforms
davolfman 11:286386c0db40 108
davolfman 11:286386c0db40 109 for(int i = 0; i < numKeys; ++i){//for all keys
davolfman 11:286386c0db40 110 carrierPhases[i] &= 0xFFFF;
davolfman 11:286386c0db40 111 modulatorPhases[i] &= 0xFFFF;
davolfman 11:286386c0db40 112
davolfman 11:286386c0db40 113 if(keyboard & (0x1ll << (long long)i)){//i key is pushed
davolfman 11:286386c0db40 114 if(envelopeStatesC[i] == off){
davolfman 11:286386c0db40 115 carrierPhases[i] = 0;
davolfman 11:286386c0db40 116 }
davolfman 11:286386c0db40 117 if(envelopeStatesM[i] == off){
davolfman 11:286386c0db40 118 modulatorPhases[i] = 0;
davolfman 11:286386c0db40 119 }
davolfman 11:286386c0db40 120
davolfman 11:286386c0db40 121
davolfman 11:286386c0db40 122 if(envelopeStatesC[i] < release)
davolfman 11:286386c0db40 123 envelopeStatesC[i] = attack;
davolfman 11:286386c0db40 124 if(envelopeStatesM[i] < release)
davolfman 11:286386c0db40 125 envelopeStatesM[i] = attack;
davolfman 1:f3350a372732 126
davolfman 11:286386c0db40 127 if(envelopeStatesC[i] == attack){
davolfman 1:f3350a372732 128 envelopeAmpsC[i] += carA;
davolfman 1:f3350a372732 129 if(envelopeAmpsC[i] >= attackLimit){
davolfman 1:f3350a372732 130 envelopeAmpsC[i] = attackLimit;
davolfman 11:286386c0db40 131 envelopeStatesC[i] = decay;
davolfman 1:f3350a372732 132 }
davolfman 1:f3350a372732 133 }
davolfman 1:f3350a372732 134
davolfman 11:286386c0db40 135 if(envelopeStatesM[i] == attack){
davolfman 11:286386c0db40 136 envelopeAmpsM[i] += modA;
davolfman 11:286386c0db40 137 if(envelopeAmpsM[i] >= attackLimit){
davolfman 11:286386c0db40 138 envelopeAmpsM[i] = attackLimit;
davolfman 11:286386c0db40 139 envelopeStatesM[i] = decay;
davolfman 11:286386c0db40 140 }
davolfman 11:286386c0db40 141 }
davolfman 11:286386c0db40 142
davolfman 11:286386c0db40 143 if(envelopeStatesC[i] == decay){
davolfman 11:286386c0db40 144 envelopeAmpsC[i] -= carD;
davolfman 1:f3350a372732 145 if(envelopeAmpsC[i] <= carS){
davolfman 1:f3350a372732 146 envelopeAmpsC[i] = carS;
davolfman 11:286386c0db40 147 envelopeStatesC[i] = sustain;
davolfman 1:f3350a372732 148 }
davolfman 1:f3350a372732 149 }
davolfman 1:f3350a372732 150
davolfman 11:286386c0db40 151 if(envelopeStatesM[i] == decay){
davolfman 11:286386c0db40 152 envelopeAmpsM[i] -= modD;
davolfman 1:f3350a372732 153 if(envelopeAmpsM[i] <= modS){
davolfman 1:f3350a372732 154 envelopeAmpsM[i] = modS;
davolfman 11:286386c0db40 155 envelopeStatesM[i] = sustain;
davolfman 1:f3350a372732 156 }
davolfman 1:f3350a372732 157 }
davolfman 1:f3350a372732 158 }else{
davolfman 11:286386c0db40 159 if(envelopeStatesC[i] > release)
davolfman 11:286386c0db40 160 envelopeStatesC[i] = release;
davolfman 11:286386c0db40 161 if(envelopeStatesM[i] > release)
davolfman 11:286386c0db40 162 envelopeStatesM[i] = release;
davolfman 1:f3350a372732 163
davolfman 11:286386c0db40 164 if(envelopeStatesC[i] == release){
davolfman 1:f3350a372732 165 if(envelopeAmpsC[i] <= 0){
davolfman 11:286386c0db40 166 envelopeStatesC[i] = off;
davolfman 1:f3350a372732 167 envelopeAmpsC[i] = 0;
davolfman 1:f3350a372732 168 }else{
davolfman 1:f3350a372732 169 envelopeAmpsC[i] -= carR;
davolfman 1:f3350a372732 170 }
davolfman 1:f3350a372732 171 }
davolfman 11:286386c0db40 172 if(envelopeStatesM[i] == release){
davolfman 1:f3350a372732 173 if(envelopeAmpsM[i] <= 0){
davolfman 11:286386c0db40 174 envelopeStatesM[i] = off;
davolfman 1:f3350a372732 175 envelopeAmpsM[i] = 0;
davolfman 1:f3350a372732 176 }else{
davolfman 1:f3350a372732 177 envelopeAmpsM[i] -= modR;
davolfman 1:f3350a372732 178 }
davolfman 1:f3350a372732 179 }
davolfman 1:f3350a372732 180 }
davolfman 1:f3350a372732 181
davolfman 1:f3350a372732 182 if(envelopeAmpsC[i] > 0){
davolfman 11:286386c0db40 183 int tempMPI = (FMmult * carrierIncrements[i]) >> 16;
davolfman 11:286386c0db40 184 int tempCPI;
davolfman 11:286386c0db40 185
davolfman 11:286386c0db40 186 tempMPI = (tempMPI > 32767) ? 32767 : tempMPI;
davolfman 11:286386c0db40 187 tempMPI = (tempMPI < -32767) ? -32767 : tempMPI;
davolfman 11:286386c0db40 188 modulatorPhases[i] += tempMPI;
davolfman 1:f3350a372732 189 modAmpI = fastSin((((modulatorPhases[i] * envelopeAmpsM[i]) >> 16)
davolfman 1:f3350a372732 190 * modVol) >> 16);
davolfman 11:286386c0db40 191
davolfman 11:286386c0db40 192 tempCPI = (carrierIncrements[i] + modAmpI);
davolfman 11:286386c0db40 193 tempCPI = (tempCPI > 32767) ? 32767 : tempCPI;
davolfman 11:286386c0db40 194 tempCPI = (tempCPI < -32767) ? -32767 : tempCPI;
davolfman 11:286386c0db40 195 carrierPhases[i] += tempCPI;
davolfman 7:b0cd74923bc6 196 carAmpS += (fastSin(carrierPhases[i]) * envelopeAmpsC[i]) >> 16;
davolfman 1:f3350a372732 197 }
davolfman 1:f3350a372732 198 }
davolfman 7:b0cd74923bc6 199 outMono.write_u16(((carAmpS / numKeys) * Volume) >> 16);
davolfman 1:f3350a372732 200 }
davolfman 0:b2f7400596ce 201
davolfman 0:b2f7400596ce 202
davolfman 0:b2f7400596ce 203 int main() {
davolfman 2:5454dee210ed 204 int ratNumer;
davolfman 2:5454dee210ed 205 int ratDenom;
davolfman 2:5454dee210ed 206
davolfman 9:86c0035f5321 207 int64_t keytemp = 0;
davolfman 9:86c0035f5321 208
davolfman 9:86c0035f5321 209 FMmult = 1;
davolfman 9:86c0035f5321 210 Volume = 0;
davolfman 9:86c0035f5321 211 modVol = 0;
davolfman 9:86c0035f5321 212 modAmpI = 0;
davolfman 9:86c0035f5321 213 carAmpS = 0;
davolfman 9:86c0035f5321 214 keyboard = 0ll;
davolfman 9:86c0035f5321 215 for(int i = 0; i < numKeys; ++i){
davolfman 9:86c0035f5321 216 carrierPhases[i] = 0;
davolfman 9:86c0035f5321 217 modulatorPhases[i] = 0;
davolfman 11:286386c0db40 218 envelopeStatesC[i] = off;
davolfman 11:286386c0db40 219 envelopeStatesM[i] = off;
davolfman 9:86c0035f5321 220 envelopeAmpsC[i] = 0;
davolfman 9:86c0035f5321 221 envelopeAmpsM[i] = 0;
davolfman 9:86c0035f5321 222 }
davolfman 9:86c0035f5321 223 modA = 0;
davolfman 9:86c0035f5321 224 modD = 0;
davolfman 9:86c0035f5321 225 modS = 0;
davolfman 9:86c0035f5321 226 modR = 0;
davolfman 9:86c0035f5321 227 carA = 0;
davolfman 9:86c0035f5321 228 carD = 0;
davolfman 9:86c0035f5321 229 carS = 0;
davolfman 9:86c0035f5321 230 carR = 0;
davolfman 9:86c0035f5321 231
lenzi002 8:13b0594510de 232 keyBank.mode(PullNone);
davolfman 9:86c0035f5321 233 synthesisClock.attach(synthesize, 0.000025);
lenzi002 8:13b0594510de 234
davolfman 2:5454dee210ed 235 while(true){
davolfman 2:5454dee210ed 236 ratNumer = 0xf & ~ numerator;
davolfman 7:b0cd74923bc6 237 ratDenom = 0xf & ~ denominator;
davolfman 7:b0cd74923bc6 238 FMmult = (ratNumer << 16) / ratDenom;
davolfman 2:5454dee210ed 239
davolfman 2:5454dee210ed 240 Volume = (int)inVol.read_u16();
davolfman 2:5454dee210ed 241 modVol = (int)inModAmt.read_u16();
davolfman 2:5454dee210ed 242
davolfman 9:86c0035f5321 243 if(! inCarA.read_u16())
davolfman 9:86c0035f5321 244 carA = 0xffff;
davolfman 9:86c0035f5321 245 else
davolfman 9:86c0035f5321 246 carA = 0xffff / ((int)inCarA.read_u16());
davolfman 9:86c0035f5321 247
davolfman 9:86c0035f5321 248 if(! inCarD.read_u16())
davolfman 9:86c0035f5321 249 carD = 0xffff;
davolfman 9:86c0035f5321 250 else
davolfman 9:86c0035f5321 251 carD = 0xffff / ((int)inCarD.read_u16());
davolfman 9:86c0035f5321 252
davolfman 2:5454dee210ed 253 carS = (int)inCarS.read_u16();
davolfman 9:86c0035f5321 254
davolfman 9:86c0035f5321 255 if(! inCarR.read_u16())
davolfman 9:86c0035f5321 256 carR = 0xffff;
davolfman 9:86c0035f5321 257 else
davolfman 9:86c0035f5321 258 carR = 0xffff / ((int)inCarR.read_u16());
davolfman 2:5454dee210ed 259
davolfman 9:86c0035f5321 260 if(! inModA.read_u16())
davolfman 9:86c0035f5321 261 modA = 0xffff;
davolfman 9:86c0035f5321 262 else
davolfman 9:86c0035f5321 263 modA = 0xffff / ((int)inModA.read_u16());
davolfman 9:86c0035f5321 264
davolfman 9:86c0035f5321 265 if(! inModD.read_u16())
davolfman 9:86c0035f5321 266 modD = 0xffff;
davolfman 9:86c0035f5321 267 else
davolfman 9:86c0035f5321 268 modD = 0xffff / ((int)inModD.read_u16());
davolfman 9:86c0035f5321 269
davolfman 2:5454dee210ed 270 modS = (int)inModS.read_u16();
davolfman 9:86c0035f5321 271
davolfman 9:86c0035f5321 272 if(! inModR.read_u16())
davolfman 9:86c0035f5321 273 modR = 0xffff;
davolfman 9:86c0035f5321 274 else
davolfman 9:86c0035f5321 275 modR = 0xffff / ((int)inModR.read_u16());
davolfman 2:5454dee210ed 276
davolfman 7:b0cd74923bc6 277 //THIS IS CORRECT (1 means the key is connected)
davolfman 7:b0cd74923bc6 278 // B8 B7 B6 B5 B4 B3 B2 B1 B0
davolfman 7:b0cd74923bc6 279 // |----||----||----||----||----||----||----||----||
davolfman 7:b0cd74923bc6 280 //0000000000000001111111111111111111111111111111111111111111111111
davolfman 7:b0cd74923bc6 281 //
davolfman 7:b0cd74923bc6 282 //THIS IS NOT CORRECT (1 means the key is connected)
davolfman 7:b0cd74923bc6 283 // B8 B7 B6 B5 B4 B3 B2 B1 B0
davolfman 7:b0cd74923bc6 284 // |----||----||----||----||----||----||----||----||----|
davolfman 9:86c0035f5321 285 //0000000000111111111111111111111111111111111111111111111111100000
davolfman 9:86c0035f5321 286 //Thus, we need to subtract 5 from our shift
davolfman 9:86c0035f5321 287 keytemp = 0; //zero the keys before we start ORing on top of everything
davolfman 9:86c0035f5321 288 for(int i = 0; i < 9; ++i) {
lenzi002 8:13b0594510de 289 bankSelect = (~(1LL << i)) & (unsigned long long)bankSelect.mask();
lenzi002 8:13b0594510de 290 wait_us(200);
lenzi002 8:13b0594510de 291 int shiftOffset = 6LL * i;
davolfman 9:86c0035f5321 292
davolfman 7:b0cd74923bc6 293
davolfman 9:86c0035f5321 294 keytemp |= ((~(unsigned long long)keyBank) & (unsigned long long)keyBank.mask()) << (unsigned long long)shiftOffset;
davolfman 7:b0cd74923bc6 295 }
davolfman 9:86c0035f5321 296 keytemp >>= 5;
davolfman 9:86c0035f5321 297
davolfman 9:86c0035f5321 298 keyboard = keytemp;
davolfman 9:86c0035f5321 299 wait_ms(5);
davolfman 2:5454dee210ed 300 }
davolfman 0:b2f7400596ce 301 }