mirror of
https://github.com/supleed2/ELEC60013-ES-CW2.git
synced 2024-12-22 21:55:50 +00:00
Added coarse and fine volume control
This commit is contained in:
parent
483b87e216
commit
555579da53
12
src/knob.cpp
12
src/knob.cpp
|
@ -41,4 +41,14 @@ void Knob::updateRotation(bool ANew, bool BNew) {
|
||||||
rotPlusOnePrev = rotPlusOneNew;
|
rotPlusOnePrev = rotPlusOneNew;
|
||||||
rotMinOnePrev = rotMinOneNew;
|
rotMinOnePrev = rotMinOneNew;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
void Knob::changeLimitsVolume(int newMinimum, int newMaximum) {
|
||||||
|
if(newMaximum>maximum){
|
||||||
|
rotation = rotation<<1;
|
||||||
|
}else if(newMaximum<maximum){
|
||||||
|
rotation = rotation>>1;
|
||||||
|
}else{}
|
||||||
|
minimum = newMinimum;
|
||||||
|
maximum = newMaximum;
|
||||||
|
};
|
|
@ -14,6 +14,8 @@ public:
|
||||||
int getRotation();
|
int getRotation();
|
||||||
|
|
||||||
void updateRotation(bool ANew, bool BNew);
|
void updateRotation(bool ANew, bool BNew);
|
||||||
|
|
||||||
|
void changeLimitsVolume(int newMinimum, int newMaximum);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
52
src/main.cpp
52
src/main.cpp
|
@ -8,6 +8,8 @@
|
||||||
volatile int32_t currentStepSize;
|
volatile int32_t currentStepSize;
|
||||||
volatile uint8_t keyArray[7];
|
volatile uint8_t keyArray[7];
|
||||||
volatile int8_t volume;
|
volatile int8_t volume;
|
||||||
|
volatile bool volumeFiner;
|
||||||
|
int8_t volumeHistory = 0;
|
||||||
SemaphoreHandle_t keyArrayMutex;
|
SemaphoreHandle_t keyArrayMutex;
|
||||||
Knob K1(0,6);
|
Knob K1(0,6);
|
||||||
Knob K3(0,10);
|
Knob K3(0,10);
|
||||||
|
@ -18,7 +20,6 @@ enum wave{SQR=0,SAW,TRI,SIN};
|
||||||
const uint32_t interval = 10; // Display update interval
|
const uint32_t interval = 10; // Display update interval
|
||||||
const uint8_t octave = 4; // Octave to start on
|
const uint8_t octave = 4; // Octave to start on
|
||||||
const uint32_t samplingRate = 44100; // Sampling rate
|
const uint32_t samplingRate = 44100; // Sampling rate
|
||||||
const int8_t volumeMax = 10;
|
|
||||||
const int32_t stepSizes[] = {
|
const int32_t stepSizes[] = {
|
||||||
0, 6370029, 6748811, 7150116, 7575284, 8025734, 8502969, 9008582,
|
0, 6370029, 6748811, 7150116, 7575284, 8025734, 8502969, 9008582,
|
||||||
9544260, 10111791, 10713070, 11350102, 12025014, 12740059, 13497622,
|
9544260, 10111791, 10713070, 11350102, 12025014, 12740059, 13497622,
|
||||||
|
@ -127,13 +128,18 @@ uint16_t getTopKey(volatile uint8_t array[]) {
|
||||||
void sampleISR(){
|
void sampleISR(){
|
||||||
static int32_t phaseAcc = 0;
|
static int32_t phaseAcc = 0;
|
||||||
phaseAcc += currentStepSize;
|
phaseAcc += currentStepSize;
|
||||||
int32_t Vout = (phaseAcc >> 16)*25*volume;
|
int32_t Vout = phaseAcc >> 16;
|
||||||
Vout = Vout >> 16;
|
if(volumeFiner){
|
||||||
|
Vout = (Vout*12*volume) >> 16;
|
||||||
|
}else{ // 25 = floor( (1/10) << 8 )
|
||||||
|
Vout = (Vout*25*volume) >> 16; //scale by 2*8 cuz 16-bit*8-bit=24-bit -> scale by 16 to get to 8
|
||||||
|
}
|
||||||
analogWrite(OUTR_PIN, Vout + 128);
|
analogWrite(OUTR_PIN, Vout + 128);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scanKeysTask(void * pvParameters){
|
void scanKeysTask(void * pvParameters){
|
||||||
uint8_t keyArrayCopy[7];
|
uint8_t keyArrayCopy[7];
|
||||||
|
bool volumeFinerNext;
|
||||||
const TickType_t xFrequency = 50/portTICK_PERIOD_MS;
|
const TickType_t xFrequency = 50/portTICK_PERIOD_MS;
|
||||||
TickType_t xLastWakeTime = xTaskGetTickCount();
|
TickType_t xLastWakeTime = xTaskGetTickCount();
|
||||||
while(1){
|
while(1){
|
||||||
|
@ -149,8 +155,16 @@ void scanKeysTask(void * pvParameters){
|
||||||
digitalToggle(LED_BUILTIN);
|
digitalToggle(LED_BUILTIN);
|
||||||
__atomic_store_n(¤tStepSize, stepSizes[getTopKey(keyArrayCopy)], __ATOMIC_RELAXED);
|
__atomic_store_n(¤tStepSize, stepSizes[getTopKey(keyArrayCopy)], __ATOMIC_RELAXED);
|
||||||
K1.updateRotation(keyArrayCopy[4] & 0x1, keyArrayCopy[4] & 0x2);
|
K1.updateRotation(keyArrayCopy[4] & 0x1, keyArrayCopy[4] & 0x2);
|
||||||
|
if(volumeFiner){
|
||||||
|
K3.changeLimitsVolume(0,20);
|
||||||
|
}else{
|
||||||
|
K3.changeLimitsVolume(0,10);
|
||||||
|
}
|
||||||
K3.updateRotation(keyArrayCopy[3] & 0x1, keyArrayCopy[3] & 0x2);
|
K3.updateRotation(keyArrayCopy[3] & 0x1, keyArrayCopy[3] & 0x2);
|
||||||
__atomic_store_n(&volume, K3.getRotation(), __ATOMIC_RELAXED);
|
__atomic_store_n(&volume, K3.getRotation(), __ATOMIC_RELAXED);
|
||||||
|
volumeHistory = (volumeHistory << 1) + ((keyArrayCopy[5]&0x2)>>1);
|
||||||
|
volumeFinerNext = ((!(volumeHistory==1))&volumeFiner) | ((volumeHistory==1)&!volumeFiner);
|
||||||
|
__atomic_store_n(&volumeFiner, volumeFinerNext, __ATOMIC_RELAXED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,20 +206,24 @@ void displayUpdateTask(void * pvParameters){
|
||||||
u8g2.setCursor(14, 30);
|
u8g2.setCursor(14, 30);
|
||||||
u8g2.print(octave);
|
u8g2.print(octave);
|
||||||
|
|
||||||
// Print volume indicator and bar
|
// Print volume indicator
|
||||||
int K3_rot = K3.getRotation();
|
if(!volumeFiner){
|
||||||
if(K3_rot==0){
|
if(volume==0){
|
||||||
u8g2.drawXBM(116,22,13,9,volumes[5]);
|
u8g2.drawXBM(116,22,13,9,volumes[5]);
|
||||||
}else if(K3_rot<3){
|
}else if(volume<3){
|
||||||
u8g2.drawXBM(116,22,13,9,volumes[4]);
|
u8g2.drawXBM(116,22,13,9,volumes[4]);
|
||||||
}else if(K3_rot<5){
|
}else if(volume<5){
|
||||||
u8g2.drawXBM(116,22,13,9,volumes[3]);
|
u8g2.drawXBM(116,22,13,9,volumes[3]);
|
||||||
}else if(K3_rot<7){
|
}else if(volume<7){
|
||||||
u8g2.drawXBM(116,22,13,9,volumes[2]);
|
u8g2.drawXBM(116,22,13,9,volumes[2]);
|
||||||
}else if(K3_rot<9){
|
}else if(volume<9){
|
||||||
u8g2.drawXBM(116,22,13,9,volumes[1]);
|
u8g2.drawXBM(116,22,13,9,volumes[1]);
|
||||||
}else if(K3_rot<11){
|
}else if(volume<11){
|
||||||
u8g2.drawXBM(116,22,13,9,volumes[0]);
|
u8g2.drawXBM(116,22,13,9,volumes[0]);
|
||||||
|
};
|
||||||
|
}else{
|
||||||
|
u8g2.setCursor(122, 30);
|
||||||
|
u8g2.print(volume/2);
|
||||||
};
|
};
|
||||||
u8g2.sendBuffer(); // transfer internal memory to the display
|
u8g2.sendBuffer(); // transfer internal memory to the display
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue