Improve the volume response

Give it a pseudo- exponential characteristic and extend the volume control values to 16bit which gives more dynamic
pull/18/head^2
Thierry Frenkel 5 years ago
parent b7a56bd1f7
commit b559848598
  1. 12
      Open_Theremin_V3/application.cpp
  2. 55
      Open_Theremin_V3/ihandlers.cpp
  3. 2
      Open_Theremin_V3/ihandlers.h

@ -165,8 +165,7 @@ void Application::loop() {
int registerPotValue,registerPotValueL = 0; int registerPotValue,registerPotValueL = 0;
int wavePotValue,wavePotValueL = 0; int wavePotValue,wavePotValueL = 0;
uint8_t registerValue = 2; uint8_t registerValue = 2;
uint16_t tmpVolume;
mloop: // Main loop avoiding the GCC "optimization" mloop: // Main loop avoiding the GCC "optimization"
@ -182,7 +181,7 @@ void Application::loop() {
// New register pot configuration: // New register pot configuration:
// Left = -1 octave, Center = +/- 0, Right = +1 octave // Left = -1 octave, Center = +/- 0, Right = +1 octave
if(registerPotValue > 681) if (registerPotValue > 681)
{ {
registerValue = 1; registerValue = 1;
} else if(registerPotValue < 342) } else if(registerPotValue < 342)
@ -288,7 +287,10 @@ void Application::loop() {
// vol_v = vol_v - (1 + MAX_VOLUME - (volumePotValue << 2)); // vol_v = vol_v - (1 + MAX_VOLUME - (volumePotValue << 2));
vol_v = vol_v ; vol_v = vol_v ;
vol_v = max(vol_v, 0); vol_v = max(vol_v, 0);
vScaledVolume = vol_v >> 4; tmpVolume = vol_v >> 4;
// Give vScaledVolume a pseudo-exponential characteristic:
vScaledVolume = tmpVolume * (tmpVolume + 2);
volumeValueAvailable = false; volumeValueAvailable = false;
} }
@ -494,7 +496,7 @@ void Application::hzToAddVal(float hz) {
} }
void Application::playNote(float hz, uint16_t milliseconds = 500, uint8_t volume = 255) { void Application::playNote(float hz, uint16_t milliseconds = 500, uint8_t volume = 255) {
vScaledVolume = volume; vScaledVolume = volume * (volume + 2);
hzToAddVal(hz); hzToAddVal(hz);
millitimer(milliseconds); millitimer(milliseconds);
vScaledVolume = 0; vScaledVolume = 0;

@ -25,7 +25,7 @@ const int16_t* const wavetables[] = { //Fixed following a suggestion by Michael
sine_table8 sine_table8
}; };
static const uint32_t MCP_DAC_BASE = 2047; static const uint32_t MCP_DAC_BASE = 2048;
#define INT0_STATE (PIND & (1<<PORTD2)) #define INT0_STATE (PIND & (1<<PORTD2))
#define PC_STATE (PINB & (1<<PORTB0)) #define PC_STATE (PINB & (1<<PORTB0))
@ -38,7 +38,7 @@ static const uint32_t MCP_DAC_BASE = 2047;
#include "hw.h" #include "hw.h"
#endif #endif
volatile uint8_t vScaledVolume = 0; volatile uint16_t vScaledVolume = 0;
volatile uint16_t vPointerIncrement = 0; volatile uint16_t vPointerIncrement = 0;
volatile uint16_t pitch = 0; // Pitch value volatile uint16_t pitch = 0; // Pitch value
@ -104,29 +104,13 @@ void ihInitialiseVolumeMeasurement() //Measurement of variable frequency oscilla
} }
/* signed 16 bit by 8 bit multiplication */
static inline uint32_t mulsu_16_8(uint16_t a, uint8_t b)
{
uint32_t product;
asm (
"mul %A1, %2\n\t"
"movw %A0, r0\n\t"
"clr %C0\n\t"
"clr %D0\n\t"
"mulsu %B1, %2\n\t"
"add %B0, r0\n\t"
"adc %C0, r1\n\t"
"clr r1"
:
"=&r" (product)
:
"r" (a), "r" (b));
return product;
}
/* Externaly generated 31250 Hz Interrupt for WAVE generator (32us) */ /* Externaly generated 31250 Hz Interrupt for WAVE generator (32us) */
ISR (INT1_vect) { ISR (INT1_vect) {
// Interrupt takes up a total of 14us plus overhead when interrupted itself. // Interrupt takes up a total of 16us plus overhead when interrupted itself.
// Added by ThF 20200419
#ifdef TH_DEBUG
HW_LED2_ON;
#endif
// Latch previously written DAC value: // Latch previously written DAC value:
SPImcpDAClatch(); SPImcpDAClatch();
@ -136,7 +120,7 @@ ISR (INT1_vect) {
interrupts(); interrupts();
int16_t waveSample; int16_t waveSample;
uint32_t scaledSample; uint32_t scaledSample = 0;
uint16_t offset = (uint16_t)(pointer >> 6) & 0x3ff; uint16_t offset = (uint16_t)(pointer >> 6) & 0x3ff;
#if CV_ENABLED // Generator for CV output #if CV_ENABLED // Generator for CV output
@ -149,22 +133,11 @@ ISR (INT1_vect) {
// Read next wave table value // Read next wave table value
waveSample = (int16_t)pgm_read_word_near(wavetables[vWavetableSelector] + offset); waveSample = (int16_t)pgm_read_word_near(wavetables[vWavetableSelector] + offset);
// multiply 16 bit wave number by 8 bit volume value (11.2us / 5.4us) scaledSample = ((int32_t)waveSample * (uint32_t)vScaledVolume) >> 16;
scaledSample = MCP_DAC_BASE + (mulsu_16_8(waveSample, vScaledVolume) >> 8);
// Added by ThF 20200419 SPImcpDACsend(scaledSample + MCP_DAC_BASE); //Send result to Digital to Analogue Converter (audio out) (6 us)
#ifdef TH_DEBUG
HW_LED2_ON;
#endif
SPImcpDACsend(scaledSample); //Send result to Digital to Analogue Converter (audio out) (6 us) pointer += vPointerIncrement; // increment table pointer (ca. 2us)
// Added by ThF 20200419
#ifdef TH_DEBUG
HW_LED2_OFF;
#endif
pointer = pointer + vPointerIncrement; // increment table pointer (ca. 2us)
#endif //CV play sound #endif //CV play sound
incrementTimer(); // update 32us timer incrementTimer(); // update 32us timer
@ -195,6 +168,10 @@ ISR (INT1_vect) {
noInterrupts(); noInterrupts();
enableInt1(); enableInt1();
// Added by ThF 20200419
#ifdef TH_DEBUG
HW_LED2_OFF;
#endif
} }
/* VOLUME read - interrupt service routine for capturing volume counter value */ /* VOLUME read - interrupt service routine for capturing volume counter value */
@ -221,5 +198,3 @@ ISR(TIMER1_OVF_vect)
{ {
timer_overflow_counter++; timer_overflow_counter++;
} }

@ -3,7 +3,7 @@
extern volatile uint16_t pitch; // Pitch value extern volatile uint16_t pitch; // Pitch value
extern volatile uint16_t vol; // Volume value extern volatile uint16_t vol; // Volume value
extern volatile uint8_t vScaledVolume; // Volume byte extern volatile uint16_t vScaledVolume; // Volume byte
extern volatile uint16_t pitch_counter; // Pitch counter extern volatile uint16_t pitch_counter; // Pitch counter
extern volatile uint16_t pitch_counter_l; // Last value of pitch counter extern volatile uint16_t pitch_counter_l; // Last value of pitch counter

Loading…
Cancel
Save