Abel Zatarain / Mbed 2 deprecated FMSynthCSUSM

Dependencies:   mbed

Committer:
lenzi002
Date:
Thu Dec 07 02:09:10 2017 +0000
Revision:
8:13b0594510de
Parent:
7:b0cd74923bc6
Child:
9:86c0035f5321
it works!!!!; mostly!

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 0:b2f7400596ce 4 AnalogOut DAC0(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 0:b2f7400596ce 7 AnalogIn ADC0(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 0:b2f7400596ce 13 AnalogIn ADC6(PA_6);
davolfman 0:b2f7400596ce 14 AnalogIn ADC7(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 0:b2f7400596ce 17 AnalogIn ADC10(PC_0);
davolfman 0:b2f7400596ce 18 AnalogIn ADC11(PC_1);
davolfman 0:b2f7400596ce 19 AnalogIn ADC12(PC_2);
davolfman 0:b2f7400596ce 20 AnalogIn ADC13(PC_3);
davolfman 0:b2f7400596ce 21 AnalogIn ADC14(PC_4);
davolfman 0:b2f7400596ce 22 AnalogIn ADC15(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 0:b2f7400596ce 32 //Renaming ports
davolfman 0:b2f7400596ce 33 #define inVol ADC0
davolfman 7:b0cd74923bc6 34 //#define inModAmt ADC1
davolfman 0:b2f7400596ce 35 #define inCarA ADC6
davolfman 0:b2f7400596ce 36 #define inCarD ADC7
davolfman 0:b2f7400596ce 37 #define inCarS ADC10
davolfman 0:b2f7400596ce 38 #define inCarR ADC11
davolfman 0:b2f7400596ce 39 #define inModA ADC12
davolfman 0:b2f7400596ce 40 #define inModD ADC13
davolfman 0:b2f7400596ce 41 #define inModS ADC14
davolfman 0:b2f7400596ce 42 #define inModR ADC15
davolfman 0:b2f7400596ce 43 #define outMono DAC0
davolfman 0:b2f7400596ce 44
davolfman 2:5454dee210ed 45 #define numKeys 49
davolfman 1:f3350a372732 46 #define PI M_PI
davolfman 0:b2f7400596ce 47
davolfman 4:1d2a699c95c7 48 //constants
davolfman 4:1d2a699c95c7 49 const int carrierIncrements[] = {107, 113, 120, 127, 135, 143, 151, 160, 170,
davolfman 4:1d2a699c95c7 50 180, 190, 202, 214, 227, 240, 254, 270, 286, 303, 321, 340, 360, 381, 404,
davolfman 4:1d2a699c95c7 51 428, 454, 481, 509, 540, 572, 606, 642, 680, 720, 763, 809, 857, 908, 962,
davolfman 4:1d2a699c95c7 52 1019, 1080, 1144, 1212, 1284, 1360, 1441, 1527, 1618, 1714};
davolfman 1:f3350a372732 53 const int attackLimit = (0x1 << 16) - 1;
davolfman 7:b0cd74923bc6 54 #define U_PI 3.14159265358979f
davolfman 7:b0cd74923bc6 55 const int fixed2pi = (int) ((2.0 * U_PI) * (0x1 << 16));
davolfman 1:f3350a372732 56
davolfman 0:b2f7400596ce 57 //non-constants
davolfman 1:f3350a372732 58 //Most of these will be recalculated or reset on every input cycle of the main
davolfman 1:f3350a372732 59 // loop, as appropriate
davolfman 0:b2f7400596ce 60 int FMmult;
davolfman 0:b2f7400596ce 61 int Volume;
davolfman 1:f3350a372732 62 int modVol;
davolfman 1:f3350a372732 63 int modAmpI;
davolfman 1:f3350a372732 64 int carAmpS;
davolfman 2:5454dee210ed 65 //bool keysPressed[numKeys];
davolfman 2:5454dee210ed 66 int64_t keyboard;
davolfman 0:b2f7400596ce 67 int carrierPhases[numKeys];
davolfman 0:b2f7400596ce 68 int modulatorPhases[numKeys];
davolfman 0:b2f7400596ce 69 short envelopeStatesC[numKeys];
davolfman 0:b2f7400596ce 70 short envelopeStatesM[numKeys];
davolfman 0:b2f7400596ce 71 int envelopeAmpsC[numKeys];
davolfman 1:f3350a372732 72 int envelopeAmpsM[numKeys];
davolfman 1:f3350a372732 73
davolfman 1:f3350a372732 74 int modA;
davolfman 1:f3350a372732 75 int modD;
davolfman 1:f3350a372732 76 int modS;
davolfman 1:f3350a372732 77 int modR;
davolfman 1:f3350a372732 78 int carA;
davolfman 1:f3350a372732 79 int carD;
davolfman 1:f3350a372732 80 int carS;
davolfman 1:f3350a372732 81 int carR;
davolfman 1:f3350a372732 82
davolfman 1:f3350a372732 83 int fastSin(const int phase){
davolfman 5:ac5c4bd3ef4b 84 int index = (phase & 0x3ffc) >> 2;
davolfman 5:ac5c4bd3ef4b 85 int subindex = phase & 0x3;
davolfman 5:ac5c4bd3ef4b 86 int quadrant = (phase & 0xc000) >> 14;
davolfman 3:83ac767f3a63 87 int sum = 0;
davolfman 5:ac5c4bd3ef4b 88 switch (quadrant) {
davolfman 5:ac5c4bd3ef4b 89 case 0:
davolfman 7:b0cd74923bc6 90 sum += (4 - subindex) * sinTable[index];
davolfman 7:b0cd74923bc6 91 sum += subindex * sinTable[index+1];
davolfman 5:ac5c4bd3ef4b 92 break;
davolfman 5:ac5c4bd3ef4b 93 case 1:
davolfman 7:b0cd74923bc6 94 sum += (4 - subindex) * sinTable[1+4095-index];
davolfman 7:b0cd74923bc6 95 sum += subindex * sinTable[4095-index];
davolfman 5:ac5c4bd3ef4b 96 break;
davolfman 5:ac5c4bd3ef4b 97 case 2:
davolfman 7:b0cd74923bc6 98 sum -= (4 - subindex) * sinTable[index];
davolfman 7:b0cd74923bc6 99 sum -= subindex * sinTable[index+1];
davolfman 5:ac5c4bd3ef4b 100 break;
davolfman 5:ac5c4bd3ef4b 101 case 3:
davolfman 7:b0cd74923bc6 102 sum -= (4 - subindex) * sinTable[1+4095-index];
davolfman 7:b0cd74923bc6 103 sum -= subindex * sinTable[4095-index];
davolfman 5:ac5c4bd3ef4b 104 break;
davolfman 5:ac5c4bd3ef4b 105 }
davolfman 3:83ac767f3a63 106 sum = sum >> 2;
davolfman 3:83ac767f3a63 107
davolfman 3:83ac767f3a63 108 return sum;
davolfman 1:f3350a372732 109 }
davolfman 0:b2f7400596ce 110
davolfman 1:f3350a372732 111 void synthesize(){
davolfman 1:f3350a372732 112 carAmpS = 0;
davolfman 1:f3350a372732 113 for(int i = 0; i < numKeys; ++i){
davolfman 2:5454dee210ed 114 if(keyboard & (0x1 << i)){
davolfman 1:f3350a372732 115 if(envelopeStatesC[i] < 2)
davolfman 1:f3350a372732 116 envelopeStatesC[i] = 4;
davolfman 1:f3350a372732 117 if(envelopeStatesM[i] < 2)
davolfman 1:f3350a372732 118 envelopeStatesM[i] = 4;
davolfman 1:f3350a372732 119
davolfman 1:f3350a372732 120 if(envelopeStatesC[i] == 4){
davolfman 1:f3350a372732 121 envelopeAmpsC[i] += carA;
davolfman 1:f3350a372732 122 if(envelopeAmpsC[i] >= attackLimit){
davolfman 1:f3350a372732 123 envelopeAmpsC[i] = attackLimit;
davolfman 1:f3350a372732 124 envelopeStatesC[i] = 3;
davolfman 1:f3350a372732 125 }
davolfman 1:f3350a372732 126 }
davolfman 1:f3350a372732 127
davolfman 1:f3350a372732 128 if(envelopeStatesM[i] == 4){
davolfman 1:f3350a372732 129 envelopeAmpsM[i] += modA;
davolfman 1:f3350a372732 130 if(envelopeAmpsM[i] >= attackLimit){
davolfman 1:f3350a372732 131 envelopeAmpsM[i] = attackLimit;
davolfman 1:f3350a372732 132 envelopeStatesM[i] = 3;
davolfman 1:f3350a372732 133 }
davolfman 1:f3350a372732 134 }
davolfman 1:f3350a372732 135
davolfman 1:f3350a372732 136 if(envelopeStatesC[i] == 3){
davolfman 1:f3350a372732 137 envelopeAmpsC[i] += carD;
davolfman 1:f3350a372732 138 if(envelopeAmpsC[i] <= carS){
davolfman 1:f3350a372732 139 envelopeAmpsC[i] = carS;
davolfman 1:f3350a372732 140 envelopeStatesC[i] = 2;
davolfman 1:f3350a372732 141 }
davolfman 1:f3350a372732 142 }
davolfman 1:f3350a372732 143
davolfman 1:f3350a372732 144 if(envelopeStatesM[i] == 3){
davolfman 1:f3350a372732 145 envelopeAmpsM[i] += modD;
davolfman 1:f3350a372732 146 if(envelopeAmpsM[i] <= modS){
davolfman 1:f3350a372732 147 envelopeAmpsM[i] = modS;
davolfman 1:f3350a372732 148 envelopeStatesM[i] = 2;
davolfman 1:f3350a372732 149 }
davolfman 1:f3350a372732 150 }
davolfman 1:f3350a372732 151 }else{
davolfman 1:f3350a372732 152 if(envelopeStatesC[i] > 1)
davolfman 1:f3350a372732 153 envelopeStatesC[i] = 1;
davolfman 1:f3350a372732 154 if(envelopeStatesM[i] > 1)
davolfman 1:f3350a372732 155 envelopeStatesM[i] = 1;
davolfman 1:f3350a372732 156
davolfman 1:f3350a372732 157 if(envelopeStatesC[i] == 1){
davolfman 1:f3350a372732 158 if(envelopeAmpsC[i] <= 0){
davolfman 1:f3350a372732 159 envelopeStatesC[i] = 0;
davolfman 1:f3350a372732 160 envelopeAmpsC[i] = 0;
davolfman 1:f3350a372732 161 }else{
davolfman 1:f3350a372732 162 envelopeAmpsC[i] -= carR;
davolfman 1:f3350a372732 163 }
davolfman 1:f3350a372732 164 }
davolfman 1:f3350a372732 165 if(envelopeStatesM[i] == 1){
davolfman 1:f3350a372732 166 if(envelopeAmpsM[i] <= 0){
davolfman 1:f3350a372732 167 envelopeStatesM[i] = 0;
davolfman 1:f3350a372732 168 envelopeAmpsM[i] = 0;
davolfman 1:f3350a372732 169 }else{
davolfman 1:f3350a372732 170 envelopeAmpsM[i] -= modR;
davolfman 1:f3350a372732 171 }
davolfman 1:f3350a372732 172 }
davolfman 1:f3350a372732 173 }
davolfman 1:f3350a372732 174
davolfman 1:f3350a372732 175 if(envelopeAmpsC[i] > 0){
davolfman 7:b0cd74923bc6 176 modulatorPhases[i] += (FMmult * carrierIncrements[i]) >> 16;
davolfman 1:f3350a372732 177 modAmpI = fastSin((((modulatorPhases[i] * envelopeAmpsM[i]) >> 16)
davolfman 1:f3350a372732 178 * modVol) >> 16);
davolfman 1:f3350a372732 179 carrierPhases[i] += ((carrierIncrements[i] + modAmpI) * fixed2pi) >> 16;
davolfman 7:b0cd74923bc6 180 carAmpS += (fastSin(carrierPhases[i]) * envelopeAmpsC[i]) >> 16;
davolfman 1:f3350a372732 181 }
davolfman 1:f3350a372732 182 }
davolfman 7:b0cd74923bc6 183 outMono.write_u16(((carAmpS / numKeys) * Volume) >> 16);
davolfman 1:f3350a372732 184 }
davolfman 0:b2f7400596ce 185
davolfman 0:b2f7400596ce 186
davolfman 0:b2f7400596ce 187 int main() {
davolfman 2:5454dee210ed 188 int ratNumer;
davolfman 2:5454dee210ed 189 int ratDenom;
davolfman 2:5454dee210ed 190
lenzi002 8:13b0594510de 191 keyBank.mode(PullNone);
lenzi002 8:13b0594510de 192
davolfman 2:5454dee210ed 193 while(true){
davolfman 2:5454dee210ed 194 ratNumer = 0xf & ~ numerator;
davolfman 7:b0cd74923bc6 195 ratDenom = 0xf & ~ denominator;
davolfman 7:b0cd74923bc6 196 FMmult = (ratNumer << 16) / ratDenom;
davolfman 2:5454dee210ed 197
davolfman 2:5454dee210ed 198 Volume = (int)inVol.read_u16();
davolfman 2:5454dee210ed 199 modVol = (int)inModAmt.read_u16();
davolfman 2:5454dee210ed 200
davolfman 2:5454dee210ed 201 carA = 0xffff / ((int)inCarA.read_u16());
davolfman 2:5454dee210ed 202 carD = 0xffff / ((int)inCarD.read_u16());
davolfman 2:5454dee210ed 203 carS = (int)inCarS.read_u16();
davolfman 2:5454dee210ed 204 carR = 0xffff / ((int)inCarR.read_u16());
davolfman 2:5454dee210ed 205
davolfman 2:5454dee210ed 206 modA = 0xffff / ((int)inModA.read_u16());
davolfman 2:5454dee210ed 207 modD = 0xffff / ((int)inModD.read_u16());
davolfman 2:5454dee210ed 208 modS = (int)inModS.read_u16();
davolfman 2:5454dee210ed 209 modR = 0xffff / ((int)inModR.read_u16());
davolfman 2:5454dee210ed 210
davolfman 7:b0cd74923bc6 211 //THIS IS CORRECT (1 means the key is connected)
davolfman 7:b0cd74923bc6 212 // B8 B7 B6 B5 B4 B3 B2 B1 B0
davolfman 7:b0cd74923bc6 213 // |----||----||----||----||----||----||----||----||
davolfman 7:b0cd74923bc6 214 //0000000000000001111111111111111111111111111111111111111111111111
davolfman 7:b0cd74923bc6 215 //
davolfman 7:b0cd74923bc6 216 //THIS IS NOT CORRECT (1 means the key is connected)
davolfman 7:b0cd74923bc6 217 // B8 B7 B6 B5 B4 B3 B2 B1 B0
davolfman 7:b0cd74923bc6 218 // |----||----||----||----||----||----||----||----||----|
davolfman 7:b0cd74923bc6 219 //0000000000111111111111111111111111111111111111111111111111000001
davolfman 7:b0cd74923bc6 220 //Thus, we need to subtract 5 from our shift for every bank > 0
davolfman 7:b0cd74923bc6 221 //'keyboard' should be uint64_t and not int64_t b/c keyboard&=~62 will make it negative, which isn't a huge deal really
davolfman 7:b0cd74923bc6 222 keyboard = 0; //zero the keys before we start ORing on top of everything
davolfman 7:b0cd74923bc6 223 for(int i = 0; i < 9; ++i) { //removed <= 9 because there is not 10 banks
lenzi002 8:13b0594510de 224 bankSelect = (~(1LL << i)) & (unsigned long long)bankSelect.mask();
lenzi002 8:13b0594510de 225 wait_us(200);
lenzi002 8:13b0594510de 226 int shiftOffset = 6LL * i;
lenzi002 8:13b0594510de 227 //shiftOffset -= 5; //bank 0 only has 1 key, so to prevent 5 missing keys and bits we subtract 5 for every bank > 0
lenzi002 8:13b0594510de 228 //else keyboard &= ~31; //clear bits 1-5 (xx00000x) b/c we are ORing the next bank of keys on top of them & they may not be 0
davolfman 7:b0cd74923bc6 229
lenzi002 8:13b0594510de 230 keyboard |= ((~(unsigned long long)keyBank) & (unsigned long long)keyBank.mask()) << (unsigned long long)shiftOffset;
davolfman 7:b0cd74923bc6 231 }
lenzi002 8:13b0594510de 232 keyboard >>= 5;
lenzi002 8:13b0594510de 233 /*for(int i = 63; i >= 0; i--) {
lenzi002 8:13b0594510de 234 pc.printf("%d", !!(keyboard & (1LL << i)));
lenzi002 8:13b0594510de 235 }
lenzi002 8:13b0594510de 236 pc.printf("\r\n");
lenzi002 8:13b0594510de 237 wait_ms(200);*/
davolfman 2:5454dee210ed 238 }
davolfman 0:b2f7400596ce 239 }