소스 검색

Increase AudioEffectEnvelope numerical resolution

fixes #102
dds
PaulStoffregen 8 년 전
부모
커밋
8a5d715dda
2개의 변경된 파일35개의 추가작업 그리고 24개의 파일을 삭제
  1. +24
    -17
      effect_envelope.cpp
  2. +11
    -7
      effect_envelope.h

+ 24
- 17
effect_envelope.cpp 파일 보기

/* Audio Library for Teensy 3.X /* 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 * 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 * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
void AudioEffectEnvelope::noteOn(void) void AudioEffectEnvelope::noteOn(void)
{ {
__disable_irq(); __disable_irq();
mult = 0;
mult_hires = 0;
count = delay_count; count = delay_count;
if (count > 0) { if (count > 0) {
state = STATE_DELAY; state = STATE_DELAY;
inc = 0;
inc_hires = 0;
} else { } else {
state = STATE_ATTACK; state = STATE_ATTACK;
count = attack_count; count = attack_count;
inc = (0x10000 / count) >> 3;
inc_hires = 0x40000000 / (int32_t)count;
} }
__enable_irq(); __enable_irq();
} }
void AudioEffectEnvelope::noteOff(void) void AudioEffectEnvelope::noteOff(void)
{ {
__disable_irq(); __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(); __enable_irq();
} }


count = hold_count; count = hold_count;
if (count > 0) { if (count > 0) {
state = STATE_HOLD; state = STATE_HOLD;
mult = 0x10000;
inc = 0;
mult_hires = 0x40000000;
inc_hires = 0;
} else { } else {
count = decay_count;
state = STATE_DECAY; state = STATE_DECAY;
inc = ((sustain_mult - 0x10000) / ((int32_t)count << 3));
count = decay_count;
inc_hires = (sustain_mult - 0x40000000) / (int32_t)count;
} }
continue; continue;
} else if (state == STATE_HOLD) { } else if (state == STATE_HOLD) {
state = STATE_DECAY; state = STATE_DECAY;
count = decay_count; count = decay_count;
inc = ((sustain_mult - 0x10000) / (int32_t)count) >> 3;
inc_hires = (sustain_mult - 0x40000000) / (int32_t)count;
continue; continue;
} else if (state == STATE_DECAY) { } else if (state == STATE_DECAY) {
state = STATE_SUSTAIN; state = STATE_SUSTAIN;
count = 0xFFFF; count = 0xFFFF;
mult = sustain_mult;
inc = 0;
mult_hires = sustain_mult;
inc_hires = 0;
} else if (state == STATE_SUSTAIN) { } else if (state == STATE_SUSTAIN) {
count = 0xFFFF; count = 0xFFFF;
} else if (state == STATE_RELEASE) { } else if (state == STATE_RELEASE) {
} else if (state == STATE_DELAY) { } else if (state == STATE_DELAY) {
state = STATE_ATTACK; state = STATE_ATTACK;
count = attack_count; count = attack_count;
inc = (0x10000 / count) >> 3;
inc_hires = 0x40000000 / count;
continue; 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++; sample12 = *p++;
sample34 = *p++; sample34 = *p++;
sample56 = *p++; sample56 = *p++;
*p++ = sample34; *p++ = sample34;
*p++ = sample56; *p++ = sample56;
*p++ = sample78; *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--; count--;
} }
transmit(block); transmit(block);

+ 11
- 7
effect_envelope.h 파일 보기

/* Audio Library for Teensy 3.X /* 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 * 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 * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
} }
void attack(float milliseconds) { void attack(float milliseconds) {
attack_count = milliseconds2count(milliseconds); attack_count = milliseconds2count(milliseconds);
if (attack_count == 0) attack_count = 1;
} }
void hold(float milliseconds) { void hold(float milliseconds) {
hold_count = milliseconds2count(milliseconds); hold_count = milliseconds2count(milliseconds);
} }
void decay(float milliseconds) { void decay(float milliseconds) {
decay_count = milliseconds2count(milliseconds); decay_count = milliseconds2count(milliseconds);
if (decay_count == 0) decay_count = 1;
} }
void sustain(float level) { void sustain(float level) {
if (level < 0.0) level = 0; if (level < 0.0) level = 0;
else if (level > 1.0) level = 1.0; else if (level > 1.0) level = 1.0;
sustain_mult = level * 65536.0;
sustain_mult = level * 1073741824.0;
} }
void release(float milliseconds) { void release(float milliseconds) {
release_count = milliseconds2count(milliseconds); release_count = milliseconds2count(milliseconds);
if (release_count == 0) release_count = 1;
} }
using AudioStream::release; using AudioStream::release;
virtual void update(void); virtual void update(void);
uint16_t milliseconds2count(float milliseconds) { uint16_t milliseconds2count(float milliseconds) {
if (milliseconds < 0.0) milliseconds = 0.0; if (milliseconds < 0.0) milliseconds = 0.0;
uint32_t c = ((uint32_t)(milliseconds*SAMPLES_PER_MSEC)+7)>>3; 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; return c;
} }
audio_block_t *inputQueueArray[1]; audio_block_t *inputQueueArray[1];
// state // 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 // settings
uint16_t delay_count; uint16_t delay_count;
uint16_t attack_count; uint16_t attack_count;

Loading…
취소
저장