Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
Fork of STM32FMSynth by
main.cpp@23:7a9ff5230149, 2017-12-15 (annotated)
- Committer:
- davolfman
- Date:
- Fri Dec 15 04:50:56 2017 +0000
- Revision:
- 23:7a9ff5230149
- Parent:
- 22:0307adac8c35
Integration of main comments and added FastSin comments.
Who changed what in which revision?
| User | Revision | Line number | New 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 | 20:7ecec5738790 | 32 | Ticker synthesisClock;// this object sets up an ISR to execute every given fraction of a second. |
| davolfman | 0:b2f7400596ce | 33 | |
| davolfman | 20:7ecec5738790 | 34 | #define numKeys 49// our keyboard includes from two octaves above middle c to two octaves below it |
| davolfman | 0:b2f7400596ce | 35 | |
| davolfman | 4:1d2a699c95c7 | 36 | //constants |
| davolfman | 20:7ecec5738790 | 37 | |
| davolfman | 20:7ecec5738790 | 38 | //These are the pitches of the notes of our keyboard in hz * int16_max / sampling rate(20khz) |
| davolfman | 16:c2f912cdd919 | 39 | const int carrierIncrements[] = {214, 227, 240, 254, 270, 286, 303, 321, 340, |
| davolfman | 16:c2f912cdd919 | 40 | 360, 381, 404, 428, 454, 481, 509, 540, 572, 606, 642, 680, 720, 763, 809, |
| davolfman | 16:c2f912cdd919 | 41 | 857, 908, 962, 1019, 1080, 1144, 1212, 1284, 1360, 1441, 1527, 1618, 1714, |
| davolfman | 16:c2f912cdd919 | 42 | 1816, 1924, 2039, 2160, 2288, 2424, 2568, 2721, 2883, 3055, 3236, 3429}; |
| davolfman | 20:7ecec5738790 | 43 | |
| davolfman | 20:7ecec5738790 | 44 | //The maximum value of our envelopes is int16_max |
| davolfman | 15:34ba7c2ef718 | 45 | #define attackLimit 0xFFFF |
| davolfman | 20:7ecec5738790 | 46 | |
| davolfman | 20:7ecec5738790 | 47 | //this gives us a value of pi to multiply things by |
| davolfman | 10:59c829586a4f | 48 | #define U_PI 3.14159265358979 |
| davolfman | 20:7ecec5738790 | 49 | |
| davolfman | 0:b2f7400596ce | 50 | //non-constants |
| davolfman | 1:f3350a372732 | 51 | //Most of these will be recalculated or reset on every input cycle of the main |
| davolfman | 1:f3350a372732 | 52 | // loop, as appropriate |
| davolfman | 20:7ecec5738790 | 53 | |
| davolfman | 20:7ecec5738790 | 54 | int FMmult = 1;//The modulator pitch is FMmult * the base carrier pitch for that note |
| davolfman | 20:7ecec5738790 | 55 | int Volume = 0xffff;//the maximum volume to start, our number format is fixed 16 bits of fractional |
| davolfman | 20:7ecec5738790 | 56 | // inside a 32bit integer usually only in that fractional allowing for |
| davolfman | 20:7ecec5738790 | 57 | // integer multiplications and shifts to recenter instead of floating |
| davolfman | 20:7ecec5738790 | 58 | // -point arithmetic |
| davolfman | 20:7ecec5738790 | 59 | int modVol = 0x2000;//the amount of modulation to apply, most useful relatively low |
| davolfman | 20:7ecec5738790 | 60 | int64_t keyboard = 0;//our key state is stored as bit flags in the lower 49 bits of this |
| davolfman | 20:7ecec5738790 | 61 | int64_t modattack = 0x1ffffffffffff;//similar to keyboard, if the corrsponding bit is |
| davolfman | 20:7ecec5738790 | 62 | // zero the envelope for that bit is in decay or sustain instead of attack |
| davolfman | 18:4992aa537387 | 63 | int64_t carattack = 0x1ffffffffffff; |
| davolfman | 20:7ecec5738790 | 64 | int carrierPhases[numKeys];//store the phases of the notes in between samplings |
| davolfman | 0:b2f7400596ce | 65 | int modulatorPhases[numKeys]; |
| davolfman | 20:7ecec5738790 | 66 | int envelopeAmpsC[numKeys];//store the amplitudes of the envelopes in between samplings |
| davolfman | 1:f3350a372732 | 67 | int envelopeAmpsM[numKeys]; |
| davolfman | 1:f3350a372732 | 68 | |
| davolfman | 20:7ecec5738790 | 69 | //the envelope parameters for synthesis are read from these registers |
| davolfman | 20:7ecec5738790 | 70 | int modA = 0xffff;//modulator attack rate |
| davolfman | 20:7ecec5738790 | 71 | int modD = 0xffff;//modulator decay rate |
| davolfman | 20:7ecec5738790 | 72 | int modS = 0;//modulator sustain level |
| davolfman | 20:7ecec5738790 | 73 | int modR = 0xffff;//modulator release rate |
| davolfman | 20:7ecec5738790 | 74 | int carA = 0xffff;//carrier attack rate |
| davolfman | 20:7ecec5738790 | 75 | int carD = 0xffff;//carrier decay rate |
| davolfman | 20:7ecec5738790 | 76 | int carS = 0;//carrier sustain level |
| davolfman | 20:7ecec5738790 | 77 | int carR = 0xffff;//carrier release level |
| davolfman | 1:f3350a372732 | 78 | |
| davolfman | 23:7a9ff5230149 | 79 | ///@brief Converts a phase of period 2^16 into a sine value |
| davolfman | 23:7a9ff5230149 | 80 | ///@phase The phase to calculate the sine of in phase/65536 * 2 pi radians |
| davolfman | 23:7a9ff5230149 | 81 | ///@return the sine as a signed 16 bit fractonal part inside a 32 bit int |
| davolfman | 1:f3350a372732 | 82 | int fastSin(const int phase){ |
| davolfman | 23:7a9ff5230149 | 83 | //the middle 12 bits are used to index into a lookuptable of pre computed sines |
| davolfman | 5:ac5c4bd3ef4b | 84 | int index = (phase & 0x3ffc) >> 2; |
| davolfman | 23:7a9ff5230149 | 85 | |
| davolfman | 23:7a9ff5230149 | 86 | //we used linear interpolation given out bottom 2 bits to turn a 2^12 Look Up Table into a 2^14 LUT |
| davolfman | 5:ac5c4bd3ef4b | 87 | int subindex = phase & 0x3; |
| davolfman | 23:7a9ff5230149 | 88 | |
| davolfman | 23:7a9ff5230149 | 89 | //We use mirroring of a quarter wave of sine so we only have to store a quarter of the samples again |
| davolfman | 5:ac5c4bd3ef4b | 90 | int quadrant = (phase & 0xc000) >> 14; |
| davolfman | 3:83ac767f3a63 | 91 | int sum = 0; |
| davolfman | 23:7a9ff5230149 | 92 | switch (quadrant) {//perform the mirroring and add the memebers of the weighted average for interpolation |
| davolfman | 5:ac5c4bd3ef4b | 93 | case 0: |
| davolfman | 7:b0cd74923bc6 | 94 | sum += (4 - subindex) * sinTable[index]; |
| davolfman | 7:b0cd74923bc6 | 95 | sum += subindex * sinTable[index+1]; |
| davolfman | 5:ac5c4bd3ef4b | 96 | break; |
| davolfman | 5:ac5c4bd3ef4b | 97 | case 1: |
| davolfman | 7:b0cd74923bc6 | 98 | sum += (4 - subindex) * sinTable[1+4095-index]; |
| davolfman | 7:b0cd74923bc6 | 99 | sum += subindex * sinTable[4095-index]; |
| davolfman | 5:ac5c4bd3ef4b | 100 | break; |
| davolfman | 5:ac5c4bd3ef4b | 101 | case 2: |
| davolfman | 7:b0cd74923bc6 | 102 | sum -= (4 - subindex) * sinTable[index]; |
| davolfman | 7:b0cd74923bc6 | 103 | sum -= subindex * sinTable[index+1]; |
| davolfman | 5:ac5c4bd3ef4b | 104 | break; |
| davolfman | 5:ac5c4bd3ef4b | 105 | case 3: |
| davolfman | 7:b0cd74923bc6 | 106 | sum -= (4 - subindex) * sinTable[1+4095-index]; |
| davolfman | 7:b0cd74923bc6 | 107 | sum -= subindex * sinTable[4095-index]; |
| davolfman | 5:ac5c4bd3ef4b | 108 | break; |
| davolfman | 5:ac5c4bd3ef4b | 109 | } |
| davolfman | 23:7a9ff5230149 | 110 | sum = sum >> 2;//divide the weighted sum of the neighborign samples by 4 |
| davolfman | 23:7a9ff5230149 | 111 | //to get a weighted average |
| davolfman | 3:83ac767f3a63 | 112 | |
| davolfman | 3:83ac767f3a63 | 113 | return sum; |
| davolfman | 1:f3350a372732 | 114 | } |
| davolfman | 0:b2f7400596ce | 115 | |
| davolfman | 21:6dc8d091e878 | 116 | ///@brief calculates one audio sample given the keyboard state and envelope paramaters and passes it to the DAC |
| davolfman | 1:f3350a372732 | 117 | void synthesize(){ |
| davolfman | 21:6dc8d091e878 | 118 | int wave = 0;// holds the sample being constructed. |
| davolfman | 21:6dc8d091e878 | 119 | int subsignal;// the subsample for one note |
| davolfman | 21:6dc8d091e878 | 120 | int64_t keymask;// holds a mask of the current note for easy access to keyboard and attack registers |
| davolfman | 21:6dc8d091e878 | 121 | |
| davolfman | 21:6dc8d091e878 | 122 | //for all keys |
| davolfman | 15:34ba7c2ef718 | 123 | for(int64_t i = 0; i < numKeys; ++i){ |
| davolfman | 21:6dc8d091e878 | 124 | keymask = 1ll << i;//set the key mask |
| davolfman | 15:34ba7c2ef718 | 125 | |
| davolfman | 21:6dc8d091e878 | 126 | if(!(keymask & keyboard)){//if the key is NOT pressed |
| davolfman | 21:6dc8d091e878 | 127 | carattack |= keymask;//allow attack the next time it is |
| davolfman | 12:3a1e7fde5040 | 128 | modattack |= keymask; |
| davolfman | 15:34ba7c2ef718 | 129 | |
| davolfman | 21:6dc8d091e878 | 130 | //if envelope is still positive, decrement by decay rate |
| davolfman | 15:34ba7c2ef718 | 131 | if(envelopeAmpsC[i] > 0){ |
| davolfman | 15:34ba7c2ef718 | 132 | envelopeAmpsC[i] -= carR; |
| davolfman | 15:34ba7c2ef718 | 133 | } |
| davolfman | 15:34ba7c2ef718 | 134 | if(envelopeAmpsM[i] > 0){ |
| davolfman | 18:4992aa537387 | 135 | envelopeAmpsM[i] -= modR; |
| davolfman | 15:34ba7c2ef718 | 136 | } |
| davolfman | 21:6dc8d091e878 | 137 | |
| davolfman | 21:6dc8d091e878 | 138 | }else{//if the key IS pressed |
| davolfman | 21:6dc8d091e878 | 139 | |
| davolfman | 21:6dc8d091e878 | 140 | if(envelopeAmpsC[i] <= 0){//if this key was silent before, |
| davolfman | 21:6dc8d091e878 | 141 | carrierPhases[i] = 0;//reset the wave states |
| davolfman | 21:6dc8d091e878 | 142 | modulatorPhases[i] = 0;//this should prevent frequency drift from stopped FM |
| davolfman | 18:4992aa537387 | 143 | envelopeAmpsM[i] = 0; |
| davolfman | 21:6dc8d091e878 | 144 | envelopeAmpsC[i] = 1;//only do it once |
| davolfman | 11:286386c0db40 | 145 | } |
| davolfman | 21:6dc8d091e878 | 146 | |
| davolfman | 21:6dc8d091e878 | 147 | //if carrier has not left attack phase |
| davolfman | 15:34ba7c2ef718 | 148 | if(keymask & carattack){ |
| davolfman | 21:6dc8d091e878 | 149 | //add attack rate to envelope if not already maximised |
| davolfman | 15:34ba7c2ef718 | 150 | if(envelopeAmpsC[i] < attackLimit ){ |
| davolfman | 15:34ba7c2ef718 | 151 | envelopeAmpsC[i] += carA; |
| davolfman | 21:6dc8d091e878 | 152 | }else{//otherwise clip to maximum and leave attack pahse |
| davolfman | 15:34ba7c2ef718 | 153 | envelopeAmpsC[i] = attackLimit; |
| davolfman | 15:34ba7c2ef718 | 154 | carattack &= ~keymask; |
| davolfman | 15:34ba7c2ef718 | 155 | } |
| davolfman | 21:6dc8d091e878 | 156 | }else{//if in decay/sustain |
| davolfman | 21:6dc8d091e878 | 157 | if(envelopeAmpsC[i] > carS){//subtract the decay rate if above sustain level |
| davolfman | 15:34ba7c2ef718 | 158 | envelopeAmpsC[i] -= carD; |
| davolfman | 15:34ba7c2ef718 | 159 | } |
| davolfman | 15:34ba7c2ef718 | 160 | } |
| davolfman | 15:34ba7c2ef718 | 161 | |
| davolfman | 21:6dc8d091e878 | 162 | //do all that again for the modulator envelope |
| davolfman | 15:34ba7c2ef718 | 163 | if(keymask & modattack){ |
| davolfman | 15:34ba7c2ef718 | 164 | if(envelopeAmpsM[i] < attackLimit){ |
| davolfman | 15:34ba7c2ef718 | 165 | envelopeAmpsM[i] += modA; |
| davolfman | 15:34ba7c2ef718 | 166 | }else{ |
| davolfman | 15:34ba7c2ef718 | 167 | envelopeAmpsM[i] = attackLimit; |
| davolfman | 18:4992aa537387 | 168 | modattack &= ~keymask; |
| davolfman | 15:34ba7c2ef718 | 169 | } |
| davolfman | 15:34ba7c2ef718 | 170 | }else{ |
| davolfman | 15:34ba7c2ef718 | 171 | if(envelopeAmpsM[i] > modS){ |
| davolfman | 15:34ba7c2ef718 | 172 | envelopeAmpsM[i] -= modD; |
| davolfman | 15:34ba7c2ef718 | 173 | } |
| davolfman | 15:34ba7c2ef718 | 174 | } |
| davolfman | 15:34ba7c2ef718 | 175 | |
| davolfman | 22:0307adac8c35 | 176 | } |
| davolfman | 22:0307adac8c35 | 177 | |
| davolfman | 22:0307adac8c35 | 178 | //If this subsignal is not silent |
| davolfman | 22:0307adac8c35 | 179 | if(envelopeAmpsC[i] > 0){ |
| davolfman | 22:0307adac8c35 | 180 | //calculate the new phase of the modulator |
| davolfman | 22:0307adac8c35 | 181 | modulatorPhases[i] += (carrierIncrements[i] * FMmult)>> 16; |
| davolfman | 22:0307adac8c35 | 182 | |
| davolfman | 22:0307adac8c35 | 183 | //get the sine for that phase and scale it by the envelope |
| davolfman | 22:0307adac8c35 | 184 | int modulation = (fastSin(modulatorPhases[i]) * envelopeAmpsM[i])>>16; |
| davolfman | 22:0307adac8c35 | 185 | |
| davolfman | 22:0307adac8c35 | 186 | //scale it again by the modulation amount |
| davolfman | 22:0307adac8c35 | 187 | modulation = (modulation * modVol) >> 16; |
| davolfman | 22:0307adac8c35 | 188 | |
| davolfman | 22:0307adac8c35 | 189 | //calculate the new phase of the carrier, modualting frequency by the modulation |
| davolfman | 22:0307adac8c35 | 190 | carrierPhases[i] += carrierIncrements[i] + modulation; |
| davolfman | 22:0307adac8c35 | 191 | |
| davolfman | 22:0307adac8c35 | 192 | //get the sine for that carrier phase and scale by the envelope |
| davolfman | 22:0307adac8c35 | 193 | //additionally divide by 8 to allow 8 notes to play without saturating the DAC |
| davolfman | 22:0307adac8c35 | 194 | subsignal = (fastSin(carrierPhases[i]) * envelopeAmpsC[i])>>19; |
| davolfman | 22:0307adac8c35 | 195 | |
| davolfman | 22:0307adac8c35 | 196 | //add the sample for this note into the overall sample |
| davolfman | 22:0307adac8c35 | 197 | wave += subsignal; |
| davolfman | 12:3a1e7fde5040 | 198 | } |
| davolfman | 15:34ba7c2ef718 | 199 | |
| davolfman | 15:34ba7c2ef718 | 200 | } |
| davolfman | 22:0307adac8c35 | 201 | |
| davolfman | 22:0307adac8c35 | 202 | //Scale the complete sample by the volume |
| davolfman | 15:34ba7c2ef718 | 203 | wave = wave * Volume >> 16; |
| davolfman | 12:3a1e7fde5040 | 204 | |
| davolfman | 22:0307adac8c35 | 205 | //clip the sample to within the limits of the DAC if neccessary |
| davolfman | 15:34ba7c2ef718 | 206 | wave = (wave > 32767) ? 32767 : wave; |
| davolfman | 15:34ba7c2ef718 | 207 | wave = (wave < -32768) ? - 32768 : wave; |
| davolfman | 22:0307adac8c35 | 208 | |
| davolfman | 22:0307adac8c35 | 209 | //Center the waveform within the range of the DAC |
| davolfman | 15:34ba7c2ef718 | 210 | wave += 32768; |
| davolfman | 22:0307adac8c35 | 211 | |
| davolfman | 22:0307adac8c35 | 212 | //output the sample |
| davolfman | 15:34ba7c2ef718 | 213 | outMono.write_u16(wave); |
| davolfman | 1:f3350a372732 | 214 | } |
| davolfman | 0:b2f7400596ce | 215 | |
| davolfman | 0:b2f7400596ce | 216 | |
| davolfman | 0:b2f7400596ce | 217 | int main() { |
| davolfman | 2:5454dee210ed | 218 | int ratNumer; |
| davolfman | 18:4992aa537387 | 219 | int ratDenom; |
| davolfman | 18:4992aa537387 | 220 | int64_t keytemp; |
| davolfman | 18:4992aa537387 | 221 | int tempCarA, tempCarD, tempCarR, tempModA, tempModD, tempModR; |
| davolfman | 9:86c0035f5321 | 222 | |
| davolfman | 23:7a9ff5230149 | 223 | for(int i = 0; i < numKeys; ++i){ //zero out values |
| davolfman | 9:86c0035f5321 | 224 | carrierPhases[i] = 0; |
| davolfman | 9:86c0035f5321 | 225 | modulatorPhases[i] = 0; |
| davolfman | 9:86c0035f5321 | 226 | envelopeAmpsC[i] = 0; |
| davolfman | 9:86c0035f5321 | 227 | envelopeAmpsM[i] = 0; |
| davolfman | 9:86c0035f5321 | 228 | } |
| davolfman | 9:86c0035f5321 | 229 | |
| davolfman | 23:7a9ff5230149 | 230 | keyBank.mode(PullNone); // we're using external pullup resistors, |
| davolfman | 23:7a9ff5230149 | 231 | //and things weren't working this didn't fix it but better safe |
| davolfman | 23:7a9ff5230149 | 232 | |
| davolfman | 23:7a9ff5230149 | 233 | synthesisClock.attach(synthesize, 0.00005); //this runs every 50 us or 20khz |
| lenzi002 | 8:13b0594510de | 234 | |
| davolfman | 2:5454dee210ed | 235 | while(true){ |
| davolfman | 23:7a9ff5230149 | 236 | ratNumer = 0xf & ~ numerator; //read ratio numerator |
| davolfman | 23:7a9ff5230149 | 237 | ratDenom = 0xf & ~ denominator; //read ratio denominator |
| davolfman | 23:7a9ff5230149 | 238 | FMmult = (ratNumer << 16) / ratDenom; //FM multiplier = numerator / denominator |
| davolfman | 23:7a9ff5230149 | 239 | |
| davolfman | 23:7a9ff5230149 | 240 | Volume = (int)inVol.read_u16(); //read volume |
| davolfman | 2:5454dee210ed | 241 | |
| davolfman | 23:7a9ff5230149 | 242 | modVol = (int)inModAmt.read_u16(); //read modulation amount |
| davolfman | 12:3a1e7fde5040 | 243 | |
| davolfman | 23:7a9ff5230149 | 244 | //ensure we don't divide by zero on any of these |
| davolfman | 23:7a9ff5230149 | 245 | |
| davolfman | 23:7a9ff5230149 | 246 | //read carrier attack |
| davolfman | 18:4992aa537387 | 247 | tempCarA = inCarA.read_u16(); |
| davolfman | 18:4992aa537387 | 248 | if(! tempCarA) |
| davolfman | 9:86c0035f5321 | 249 | carA = 0xffff; |
| davolfman | 9:86c0035f5321 | 250 | else |
| davolfman | 18:4992aa537387 | 251 | carA = 0xffff / tempCarA; |
| davolfman | 9:86c0035f5321 | 252 | |
| davolfman | 23:7a9ff5230149 | 253 | //read carrier decay |
| davolfman | 18:4992aa537387 | 254 | tempCarD = inCarD.read_u16(); |
| davolfman | 18:4992aa537387 | 255 | if(! tempCarD) |
| davolfman | 9:86c0035f5321 | 256 | carD = 0xffff; |
| davolfman | 9:86c0035f5321 | 257 | else |
| davolfman | 18:4992aa537387 | 258 | carD = 0xffff / tempCarD; |
| davolfman | 9:86c0035f5321 | 259 | |
| davolfman | 23:7a9ff5230149 | 260 | //read carrier sustain |
| davolfman | 2:5454dee210ed | 261 | carS = (int)inCarS.read_u16(); |
| davolfman | 9:86c0035f5321 | 262 | |
| davolfman | 23:7a9ff5230149 | 263 | //read carrier release |
| davolfman | 18:4992aa537387 | 264 | tempCarR = inCarR.read_u16(); |
| davolfman | 18:4992aa537387 | 265 | if(! tempCarR) |
| davolfman | 9:86c0035f5321 | 266 | carR = 0xffff; |
| davolfman | 9:86c0035f5321 | 267 | else |
| davolfman | 18:4992aa537387 | 268 | carR = 0xffff / tempCarR; |
| davolfman | 2:5454dee210ed | 269 | |
| davolfman | 23:7a9ff5230149 | 270 | //read modulation attack |
| davolfman | 18:4992aa537387 | 271 | tempModA = inModA.read_u16(); |
| davolfman | 18:4992aa537387 | 272 | if(! tempModA) |
| davolfman | 9:86c0035f5321 | 273 | modA = 0xffff; |
| davolfman | 9:86c0035f5321 | 274 | else |
| davolfman | 18:4992aa537387 | 275 | modA = 0xffff / tempModA; |
| davolfman | 9:86c0035f5321 | 276 | |
| davolfman | 23:7a9ff5230149 | 277 | //read modulation decay |
| davolfman | 18:4992aa537387 | 278 | tempModD = inModD.read_u16(); |
| davolfman | 18:4992aa537387 | 279 | if(! tempModD) |
| davolfman | 9:86c0035f5321 | 280 | modD = 0xffff; |
| davolfman | 9:86c0035f5321 | 281 | else |
| davolfman | 18:4992aa537387 | 282 | modD = 0xffff / tempModD; |
| davolfman | 9:86c0035f5321 | 283 | |
| davolfman | 23:7a9ff5230149 | 284 | //read modulation sustain |
| davolfman | 2:5454dee210ed | 285 | modS = (int)inModS.read_u16(); |
| davolfman | 9:86c0035f5321 | 286 | |
| davolfman | 23:7a9ff5230149 | 287 | //read modulation release |
| davolfman | 18:4992aa537387 | 288 | tempModR = inModR.read_u16(); |
| davolfman | 18:4992aa537387 | 289 | if(! tempModR) |
| davolfman | 9:86c0035f5321 | 290 | modR = 0xffff; |
| davolfman | 9:86c0035f5321 | 291 | else |
| davolfman | 18:4992aa537387 | 292 | modR = 0xffff / tempModR; |
| davolfman | 13:29705e6bf718 | 293 | |
| davolfman | 23:7a9ff5230149 | 294 | keytemp = 0; //zero the keys before we start ORing on top of everything, |
| davolfman | 23:7a9ff5230149 | 295 | //keytemp is a buffer that waits until every key is read, then it pushes |
| davolfman | 23:7a9ff5230149 | 296 | //into the 'keyboard' variable |
| davolfman | 23:7a9ff5230149 | 297 | |
| davolfman | 23:7a9ff5230149 | 298 | for(int i = 0; i < 9; ++i) {//for all 9 half-octaves of the keyboard |
| davolfman | 23:7a9ff5230149 | 299 | bankSelect = (~(1 << i)) & bankSelect.mask();//supply power (as ground) to that bank |
| davolfman | 23:7a9ff5230149 | 300 | wait_us(200); //delay to get to get full reading |
| davolfman | 23:7a9ff5230149 | 301 | int shiftOffset = 6LL * i; //read the keys in the bank |
| davolfman | 13:29705e6bf718 | 302 | |
| davolfman | 23:7a9ff5230149 | 303 | //assign the bank to its corresponding position in the overall keyboard |
| davolfman | 9:86c0035f5321 | 304 | keytemp |= ((~(unsigned long long)keyBank) & (unsigned long long)keyBank.mask()) << (unsigned long long)shiftOffset; |
| davolfman | 7:b0cd74923bc6 | 305 | } |
| davolfman | 23:7a9ff5230149 | 306 | keytemp >>= 5;//shift 5 over because bank 0 only has 1 key and it is the 6th key (...111111 111111 100000) |
| davolfman | 9:86c0035f5321 | 307 | |
| davolfman | 23:7a9ff5230149 | 308 | keyboard = keytemp;//push our read values once we are complete. |
| davolfman | 23:7a9ff5230149 | 309 | //This only takes 1 cycle, especially since we are using 'keyboard' in the ISR |
| davolfman | 13:29705e6bf718 | 310 | |
| davolfman | 23:7a9ff5230149 | 311 | //wait_ms(10);//we've stopped bothering to wait here. it didn't make a difference |
| davolfman | 2:5454dee210ed | 312 | } |
| davolfman | 0:b2f7400596ce | 313 | } |
