Added coarse and fine volume control

This commit is contained in:
Kacper 2022-03-23 22:26:20 +00:00
parent 483b87e216
commit 555579da53
3 changed files with 48 additions and 18 deletions

View file

@ -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;
};

View file

@ -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

View file

@ -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(&currentStepSize, stepSizes[getTopKey(keyArrayCopy)], __ATOMIC_RELAXED); __atomic_store_n(&currentStepSize, 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
} }