Browse Source

Increase AudioEffectEnvelope numerical resolution

fixes #102
dds
PaulStoffregen 7 years ago
parent
commit
8a5d715dda
2 changed files with 35 additions and 24 deletions
  1. +24
    -17
      effect_envelope.cpp
  2. +11
    -7
      effect_envelope.h

+ 24
- 17
effect_envelope.cpp View File

@@ -1,5 +1,5 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
* Copyright (c) 2017, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
@@ -37,15 +37,15 @@
void AudioEffectEnvelope::noteOn(void)
{
__disable_irq();
mult = 0;
mult_hires = 0;
count = delay_count;
if (count > 0) {
state = STATE_DELAY;
inc = 0;
inc_hires = 0;
} else {
state = STATE_ATTACK;
count = attack_count;
inc = (0x10000 / count) >> 3;
inc_hires = 0x40000000 / (int32_t)count;
}
__enable_irq();
}
@@ -53,10 +53,11 @@ void AudioEffectEnvelope::noteOn(void)
void AudioEffectEnvelope::noteOff(void)
{
__disable_irq();
state = STATE_RELEASE;
count = release_count;
mult = sustain_mult;
inc = (-mult / ((int32_t)count << 3));
if (state != STATE_IDLE) {
state = STATE_RELEASE;
count = release_count;
inc_hires = (-mult_hires) / (int32_t)count;
}
__enable_irq();
}

@@ -82,24 +83,24 @@ void AudioEffectEnvelope::update(void)
count = hold_count;
if (count > 0) {
state = STATE_HOLD;
mult = 0x10000;
inc = 0;
mult_hires = 0x40000000;
inc_hires = 0;
} else {
count = decay_count;
state = STATE_DECAY;
inc = ((sustain_mult - 0x10000) / ((int32_t)count << 3));
count = decay_count;
inc_hires = (sustain_mult - 0x40000000) / (int32_t)count;
}
continue;
} else if (state == STATE_HOLD) {
state = STATE_DECAY;
count = decay_count;
inc = ((sustain_mult - 0x10000) / (int32_t)count) >> 3;
inc_hires = (sustain_mult - 0x40000000) / (int32_t)count;
continue;
} else if (state == STATE_DECAY) {
state = STATE_SUSTAIN;
count = 0xFFFF;
mult = sustain_mult;
inc = 0;
mult_hires = sustain_mult;
inc_hires = 0;
} else if (state == STATE_SUSTAIN) {
count = 0xFFFF;
} else if (state == STATE_RELEASE) {
@@ -114,11 +115,14 @@ void AudioEffectEnvelope::update(void)
} else if (state == STATE_DELAY) {
state = STATE_ATTACK;
count = attack_count;
inc = (0x10000 / count) >> 3;
inc_hires = 0x40000000 / count;
continue;
}
}
// process 8 samples, using only mult and inc

int32_t mult = mult_hires >> 14;
int32_t inc = inc_hires >> 17;
// process 8 samples, using only mult and inc (16 bit resolution)
sample12 = *p++;
sample34 = *p++;
sample56 = *p++;
@@ -148,6 +152,9 @@ void AudioEffectEnvelope::update(void)
*p++ = sample34;
*p++ = sample56;
*p++ = sample78;
// adjust the long-term gain using 30 bit resolution (fix #102)
// https://github.com/PaulStoffregen/Audio/issues/102
mult_hires += inc_hires;
count--;
}
transmit(block);

+ 11
- 7
effect_envelope.h View File

@@ -1,5 +1,5 @@
/* Audio Library for Teensy 3.X
* Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
* Copyright (c) 2017, Paul Stoffregen, paul@pjrc.com
*
* Development of this audio library was funded by PJRC.COM, LLC by sales of
* Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
@@ -51,20 +51,23 @@ public:
}
void attack(float milliseconds) {
attack_count = milliseconds2count(milliseconds);
if (attack_count == 0) attack_count = 1;
}
void hold(float milliseconds) {
hold_count = milliseconds2count(milliseconds);
}
void decay(float milliseconds) {
decay_count = milliseconds2count(milliseconds);
if (decay_count == 0) decay_count = 1;
}
void sustain(float level) {
if (level < 0.0) level = 0;
else if (level > 1.0) level = 1.0;
sustain_mult = level * 65536.0;
sustain_mult = level * 1073741824.0;
}
void release(float milliseconds) {
release_count = milliseconds2count(milliseconds);
if (release_count == 0) release_count = 1;
}
using AudioStream::release;
virtual void update(void);
@@ -72,15 +75,16 @@ private:
uint16_t milliseconds2count(float milliseconds) {
if (milliseconds < 0.0) milliseconds = 0.0;
uint32_t c = ((uint32_t)(milliseconds*SAMPLES_PER_MSEC)+7)>>3;
if (c > 1103) return 1103; // allow up to 200 ms
if (c > 65535) c = 65535; // allow up to 11.88 seconds
return c;
}
audio_block_t *inputQueueArray[1];
// state
uint8_t state; // idle, delay, attack, hold, decay, sustain, release
uint16_t count; // how much time remains in this state, in 8 sample units
int32_t mult; // attenuation, 0=off, 0x10000=unity gain
int32_t inc; // amount to change mult on each sample
uint8_t state; // idle, delay, attack, hold, decay, sustain, release
uint16_t count; // how much time remains in this state, in 8 sample units
int32_t mult_hires; // attenuation, 0=off, 0x40000000=unity gain
int32_t inc_hires; // amount to change mult_hires every 8 samples

// settings
uint16_t delay_count;
uint16_t attack_count;

Loading…
Cancel
Save