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.
main.cpp
- Committer:
- davolfman
- Date:
- 2017-12-10
- Revision:
- 17:65437c94ab1b
- Parent:
- 16:c2f912cdd919
- Child:
- 18:4992aa537387
File content as of revision 17:65437c94ab1b:
#include "mbed.h"
#include "sintable.h"
AnalogOut outMono(PA_4);//Not labeled in the docs for the f401, but seems to be for all
//AnalogOut DAC1(PA_5);
AnalogIn inVol(PA_0);
AnalogIn inModAmt(PA_1);
//AnalogIn ADC2(PA_2);//these are the uart pins!!
//AnalogIn ADC3(PA_3);//these are the uart pins!!
//AnalogIn ADC4(PA_4);//we're using these for output
//AnalogIn ADC5(PA_5);//we're using these for output
AnalogIn inCarA(PA_6);
AnalogIn inCarD(PA_7);
//AnalogIn ADC8(PB_0);//lets leave the 2 we aren't using in a single port
//AnalogIn ADC9(PB_1);//that way we know there's not ADCs on one of them
AnalogIn inCarS(PC_0);
AnalogIn inCarR(PC_1);
AnalogIn inModA(PC_2);
AnalogIn inModD(PC_3);
AnalogIn inModS(PC_4);
AnalogIn inModR(PC_5);
//BusIn keyBank(PC_10, PC_11, PC_12, PC_13, PD_2, PH_1); old
BusIn keyBank(PH_1, PD_2, PC_13, PC_12, PC_11, PC_10);
BusOut bankSelect(PB_0, PB_1, PB_2, PB_3, PB_4, PB_5, PB_6, PB_7, PB_8);
BusIn numerator(PA_8, PA_9, PA_10, PA_11);
BusIn denominator(PA_12, PA_13, PA_14, PA_15);
//Serial pc(USBTX, USBRX);
Ticker synthesisClock;
#define numKeys 49
//constants
const int carrierIncrements[] = {214, 227, 240, 254, 270, 286, 303, 321, 340,
360, 381, 404, 428, 454, 481, 509, 540, 572, 606, 642, 680, 720, 763, 809,
857, 908, 962, 1019, 1080, 1144, 1212, 1284, 1360, 1441, 1527, 1618, 1714,
1816, 1924, 2039, 2160, 2288, 2424, 2568, 2721, 2883, 3055, 3236, 3429};
#define attackLimit 0xFFFF
#define U_PI 3.14159265358979
//non-constants
//Most of these will be recalculated or reset on every input cycle of the main
// loop, as appropriate
int FMmult;
int Volume;
int modVol;
int64_t keyboard;
int64_t modattack;
int64_t carattack;
int carrierPhases[numKeys];
int modulatorPhases[numKeys];
int envelopeAmpsC[numKeys];
int envelopeAmpsM[numKeys];
//int testTone = 0;
int modA;
int modD;
int modS;
int modR;
int carA;
int carD;
int carS;
int carR;
int fastSin(const int phase){
int index = (phase & 0x3ffc) >> 2;
int subindex = phase & 0x3;
int quadrant = (phase & 0xc000) >> 14;
int sum = 0;
switch (quadrant) {
case 0:
sum += (4 - subindex) * sinTable[index];
sum += subindex * sinTable[index+1];
break;
case 1:
sum += (4 - subindex) * sinTable[1+4095-index];
sum += subindex * sinTable[4095-index];
break;
case 2:
sum -= (4 - subindex) * sinTable[index];
sum -= subindex * sinTable[index+1];
break;
case 3:
sum -= (4 - subindex) * sinTable[1+4095-index];
sum -= subindex * sinTable[4095-index];
break;
}
sum = sum >> 2;
return sum;
}
void synthesize(){
int wave = 0;
int subsignal;
int64_t keymask;
//testTone = testTone + carrierIncrements[25] & 0xffff;
for(int64_t i = 0; i < numKeys; ++i){
subsignal = 0;
keymask = 1ll << i;
if(!(keymask & keyboard)){
carattack |= keymask;
modattack |= keymask;
if(envelopeAmpsC[i] > 0){
envelopeAmpsC[i] -= carR;
}
if(envelopeAmpsM[i] > 0){
envelopeAmpsM[i] -= carR;
}
}else{
if(envelopeAmpsC[i] <= 0){
carrierPhases[i] = 0;
modulatorPhases[i] = 0;
}
if(keymask & carattack){
if(envelopeAmpsC[i] < attackLimit ){
envelopeAmpsC[i] += carA;
}else{
envelopeAmpsC[i] = attackLimit;
carattack &= ~keymask;
}
}else{
if(envelopeAmpsC[i] > carS){
envelopeAmpsC[i] -= carD;
}
}
if(keymask & modattack){
if(envelopeAmpsM[i] < attackLimit){
envelopeAmpsM[i] += modA;
}else{
envelopeAmpsM[i] = attackLimit;
carattack &= ~keymask;
}
}else{
if(envelopeAmpsM[i] > modS){
envelopeAmpsM[i] -= modD;
}
}
if(envelopeAmpsC[i] > 0){
modulatorPhases[i] += (carrierIncrements[i] * FMmult)>> 16;
int modulation = (fastSin(modulatorPhases[i]) * envelopeAmpsM[i])>>16;
modulation = (modulation * modVol) >> 16;
carrierPhases[i] += carrierIncrements[i] + modulation;
subsignal = (fastSin(carrierPhases[i]) * envelopeAmpsC[i])>>16;
}
}
wave += subsignal >> 3;
}
//if(keyboard)
// wave += fastSin(testTone);
wave = wave * Volume >> 16;
//wave = wave << 3;
wave = (wave > 32767) ? 32767 : wave;
wave = (wave < -32768) ? - 32768 : wave;
wave += 32768;
outMono.write_u16(wave);
}
int main() {
int ratNumer;
int ratDenom;
int64_t keytemp = 0;
//pc.printf("Starting up...");
FMmult = 1;
Volume = 0;
modVol = 0;
keyboard = 0ll;
modattack = 0x1ffffffffffff;
carattack = 0x1ffffffffffff;
for(int i = 0; i < numKeys; ++i){
carrierPhases[i] = 0;
modulatorPhases[i] = 0;
envelopeAmpsC[i] = 0;
envelopeAmpsM[i] = 0;
}
modA = 0;
modD = 0;
modS = 0;
modR = 0;
carA = 0;
carD = 0;
carS = 0;
carR = 0;
keyBank.mode(PullNone);
synthesisClock.attach(synthesize, 0.00005);//debug
//pc.printf("done.\r\n");
while(true){
ratNumer = 0xf & ~ numerator;
ratDenom = 0xf & ~ denominator;
FMmult = (ratNumer << 16) / ratDenom;
Volume = (int)inVol.read_u16();
modVol = (int)inModAmt.read_u16();
if(! inCarA.read_u16())
carA = 0xffff;
else
carA = 0xffff / ((int)inCarA.read_u16());
if(! inCarD.read_u16())
carD = 0xffff;
else
carD = 0xffff / ((int)inCarD.read_u16());
carS = (int)inCarS.read_u16();
if(! inCarR.read_u16())
carR = 0xffff;
else
carR = 0xffff / ((int)inCarR.read_u16());
if(! inModA.read_u16())
modA = 0xffff;
else
modA = 0xffff / ((int)inModA.read_u16());
if(! inModD.read_u16())
modD = 0xffff;
else
modD = 0xffff / ((int)inModD.read_u16());
modS = (int)inModS.read_u16();
if(! inModR.read_u16())
modR = 0xffff;
else
modR = 0xffff / ((int)inModR.read_u16());
keytemp = 0; //zero the keys before we start ORing on top of everything
for(int i = 0; i < 9; ++i) {
bankSelect = (~(1 << i)) & bankSelect.mask();
wait_us(200);
int shiftOffset = 6LL * i;
keytemp |= ((~(unsigned long long)keyBank) & (unsigned long long)keyBank.mask()) << (unsigned long long)shiftOffset;
}
keytemp >>= 5;
keyboard = keytemp;
wait_ms(5);
}
}