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 4 years ago
parent b7a56bd1f7
commit b559848598
  1. 32
      Open_Theremin_V3/application.cpp
  2. 59
      Open_Theremin_V3/ihandlers.cpp
  3. 4
      Open_Theremin_V3/ihandlers.h

@ -82,7 +82,7 @@ unsigned long Application::GetQMeasurement()
{
int qn=0;
TCCR1B = (1<<CS10);
TCCR1B = (1<<CS10);
while(!(PIND & (1<<PORTD3)));
while((PIND & (1<<PORTD3)));
@ -97,7 +97,7 @@ while((PIND & (1<<PORTD3)));
TCCR1B = 0;
TCCR1B = 0;
unsigned long frequency = TCNT1;
unsigned long temp = 65536*(unsigned long)timer_overflow_counter;
@ -112,11 +112,11 @@ unsigned long Application::GetPitchMeasurement()
{
TCNT1 = 0;
timer_overflow_counter = 0;
TCCR1B = (1<<CS12) | (1<<CS11) | (1<<CS10);
TCCR1B = (1<<CS12) | (1<<CS11) | (1<<CS10);
delay(1000);
TCCR1B = 0;
TCCR1B = 0;
unsigned long frequency = TCNT1;
unsigned long temp = 65536*(unsigned long)timer_overflow_counter;
@ -131,11 +131,11 @@ unsigned long Application::GetVolumeMeasurement()
TCNT0=0;
TCNT1=49911;
TCCR0B = (1<<CS02) | (1<<CS01) | (1<<CS00); // //External clock source on T0 pin. Clock on rising edge.
TCCR0B = (1<<CS02) | (1<<CS01) | (1<<CS00); // //External clock source on T0 pin. Clock on rising edge.
TIFR1 = (1<<TOV1); //Timer1 INT Flag Reg: Clear Timer Overflow Flag
while(!(TIFR1&((1<<TOV1)))); // on Timer 1 overflow (1s)
TCCR0B = 0; // Stop TimerCounter 0
TCCR0B = 0; // Stop TimerCounter 0
unsigned long frequency = TCNT0; // get counter 0 value
unsigned long temp = (unsigned long)timer_overflow_counter; // and overflow counter
@ -165,8 +165,7 @@ void Application::loop() {
int registerPotValue,registerPotValueL = 0;
int wavePotValue,wavePotValueL = 0;
uint8_t registerValue = 2;
uint16_t tmpVolume;
mloop: // Main loop avoiding the GCC "optimization"
@ -182,15 +181,15 @@ void Application::loop() {
// New register pot configuration:
// Left = -1 octave, Center = +/- 0, Right = +1 octave
if(registerPotValue > 681)
if (registerPotValue > 681)
{
registerValue = 1;
registerValue = 1;
} else if(registerPotValue < 342)
{
registerValue = 3;
registerValue = 3;
} else
{
registerValue = 2;
registerValue = 2;
}
if (_state == PLAYING && HW_BUTTON_PRESSED) {
@ -288,9 +287,12 @@ void Application::loop() {
// vol_v = vol_v - (1 + MAX_VOLUME - (volumePotValue << 2));
vol_v = vol_v ;
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;
}
goto mloop; // End of main loop
@ -494,7 +496,7 @@ void Application::hzToAddVal(float hz) {
}
void Application::playNote(float hz, uint16_t milliseconds = 500, uint8_t volume = 255) {
vScaledVolume = volume;
vScaledVolume = volume * (volume + 2);
hzToAddVal(hz);
millitimer(milliseconds);
vScaledVolume = 0;

@ -25,7 +25,7 @@ const int16_t* const wavetables[] = { //Fixed following a suggestion by Michael
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 PC_STATE (PINB & (1<<PORTB0))
@ -38,7 +38,7 @@ static const uint32_t MCP_DAC_BASE = 2047;
#include "hw.h"
#endif
volatile uint8_t vScaledVolume = 0;
volatile uint16_t vScaledVolume = 0;
volatile uint16_t vPointerIncrement = 0;
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) */
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:
SPImcpDAClatch();
@ -136,7 +120,7 @@ ISR (INT1_vect) {
interrupts();
int16_t waveSample;
uint32_t scaledSample;
uint32_t scaledSample = 0;
uint16_t offset = (uint16_t)(pointer >> 6) & 0x3ff;
#if CV_ENABLED // Generator for CV output
@ -146,25 +130,14 @@ ISR (INT1_vect) {
#else //Play sound
// Read next wave table value
waveSample = (int16_t)pgm_read_word_near(wavetables[vWavetableSelector] + offset);
// Read next wave table value
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 = MCP_DAC_BASE + (mulsu_16_8(waveSample, vScaledVolume) >> 8);
scaledSample = ((int32_t)waveSample * (uint32_t)vScaledVolume) >> 16;
// Added by ThF 20200419
#ifdef TH_DEBUG
HW_LED2_ON;
#endif
SPImcpDACsend(scaledSample + MCP_DAC_BASE); //Send result to Digital to Analogue Converter (audio out) (6 us)
SPImcpDACsend(scaledSample); //Send result to Digital to Analogue Converter (audio out) (6 us)
// Added by ThF 20200419
#ifdef TH_DEBUG
HW_LED2_OFF;
#endif
pointer = pointer + vPointerIncrement; // increment table pointer (ca. 2us)
pointer += vPointerIncrement; // increment table pointer (ca. 2us)
#endif //CV play sound
incrementTimer(); // update 32us timer
@ -195,6 +168,10 @@ ISR (INT1_vect) {
noInterrupts();
enableInt1();
// Added by ThF 20200419
#ifdef TH_DEBUG
HW_LED2_OFF;
#endif
}
/* VOLUME read - interrupt service routine for capturing volume counter value */
@ -221,5 +198,3 @@ ISR(TIMER1_OVF_vect)
{
timer_overflow_counter++;
}

@ -3,7 +3,7 @@
extern volatile uint16_t pitch; // Pitch 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_l; // Last value of pitch counter
@ -19,7 +19,7 @@ extern volatile bool pitchValueAvailable; // Pitch read flag
extern volatile bool reenableInt1; // Pitch read flag
extern volatile uint8_t vWavetableSelector;
extern volatile uint16_t vPointerIncrement; // Table pointer increment
extern volatile uint16_t vPointerIncrement; // Table pointer increment
inline void resetPitchFlag() { pitchValueAvailable = false; }
inline void resetVolFlag() { volumeValueAvailable = false; }

Loading…
Cancel
Save