|
|
|
@ -28,11 +28,26 @@ const int levellut[] = { |
|
|
|
|
0, 5, 9, 13, 17, 20, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 42, 43, 45, 46 |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
#ifdef ACCURATE_ENVELOPE |
|
|
|
|
const int statics[] = { |
|
|
|
|
1764000, 1764000, 1411200, 1411200, 1190700, 1014300, 992250, |
|
|
|
|
882000, 705600, 705600, 584325, 507150, 502740, 441000, 418950, |
|
|
|
|
352800, 308700, 286650, 253575, 220500, 220500, 176400, 145530, |
|
|
|
|
145530, 125685, 110250, 110250, 88200, 88200, 74970, 61740, |
|
|
|
|
61740, 55125, 48510, 44100, 37485, 31311, 30870, 27562, 27562, |
|
|
|
|
22050, 18522, 17640, 15435, 14112, 13230, 11025, 9261, 9261, 7717, |
|
|
|
|
6615, 6615, 5512, 5512, 4410, 3969, 3969, 3439, 2866, 2690, 2249, |
|
|
|
|
1984, 1896, 1808, 1411, 1367, 1234, 1146, 926, 837, 837, 705, |
|
|
|
|
573, 573, 529, 441, 441 |
|
|
|
|
// and so on, I stopped measuring after R=76 (needs to be double-checked anyway)
|
|
|
|
|
}; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
void Env::init_sr(double sampleRate) { |
|
|
|
|
sr_multiplier = (44100.0 / sampleRate) * (1<<24); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Env::init(const int r[4], const int l[4], int32_t ol, int rate_scaling) { |
|
|
|
|
void Env::init(const int r[4], const int l[4], int ol, int rate_scaling) { |
|
|
|
|
for (int i = 0; i < 4; i++) { |
|
|
|
|
rates_[i] = r[i]; |
|
|
|
|
levels_[i] = l[i]; |
|
|
|
@ -45,6 +60,16 @@ void Env::init(const int r[4], const int l[4], int32_t ol, int rate_scaling) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int32_t Env::getsample() { |
|
|
|
|
#ifdef ACCURATE_ENVELOPE |
|
|
|
|
if (staticcount_) { |
|
|
|
|
staticcount_ -= N; |
|
|
|
|
if (staticcount_ <= 0) { |
|
|
|
|
staticcount_ = 0; |
|
|
|
|
advance(ix_ + 1); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
if (ix_ < 3 || ((ix_ < 4) && !down_)) { |
|
|
|
|
if (rising_) { |
|
|
|
|
const int jumptarget = 1716; |
|
|
|
@ -57,7 +82,11 @@ int32_t Env::getsample() { |
|
|
|
|
level_ = targetlevel_; |
|
|
|
|
advance(ix_ + 1); |
|
|
|
|
} |
|
|
|
|
} else { // !rising
|
|
|
|
|
} |
|
|
|
|
else if (staticcount_) { |
|
|
|
|
; |
|
|
|
|
} |
|
|
|
|
else { // !rising
|
|
|
|
|
level_ -= inc_; |
|
|
|
|
if (level_ <= targetlevel_) { |
|
|
|
|
level_ = targetlevel_; |
|
|
|
@ -95,14 +124,29 @@ void Env::advance(int newix) { |
|
|
|
|
int qrate = (rates_[ix_] * 41) >> 6; |
|
|
|
|
qrate += rate_scaling_; |
|
|
|
|
qrate = min(qrate, 63); |
|
|
|
|
inc_ = (4 + (qrate & 3)) << (2 + LG_N + (qrate >> 2)); |
|
|
|
|
|
|
|
|
|
#ifdef ACCURATE_ENVELOPE |
|
|
|
|
if (targetlevel_ == level_) { |
|
|
|
|
// approximate number of samples at 44.100 kHz to achieve the time
|
|
|
|
|
// empirically gathered using 2 TF1s, could probably use some double-checking
|
|
|
|
|
// and cleanup, but it's pretty close for now.
|
|
|
|
|
int staticrate = rates_[ix_]; |
|
|
|
|
staticrate += rate_scaling_; // needs to be checked, as well, but seems correct
|
|
|
|
|
staticrate = min(staticrate, 99); |
|
|
|
|
staticcount_ = staticrate < 77 ? statics[staticrate] : 20 * (99 - staticrate); |
|
|
|
|
staticcount_ = (int)(((int64_t)staticcount_ * (int64_t)sr_multiplier) >> 24); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
staticcount_ = 0; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
inc_ = (4 + (qrate & 3)) << (2 + LG_N + (qrate >> 2)); |
|
|
|
|
// meh, this should be fixed elsewhere
|
|
|
|
|
inc_ = ((int64_t)inc_ * (int64_t)sr_multiplier) >> 24; |
|
|
|
|
inc_ = (int)(((int64_t)inc_ * (int64_t)sr_multiplier) >> 24); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Env::update(const int r[4], const int l[4], int32_t ol, int rate_scaling) { |
|
|
|
|
void Env::update(const int r[4], const int l[4], int ol, int rate_scaling) { |
|
|
|
|
for (int i = 0; i < 4; i++) { |
|
|
|
|
rates_[i] = r[i]; |
|
|
|
|
levels_[i] = l[i]; |
|
|
|
@ -135,7 +179,10 @@ void Env::transfer(Env &src) { |
|
|
|
|
targetlevel_ = src.targetlevel_; |
|
|
|
|
rising_= src.rising_; |
|
|
|
|
ix_ = src.ix_; |
|
|
|
|
inc_ = src.inc_; |
|
|
|
|
down_ = src.down_; |
|
|
|
|
#ifdef ACCURATE_ENVELOPE |
|
|
|
|
staticcount_ = src.staticcount_; |
|
|
|
|
#endif |
|
|
|
|
inc_ = src.inc_; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|