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
- Committer:
- lenzi002
- Date:
- 2017-12-07
- Revision:
- 8:13b0594510de
- Parent:
- 7:b0cd74923bc6
- Child:
- 9:86c0035f5321
File content as of revision 8:13b0594510de:
#include "mbed.h"
#include "sintable.h"
AnalogOut DAC0(PA_4);//Not labeled in the docs for the f401, but seems to be for all
//AnalogOut DAC1(PA_5);
AnalogIn ADC0(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 ADC6(PA_6);
AnalogIn ADC7(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 ADC10(PC_0);
AnalogIn ADC11(PC_1);
AnalogIn ADC12(PC_2);
AnalogIn ADC13(PC_3);
AnalogIn ADC14(PC_4);
AnalogIn ADC15(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);
//Renaming ports
#define inVol ADC0
//#define inModAmt ADC1
#define inCarA ADC6
#define inCarD ADC7
#define inCarS ADC10
#define inCarR ADC11
#define inModA ADC12
#define inModD ADC13
#define inModS ADC14
#define inModR ADC15
#define outMono DAC0
#define numKeys 49
#define PI M_PI
//constants
const int carrierIncrements[] = {107, 113, 120, 127, 135, 143, 151, 160, 170,
180, 190, 202, 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};
const int attackLimit = (0x1 << 16) - 1;
#define U_PI 3.14159265358979f
const int fixed2pi = (int) ((2.0 * U_PI) * (0x1 << 16));
//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;
int modAmpI;
int carAmpS;
//bool keysPressed[numKeys];
int64_t keyboard;
int carrierPhases[numKeys];
int modulatorPhases[numKeys];
short envelopeStatesC[numKeys];
short envelopeStatesM[numKeys];
int envelopeAmpsC[numKeys];
int envelopeAmpsM[numKeys];
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(){
carAmpS = 0;
for(int i = 0; i < numKeys; ++i){
if(keyboard & (0x1 << i)){
if(envelopeStatesC[i] < 2)
envelopeStatesC[i] = 4;
if(envelopeStatesM[i] < 2)
envelopeStatesM[i] = 4;
if(envelopeStatesC[i] == 4){
envelopeAmpsC[i] += carA;
if(envelopeAmpsC[i] >= attackLimit){
envelopeAmpsC[i] = attackLimit;
envelopeStatesC[i] = 3;
}
}
if(envelopeStatesM[i] == 4){
envelopeAmpsM[i] += modA;
if(envelopeAmpsM[i] >= attackLimit){
envelopeAmpsM[i] = attackLimit;
envelopeStatesM[i] = 3;
}
}
if(envelopeStatesC[i] == 3){
envelopeAmpsC[i] += carD;
if(envelopeAmpsC[i] <= carS){
envelopeAmpsC[i] = carS;
envelopeStatesC[i] = 2;
}
}
if(envelopeStatesM[i] == 3){
envelopeAmpsM[i] += modD;
if(envelopeAmpsM[i] <= modS){
envelopeAmpsM[i] = modS;
envelopeStatesM[i] = 2;
}
}
}else{
if(envelopeStatesC[i] > 1)
envelopeStatesC[i] = 1;
if(envelopeStatesM[i] > 1)
envelopeStatesM[i] = 1;
if(envelopeStatesC[i] == 1){
if(envelopeAmpsC[i] <= 0){
envelopeStatesC[i] = 0;
envelopeAmpsC[i] = 0;
}else{
envelopeAmpsC[i] -= carR;
}
}
if(envelopeStatesM[i] == 1){
if(envelopeAmpsM[i] <= 0){
envelopeStatesM[i] = 0;
envelopeAmpsM[i] = 0;
}else{
envelopeAmpsM[i] -= modR;
}
}
}
if(envelopeAmpsC[i] > 0){
modulatorPhases[i] += (FMmult * carrierIncrements[i]) >> 16;
modAmpI = fastSin((((modulatorPhases[i] * envelopeAmpsM[i]) >> 16)
* modVol) >> 16);
carrierPhases[i] += ((carrierIncrements[i] + modAmpI) * fixed2pi) >> 16;
carAmpS += (fastSin(carrierPhases[i]) * envelopeAmpsC[i]) >> 16;
}
}
outMono.write_u16(((carAmpS / numKeys) * Volume) >> 16);
}
int main() {
int ratNumer;
int ratDenom;
keyBank.mode(PullNone);
while(true){
ratNumer = 0xf & ~ numerator;
ratDenom = 0xf & ~ denominator;
FMmult = (ratNumer << 16) / ratDenom;
Volume = (int)inVol.read_u16();
modVol = (int)inModAmt.read_u16();
carA = 0xffff / ((int)inCarA.read_u16());
carD = 0xffff / ((int)inCarD.read_u16());
carS = (int)inCarS.read_u16();
carR = 0xffff / ((int)inCarR.read_u16());
modA = 0xffff / ((int)inModA.read_u16());
modD = 0xffff / ((int)inModD.read_u16());
modS = (int)inModS.read_u16();
modR = 0xffff / ((int)inModR.read_u16());
//THIS IS CORRECT (1 means the key is connected)
// B8 B7 B6 B5 B4 B3 B2 B1 B0
// |----||----||----||----||----||----||----||----||
//0000000000000001111111111111111111111111111111111111111111111111
//
//THIS IS NOT CORRECT (1 means the key is connected)
// B8 B7 B6 B5 B4 B3 B2 B1 B0
// |----||----||----||----||----||----||----||----||----|
//0000000000111111111111111111111111111111111111111111111111000001
//Thus, we need to subtract 5 from our shift for every bank > 0
//'keyboard' should be uint64_t and not int64_t b/c keyboard&=~62 will make it negative, which isn't a huge deal really
keyboard = 0; //zero the keys before we start ORing on top of everything
for(int i = 0; i < 9; ++i) { //removed <= 9 because there is not 10 banks
bankSelect = (~(1LL << i)) & (unsigned long long)bankSelect.mask();
wait_us(200);
int shiftOffset = 6LL * i;
//shiftOffset -= 5; //bank 0 only has 1 key, so to prevent 5 missing keys and bits we subtract 5 for every bank > 0
//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
keyboard |= ((~(unsigned long long)keyBank) & (unsigned long long)keyBank.mask()) << (unsigned long long)shiftOffset;
}
keyboard >>= 5;
/*for(int i = 63; i >= 0; i--) {
pc.printf("%d", !!(keyboard & (1LL << i)));
}
pc.printf("\r\n");
wait_ms(200);*/
}
}
