Abel Zatarain / Mbed 2 deprecated FMSynthCSUSM

Dependencies:   mbed

Committer:
davolfman
Date:
Thu Dec 07 22:48:14 2017 +0000
Revision:
12:3a1e7fde5040
Parent:
11:286386c0db40
Child:
13:29705e6bf718
partially disabled to test audibility

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 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 12:3a1e7fde5040 97 int volumeSum = 0;//starting from silence
davolfman 12:3a1e7fde5040 98 int CenvAmp, MenvAmp;
davolfman 12:3a1e7fde5040 99 bool keypressed;
davolfman 12:3a1e7fde5040 100 int tempPhase, modVal, carVal;
davolfman 11:286386c0db40 101
davolfman 12:3a1e7fde5040 102 testTone = (testTone + carrierIncrements[25]) & 0xffff;
davolfman 12:3a1e7fde5040 103
davolfman 12:3a1e7fde5040 104 for(int64_t i; i < numKeys; ++i){//for all keys
davolfman 12:3a1e7fde5040 105 int64_t keymask = 0x00000001 << i;
davolfman 12:3a1e7fde5040 106 keypressed = keyboard & keymask;
davolfman 12:3a1e7fde5040 107 CenvAmp = envelopeAmpsC[i];
davolfman 12:3a1e7fde5040 108 MenvAmp = envelopeAmpsM[i];
davolfman 11:286386c0db40 109
davolfman 12:3a1e7fde5040 110 if(!keypressed){
davolfman 12:3a1e7fde5040 111 carattack |= keymask;//re-enable attack
davolfman 12:3a1e7fde5040 112 modattack |= keymask;
davolfman 12:3a1e7fde5040 113 CenvAmp = (CenvAmp > 0) ? CenvAmp - carR : CenvAmp;
davolfman 12:3a1e7fde5040 114 MenvAmp = (MenvAmp > 0) ? MenvAmp - modR : CenvAmp;
davolfman 12:3a1e7fde5040 115 }else{
davolfman 12:3a1e7fde5040 116 if(carattack & keymask){//if in carrier attack
davolfman 12:3a1e7fde5040 117 CenvAmp = (CenvAmp < attackLimit) ? CenvAmp + carA : attackLimit;
davolfman 12:3a1e7fde5040 118 }else{
davolfman 12:3a1e7fde5040 119 CenvAmp = (CenvAmp > carS) ? CenvAmp - carD : carS;
davolfman 11:286386c0db40 120 }
davolfman 11:286386c0db40 121
davolfman 12:3a1e7fde5040 122 if(modattack * keymask){//if in modulator attack
davolfman 12:3a1e7fde5040 123 MenvAmp = (MenvAmp < attackLimit) ? MenvAmp + modA : attackLimit;
davolfman 12:3a1e7fde5040 124 }else{
davolfman 12:3a1e7fde5040 125 MenvAmp = (MenvAmp > modS) ? MenvAmp - modD : modS;
davolfman 1:f3350a372732 126 }
davolfman 12:3a1e7fde5040 127 }
davolfman 12:3a1e7fde5040 128
davolfman 12:3a1e7fde5040 129 CenvAmp = (CenvAmp < 0) ? 0 : CenvAmp;
davolfman 12:3a1e7fde5040 130 MenvAmp = (MenvAmp < 0) ? 0 : MenvAmp;
davolfman 12:3a1e7fde5040 131 if(CenvAmp >= attackLimit){
davolfman 12:3a1e7fde5040 132 CenvAmp = attackLimit;
davolfman 12:3a1e7fde5040 133 carattack &= ~keymask; // disable attack on this key
davolfman 1:f3350a372732 134 }
davolfman 12:3a1e7fde5040 135 if(MenvAmp >= attackLimit){
davolfman 12:3a1e7fde5040 136 MenvAmp = attackLimit;
davolfman 12:3a1e7fde5040 137 modattack &= ~keymask;
davolfman 12:3a1e7fde5040 138 }
davolfman 12:3a1e7fde5040 139 if(CenvAmp == 0)
davolfman 12:3a1e7fde5040 140 carrierPhases[i] = 0;
davolfman 12:3a1e7fde5040 141 if(MenvAmp == 0)
davolfman 12:3a1e7fde5040 142 modulatorPhases[i] = 0;
davolfman 11:286386c0db40 143
davolfman 12:3a1e7fde5040 144 envelopeAmpsC[i] = CenvAmp;
davolfman 12:3a1e7fde5040 145 envelopeAmpsM[i]= MenvAmp;
davolfman 12:3a1e7fde5040 146
davolfman 12:3a1e7fde5040 147 modulatorPhases[i] = (modulatorPhases[i] + ((carrierIncrements[i] * FMmult) >> 16)) & 0xffff;
davolfman 12:3a1e7fde5040 148 modVal = fastSin(modulatorPhases[i]) * MenvAmp >> 16;
davolfman 12:3a1e7fde5040 149 modVal = modVal * modVol >> 16;
davolfman 12:3a1e7fde5040 150
davolfman 12:3a1e7fde5040 151 //debug
davolfman 12:3a1e7fde5040 152 //modVal = 0;
davolfman 12:3a1e7fde5040 153 //CenvAmp = keypressed ? 1 : 0;
davolfman 12:3a1e7fde5040 154
davolfman 12:3a1e7fde5040 155 tempPhase = carrierPhases[i] + carrierIncrements[i];
davolfman 12:3a1e7fde5040 156 tempPhase = (tempPhase + modVal) & 0xffff;
davolfman 12:3a1e7fde5040 157 carrierPhases[i] = tempPhase;
davolfman 12:3a1e7fde5040 158
davolfman 12:3a1e7fde5040 159 carVal = fastSin(tempPhase) * CenvAmp >> 16;
davolfman 12:3a1e7fde5040 160
davolfman 12:3a1e7fde5040 161 volumeSum += carVal;
davolfman 1:f3350a372732 162 }
davolfman 12:3a1e7fde5040 163
davolfman 12:3a1e7fde5040 164 volumeSum = volumeSum / numKeys;
davolfman 12:3a1e7fde5040 165 volumeSum = (volumeSum * Volume) >> 16;
davolfman 12:3a1e7fde5040 166 //outMono.write_u16((volumeSum + Volume) > 1);
davolfman 12:3a1e7fde5040 167 volumeSum = fastSin(testTone) * 8;
davolfman 12:3a1e7fde5040 168 volumeSum = (volumeSum > 32767) ? 32767 : volumeSum;
davolfman 12:3a1e7fde5040 169 volumeSum = (volumeSum < -32768) ? -32768 : volumeSum;
davolfman 12:3a1e7fde5040 170 volumeSum = volumeSum + 32768;
davolfman 12:3a1e7fde5040 171
davolfman 12:3a1e7fde5040 172
davolfman 12:3a1e7fde5040 173 outMono.write_u16(volumeSum);
davolfman 1:f3350a372732 174 }
davolfman 0:b2f7400596ce 175
davolfman 0:b2f7400596ce 176
davolfman 0:b2f7400596ce 177 int main() {
davolfman 2:5454dee210ed 178 int ratNumer;
davolfman 2:5454dee210ed 179 int ratDenom;
davolfman 2:5454dee210ed 180
davolfman 9:86c0035f5321 181 int64_t keytemp = 0;
davolfman 9:86c0035f5321 182
davolfman 9:86c0035f5321 183 FMmult = 1;
davolfman 9:86c0035f5321 184 Volume = 0;
davolfman 9:86c0035f5321 185 modVol = 0;
davolfman 9:86c0035f5321 186 keyboard = 0ll;
davolfman 12:3a1e7fde5040 187 modattack = 0x1ffffffffffff;
davolfman 12:3a1e7fde5040 188 carattack = 0x1ffffffffffff;
davolfman 9:86c0035f5321 189 for(int i = 0; i < numKeys; ++i){
davolfman 9:86c0035f5321 190 carrierPhases[i] = 0;
davolfman 9:86c0035f5321 191 modulatorPhases[i] = 0;
davolfman 9:86c0035f5321 192 envelopeAmpsC[i] = 0;
davolfman 9:86c0035f5321 193 envelopeAmpsM[i] = 0;
davolfman 9:86c0035f5321 194 }
davolfman 9:86c0035f5321 195 modA = 0;
davolfman 9:86c0035f5321 196 modD = 0;
davolfman 9:86c0035f5321 197 modS = 0;
davolfman 9:86c0035f5321 198 modR = 0;
davolfman 9:86c0035f5321 199 carA = 0;
davolfman 9:86c0035f5321 200 carD = 0;
davolfman 9:86c0035f5321 201 carS = 0;
davolfman 9:86c0035f5321 202 carR = 0;
davolfman 9:86c0035f5321 203
lenzi002 8:13b0594510de 204 keyBank.mode(PullNone);
davolfman 9:86c0035f5321 205 synthesisClock.attach(synthesize, 0.000025);
lenzi002 8:13b0594510de 206
davolfman 2:5454dee210ed 207 while(true){
davolfman 2:5454dee210ed 208 ratNumer = 0xf & ~ numerator;
davolfman 7:b0cd74923bc6 209 ratDenom = 0xf & ~ denominator;
davolfman 7:b0cd74923bc6 210 FMmult = (ratNumer << 16) / ratDenom;
davolfman 2:5454dee210ed 211
davolfman 12:3a1e7fde5040 212 //Volume = (int)inVol.read_u16();
davolfman 12:3a1e7fde5040 213 Volume = 0xffff;
davolfman 12:3a1e7fde5040 214
davolfman 2:5454dee210ed 215 modVol = (int)inModAmt.read_u16();
davolfman 2:5454dee210ed 216
davolfman 9:86c0035f5321 217 if(! inCarA.read_u16())
davolfman 9:86c0035f5321 218 carA = 0xffff;
davolfman 9:86c0035f5321 219 else
davolfman 9:86c0035f5321 220 carA = 0xffff / ((int)inCarA.read_u16());
davolfman 9:86c0035f5321 221
davolfman 9:86c0035f5321 222 if(! inCarD.read_u16())
davolfman 9:86c0035f5321 223 carD = 0xffff;
davolfman 9:86c0035f5321 224 else
davolfman 9:86c0035f5321 225 carD = 0xffff / ((int)inCarD.read_u16());
davolfman 9:86c0035f5321 226
davolfman 2:5454dee210ed 227 carS = (int)inCarS.read_u16();
davolfman 9:86c0035f5321 228
davolfman 9:86c0035f5321 229 if(! inCarR.read_u16())
davolfman 9:86c0035f5321 230 carR = 0xffff;
davolfman 9:86c0035f5321 231 else
davolfman 9:86c0035f5321 232 carR = 0xffff / ((int)inCarR.read_u16());
davolfman 2:5454dee210ed 233
davolfman 9:86c0035f5321 234 if(! inModA.read_u16())
davolfman 9:86c0035f5321 235 modA = 0xffff;
davolfman 9:86c0035f5321 236 else
davolfman 9:86c0035f5321 237 modA = 0xffff / ((int)inModA.read_u16());
davolfman 9:86c0035f5321 238
davolfman 9:86c0035f5321 239 if(! inModD.read_u16())
davolfman 9:86c0035f5321 240 modD = 0xffff;
davolfman 9:86c0035f5321 241 else
davolfman 9:86c0035f5321 242 modD = 0xffff / ((int)inModD.read_u16());
davolfman 9:86c0035f5321 243
davolfman 2:5454dee210ed 244 modS = (int)inModS.read_u16();
davolfman 9:86c0035f5321 245
davolfman 9:86c0035f5321 246 if(! inModR.read_u16())
davolfman 9:86c0035f5321 247 modR = 0xffff;
davolfman 9:86c0035f5321 248 else
davolfman 9:86c0035f5321 249 modR = 0xffff / ((int)inModR.read_u16());
davolfman 2:5454dee210ed 250
davolfman 7:b0cd74923bc6 251 //THIS IS CORRECT (1 means the key is connected)
davolfman 7:b0cd74923bc6 252 // B8 B7 B6 B5 B4 B3 B2 B1 B0
davolfman 7:b0cd74923bc6 253 // |----||----||----||----||----||----||----||----||
davolfman 7:b0cd74923bc6 254 //0000000000000001111111111111111111111111111111111111111111111111
davolfman 7:b0cd74923bc6 255 //
davolfman 7:b0cd74923bc6 256 //THIS IS NOT CORRECT (1 means the key is connected)
davolfman 7:b0cd74923bc6 257 // B8 B7 B6 B5 B4 B3 B2 B1 B0
davolfman 7:b0cd74923bc6 258 // |----||----||----||----||----||----||----||----||----|
davolfman 9:86c0035f5321 259 //0000000000111111111111111111111111111111111111111111111111100000
davolfman 9:86c0035f5321 260 //Thus, we need to subtract 5 from our shift
davolfman 9:86c0035f5321 261 keytemp = 0; //zero the keys before we start ORing on top of everything
davolfman 9:86c0035f5321 262 for(int i = 0; i < 9; ++i) {
lenzi002 8:13b0594510de 263 bankSelect = (~(1LL << i)) & (unsigned long long)bankSelect.mask();
lenzi002 8:13b0594510de 264 wait_us(200);
lenzi002 8:13b0594510de 265 int shiftOffset = 6LL * i;
davolfman 9:86c0035f5321 266
davolfman 7:b0cd74923bc6 267
davolfman 9:86c0035f5321 268 keytemp |= ((~(unsigned long long)keyBank) & (unsigned long long)keyBank.mask()) << (unsigned long long)shiftOffset;
davolfman 7:b0cd74923bc6 269 }
davolfman 9:86c0035f5321 270 keytemp >>= 5;
davolfman 9:86c0035f5321 271
davolfman 12:3a1e7fde5040 272 //keyboard = keytemp;
davolfman 12:3a1e7fde5040 273 //debug
davolfman 12:3a1e7fde5040 274 keyboard = 0x1000000ll;
davolfman 9:86c0035f5321 275 wait_ms(5);
davolfman 2:5454dee210ed 276 }
davolfman 0:b2f7400596ce 277 }