Added all recent commits from main dexed to native-lv2.

pull/2/head
Holger Wirtz 7 years ago
parent 58f8f4c3f8
commit 8efb5f4406
  1. 17
      src/EngineMkI.cpp
  2. 2
      src/EngineMkI.h
  3. 2
      src/EngineOpl.cpp
  4. 2
      src/msfa/.gitignore
  5. 0
      src/msfa/aligned_buf.h
  6. 0
      src/msfa/controllers.h
  7. 52
      src/msfa/dx7note.cc
  8. 4
      src/msfa/dx7note.h
  9. 197
      src/msfa/env.cc
  10. 10
      src/msfa/env.h
  11. 0
      src/msfa/exp2.cc
  12. 0
      src/msfa/exp2.h
  13. 1
      src/msfa/fm_core.cc
  14. 0
      src/msfa/freqlut.cc
  15. 0
      src/msfa/freqlut.h
  16. 1
      src/msfa/lfo.cc
  17. 0
      src/msfa/module.h
  18. 0
      src/msfa/pitchenv.h
  19. 1
      src/msfa/synth.h

@ -35,12 +35,14 @@
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
#if _MSC_VER < 1800
double log2(double n) { double log2(double n) {
return log(n) / log(2.0); return log(n) / log(2.0);
} }
double round(double n) { double round(double n) {
return n < 0.0 ? ceil(n - 0.5) : floor(n + 0.5); return n < 0.0 ? ceil(n - 0.5) : floor(n + 0.5);
} }
#endif
__declspec(align(16)) const int zeros[N] = {0}; __declspec(align(16)) const int zeros[N] = {0};
#else #else
const int32_t __attribute__ ((aligned(16))) zeros[N] = {0}; const int32_t __attribute__ ((aligned(16))) zeros[N] = {0};
@ -76,7 +78,6 @@ static inline uint16_t sinLog(uint16_t phi) {
} }
EngineMkI::EngineMkI() { EngineMkI::EngineMkI() {
TRACE("Hi");
float bitReso = SINLOG_TABLESIZE; float bitReso = SINLOG_TABLESIZE;
for(int i=0;i<SINLOG_TABLESIZE;i++) { for(int i=0;i<SINLOG_TABLESIZE;i++) {
@ -118,16 +119,12 @@ EngineMkI::EngineMkI() {
TRACE("SINEXTTABLE: %s", buffer); TRACE("SINEXTTABLE: %s", buffer);
TRACE("****************************************"); TRACE("****************************************");
#endif #endif
TRACE("Bye");
} }
inline int32_t mkiSin(int32_t phase, uint16_t env) { inline int32_t mkiSin(int32_t phase, uint16_t env) {
uint16_t expVal = sinLog(phase >> (22 - SINLOG_BITDEPTH)) + (env); uint16_t expVal = sinLog(phase >> (22 - SINLOG_BITDEPTH)) + (env);
#ifdef MKIDEBUG //int16_t expValShow = expVal;
int16_t expValShow = expVal;
#endif
const bool isSigned = expVal & NEGATIVE_BIT; const bool isSigned = expVal & NEGATIVE_BIT;
expVal &= ~NEGATIVE_BIT; expVal &= ~NEGATIVE_BIT;
@ -295,7 +292,7 @@ void EngineMkI::compute_fb3(int32_t *output, FmOpParams *parms, int32_t gain01,
fb_buf[1] = y; fb_buf[1] = y;
} }
void EngineMkI::render(int32_t *output, FmOpParams *params, int algorithm, int32_t *fb_buf, int feedback_shift) { void EngineMkI::render(int32_t *output, FmOpParams *params, int algorithm, int32_t *fb_buf, int32_t feedback_shift) {
const int kLevelThresh = ENV_MAX-100; const int kLevelThresh = ENV_MAX-100;
FmAlgorithm alg = algorithms[algorithm]; FmAlgorithm alg = algorithms[algorithm];
bool has_contents[3] = { true, false, false }; bool has_contents[3] = { true, false, false };
@ -330,14 +327,14 @@ void EngineMkI::render(int32_t *output, FmOpParams *params, int algorithm, int32
switch ( algorithm ) { switch ( algorithm ) {
// three operator feedback, process exception for ALGO 4 // three operator feedback, process exception for ALGO 4
case 3 : case 3 :
compute_fb3(outptr, params, gain1, gain2, fb_buf, min((feedback_shift+2),16)); compute_fb3(outptr, params, gain1, gain2, fb_buf, min((feedback_shift+2), 16));
params[1].phase += params[1].freq << LG_N; // hack, we already processed op-5 - op-4 params[1].phase += params[1].freq << LG_N; // hack, we already processed op-5 - op-4
params[2].phase += params[2].freq << LG_N; // yuk yuk params[2].phase += params[2].freq << LG_N; // yuk yuk
op += 2; // ignore the 2 other operators op += 2; // ignore the 2 other operators
break; break;
// two operator feedback, process exception for ALGO 6 // two operator feedback, process exception for ALGO 6
case 5 : case 5 :
compute_fb2(outptr, params, gain1, gain2, fb_buf, min((feedback_shift+2),16)); compute_fb2(outptr, params, gain1, gain2, fb_buf, min((feedback_shift+2), 16));
params[1].phase += params[1].freq << LG_N; // yuk, hack, we already processed op-5 params[1].phase += params[1].freq << LG_N; // yuk, hack, we already processed op-5
op++; // ignore next operator; op++; // ignore next operator;
break; break;

@ -29,7 +29,7 @@ class EngineMkI : public FmCore {
public: public:
EngineMkI(); EngineMkI();
void render(int32_t *output, FmOpParams *params, int algorithm, int32_t *fb_buf, int feedback_shift) override; void render(int32_t *output, FmOpParams *params, int algorithm, int32_t *fb_buf, int32_t feedback_shift) override;
void compute(int32_t *output, const int32_t *input, int32_t phase0, int32_t freq, int32_t gain1, int32_t gain2, void compute(int32_t *output, const int32_t *input, int32_t phase0, int32_t freq, int32_t gain1, int32_t gain2,
bool add); bool add);

@ -169,7 +169,7 @@ void EngineOpl::compute_fb(int32_t *output, int32_t phase0, int32_t freq,
void EngineOpl::render(int32_t *output, FmOpParams *params, int algorithm, void EngineOpl::render(int32_t *output, FmOpParams *params, int algorithm,
int32_t *fb_buf, int feedback_shift) { int32_t *fb_buf, int32_t feedback_shift) {
const int kLevelThresh = 507; // really ???? const int kLevelThresh = 507; // really ????
const FmAlgorithm alg = algorithms[algorithm]; const FmAlgorithm alg = algorithms[algorithm];
bool has_contents[3] = { true, false, false }; bool has_contents[3] = { true, false, false };

@ -1,2 +0,0 @@
*.o
*.gch

@ -44,14 +44,20 @@ int32_t osc_freq(int midinote, int mode, int coarse, int fine, int detune) {
int32_t logfreq; int32_t logfreq;
if (mode == 0) { if (mode == 0) {
logfreq = midinote_to_logfreq(midinote); logfreq = midinote_to_logfreq(midinote);
// could use more precision, closer enough for now. those numbers comes from my DX7
double detuneRatio = 0.0209 * exp(-0.396 * (((float)logfreq)/(1<<24))) / 7;
logfreq += detuneRatio * logfreq * (detune - 7);
logfreq += coarsemul[coarse & 31]; logfreq += coarsemul[coarse & 31];
if (fine) { if (fine) {
// (1 << 24) / log(2) // (1 << 24) / log(2)
logfreq += (int32_t)floor(24204406.323123 * log(1 + 0.01 * fine) + 0.5); logfreq += (int32_t)floor(24204406.323123 * log(1 + 0.01 * fine) + 0.5);
} }
// This was measured at 7.213Hz per count at 9600Hz, but the exact
// value is somewhat dependent on midinote. Close enough for now. // // This was measured at 7.213Hz per count at 9600Hz, but the exact
logfreq += 12606 * (detune - 7); // // value is somewhat dependent on midinote. Close enough for now.
// //logfreq += 12606 * (detune -7);
} else { } else {
// ((1 << 24) * log(10) / log(2) * .01) << 3 // ((1 << 24) * log(10) / log(2) * .01) << 3
logfreq = (4458616 * ((coarse & 3) * 100 + fine)) >> 3; logfreq = (4458616 * ((coarse & 3) * 100 + fine)) >> 3;
@ -138,7 +144,7 @@ Dx7Note::Dx7Note() {
} }
} }
void Dx7Note::init(const uint8_t patch[167], int midinote, int velocity) { void Dx7Note::init(const uint8_t patch[156], int midinote, int velocity) {
int rates[4]; int rates[4];
int levels[4]; int levels[4];
for (int op = 0; op < 6; op++) { for (int op = 0; op < 6; op++) {
@ -164,6 +170,7 @@ void Dx7Note::init(const uint8_t patch[167], int midinote, int velocity) {
int fine = patch[off + 19]; int fine = patch[off + 19];
int detune = patch[off + 20]; int detune = patch[off + 20];
int32_t freq = osc_freq(midinote, mode, coarse, fine, detune); int32_t freq = osc_freq(midinote, mode, coarse, fine, detune);
opMode[op] = mode;
basepitch_[op] = freq; basepitch_[op] = freq;
ampmodsens_[op] = ampmodsenstab[patch[off + 14] & 3]; ampmodsens_[op] = ampmodsenstab[patch[off + 14] & 3];
} }
@ -186,30 +193,31 @@ void Dx7Note::compute(int32_t *buf, int32_t lfo_val, int32_t lfo_delay, const Co
int32_t senslfo = pitchmodsens_ * (lfo_val - (1 << 23)); int32_t senslfo = pitchmodsens_ * (lfo_val - (1 << 23));
int32_t pmod_1 = (((int64_t) pmd) * (int64_t) senslfo) >> 39; int32_t pmod_1 = (((int64_t) pmd) * (int64_t) senslfo) >> 39;
pmod_1 = abs(pmod_1); pmod_1 = abs(pmod_1);
int32_t pmod_2 = ((int64_t)ctrls->pitch_mod * (int64_t)senslfo) >> 14; int32_t pmod_2 = (int32_t)(((int64_t)ctrls->pitch_mod * (int64_t)senslfo) >> 14);
pmod_2 = abs(pmod_2); pmod_2 = abs(pmod_2);
int32_t pitch_mod = max(pmod_1, pmod_2); int32_t pitch_mod = max(pmod_1, pmod_2);
pitch_mod = pitchenv_.getsample() + (pitch_mod * (senslfo < 0 ? -1 : 1)); pitch_mod = pitchenv_.getsample() + (pitch_mod * (senslfo < 0 ? -1 : 1));
// ---- PITCH BEND ---- // ---- PITCH BEND ----
int pitchbend = ctrls->values_[kControllerPitch]; int pitchbend = ctrls->values_[kControllerPitch];
int32_t pb = (pitchbend - 0x2000); int32_t pb = (pitchbend - 0x2000);
if (pb != 0) { if (pb != 0) {
if (ctrls->values_[kControllerPitchStep] == 0) { if (ctrls->values_[kControllerPitchStep] == 0) {
pb = ((float) (pb << 11)) * ((float)ctrls->values_[kControllerPitchRange]) / 12.0; pb = ((float) (pb << 11)) * ((float) ctrls->values_[kControllerPitchRange]) / 12.0;
} else { } else {
int stp = 12 / ctrls->values_[kControllerPitchStep]; int stp = 12 / ctrls->values_[kControllerPitchStep];
pb = pb * stp / 8191; pb = pb * stp / 8191;
pb = (pb * (8191 / stp)) << 11; pb = (pb * (8191 / stp)) << 11;
} }
} }
pitch_mod += pb; int32_t pitch_base = pb + ctrls->masterTune;
pitch_mod += ctrls->masterTune; pitch_mod += pitch_base;
// ==== AMP MOD ==== // ==== AMP MOD ====
uint32_t amod_1 = ((int64_t) ampmoddepth_ * (int64_t) lfo_delay) >> 8; // Q24 :D lfo_val = (1<<24) - lfo_val;
amod_1 = ((int64_t) amod_1 * (int64_t) lfo_val) >> 24; uint32_t amod_1 = (uint32_t)(((int64_t) ampmoddepth_ * (int64_t) lfo_delay) >> 8); // Q24 :D
uint32_t amod_2 = ((int64_t) ctrls->amp_mod * (int64_t) lfo_val) >> 7; // Q?? :| amod_1 = (uint32_t)(((int64_t) amod_1 * (int64_t) lfo_val) >> 24);
uint32_t amod_2 = (uint32_t)(((int64_t) ctrls->amp_mod * (int64_t) lfo_val) >> 7); // Q?? :|
uint32_t amd_mod = max(amod_1, amod_2); uint32_t amd_mod = max(amod_1, amod_2);
// ==== EG AMP MOD ==== // ==== EG AMP MOD ====
@ -218,21 +226,25 @@ void Dx7Note::compute(int32_t *buf, int32_t lfo_val, int32_t lfo_delay, const Co
// ==== OP RENDER ==== // ==== OP RENDER ====
for (int op = 0; op < 6; op++) { for (int op = 0; op < 6; op++) {
//if ( ctrls->opSwitch[op] == '0' ) { // if ( ctrls->opSwitch[op] == '0' ) {
if (!(ctrls->opSwitch & (1<<op))) { if (!(ctrls->opSwitch & (1<<op))) {
env_[op].getsample(); // advance the envelop even if it is not playing env_[op].getsample(); // advance the envelop even if it is not playing
params_[op].level_in = 0; params_[op].level_in = 0;
} else { } else {
//int32_t gain = pow(2, 10 + level * (1.0 / (1 << 24))); //int32_t gain = pow(2, 10 + level * (1.0 / (1 << 24)));
params_[op].freq = Freqlut::lookup(basepitch_[op] + pitch_mod);
if ( opMode[op] )
params_[op].freq = Freqlut::lookup(basepitch_[op] + pitch_base);
else
params_[op].freq = Freqlut::lookup(basepitch_[op] + pitch_mod);
int32_t level = env_[op].getsample(); int32_t level = env_[op].getsample();
if (ampmodsens_[op] != 0) { if (ampmodsens_[op] != 0) {
uint32_t sensamp = ((uint64_t) amd_mod) * ((uint64_t) ampmodsens_[op]) >> 24; uint32_t sensamp = (uint32_t)(((uint64_t) amd_mod) * ((uint64_t) ampmodsens_[op]) >> 24);
// TODO: mehhh.. this needs some real tuning. // TODO: mehhh.. this needs some real tuning.
uint32_t pt = exp(((float)sensamp)/262144 * 0.07 + 12.2); uint32_t pt = exp(((float)sensamp)/262144 * 0.07 + 12.2);
uint32_t ldiff = ((uint64_t)level) * (((uint64_t)pt<<4)) >> 28; uint32_t ldiff = (uint32_t)(((uint64_t)level) * (((uint64_t)pt<<4)) >> 28);
level -= ldiff; level -= ldiff;
} }
params_[op].level_in = level; params_[op].level_in = level;
@ -259,10 +271,11 @@ void Dx7Note::update(const uint8_t patch[156], int midinote, int velocity) {
int detune = patch[off + 20]; int detune = patch[off + 20];
basepitch_[op] = osc_freq(midinote, mode, coarse, fine, detune); basepitch_[op] = osc_freq(midinote, mode, coarse, fine, detune);
ampmodsens_[op] = ampmodsenstab[patch[off + 14] & 3]; ampmodsens_[op] = ampmodsenstab[patch[off + 14] & 3];
opMode[op] = mode;
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
rates[i] = patch[off + i]; rates[i] = patch[off + i];
levels[i] = patch[off + 4 + i]; levels[i] = patch[off + 4 + i];
} }
int outlevel = patch[off + 16]; int outlevel = patch[off + 16];
outlevel = Env::scaleoutlevel(outlevel); outlevel = Env::scaleoutlevel(outlevel);
@ -316,4 +329,3 @@ void Dx7Note::oscSync() {
params_[i].phase = 0; params_[i].phase = 0;
} }
} }

@ -37,8 +37,7 @@ struct VoiceStatus {
class Dx7Note { class Dx7Note {
public: public:
Dx7Note(); Dx7Note();
//void init(const uint8_t patch[156], int midinote, int velocity, int fb_depth); void init(const uint8_t patch[156], int midinote, int velocity);
void init(const uint8_t patch[160], int midinote, int velocity);
// Note: this _adds_ to the buffer. Interesting question whether it's // Note: this _adds_ to the buffer. Interesting question whether it's
// worth it... // worth it...
@ -67,6 +66,7 @@ private:
int32_t fb_buf_[2]; int32_t fb_buf_[2];
int32_t fb_shift_; int32_t fb_shift_;
int32_t ampmodsens_[6]; int32_t ampmodsens_[6];
int32_t opMode[6];
int ampmoddepth_; int ampmoddepth_;
int algorithm_; int algorithm_;

@ -1,13 +1,13 @@
/* /*
* Copyright 2017 Pascal Gauthier. * Copyright 2017 Pascal Gauthier.
* Copyright 2012 Google Inc. * Copyright 2012 Google Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -28,96 +28,140 @@ const int levellut[] = {
0, 5, 9, 13, 17, 20, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 42, 43, 45, 46 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) { void Env::init_sr(double sampleRate) {
sr_multiplier = (44100.0 / sampleRate) * (1<<24); 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++) { for (int i = 0; i < 4; i++) {
rates_[i] = r[i]; rates_[i] = r[i];
levels_[i] = l[i]; levels_[i] = l[i];
} }
outlevel_ = ol; outlevel_ = ol;
rate_scaling_ = rate_scaling; rate_scaling_ = rate_scaling;
level_ = 0; level_ = 0;
down_ = true; down_ = true;
advance(0); advance(0);
} }
int32_t Env::getsample() { int32_t Env::getsample() {
if (ix_ < 3 || ((ix_ < 4) && !down_)) { #ifdef ACCURATE_ENVELOPE
if (rising_) { if (staticcount_) {
const int jumptarget = 1716; staticcount_ -= N;
if (level_ < (jumptarget << 16)) { if (staticcount_ <= 0) {
level_ = jumptarget << 16; staticcount_ = 0;
} advance(ix_ + 1);
level_ += (((17 << 24) - level_) >> 24) * inc_; }
// TODO: should probably be more accurate when inc is large
if (level_ >= targetlevel_) {
level_ = targetlevel_;
advance(ix_ + 1);
}
} else { // !rising
level_ -= inc_;
if (level_ <= targetlevel_) {
level_ = targetlevel_;
advance(ix_ + 1);
}
} }
} #endif
// TODO: this would be a good place to set level to 0 when under threshold
return level_; if (ix_ < 3 || ((ix_ < 4) && !down_)) {
if (rising_) {
const int jumptarget = 1716;
if (level_ < (jumptarget << 16)) {
level_ = jumptarget << 16;
}
level_ += (((17 << 24) - level_) >> 24) * inc_;
// TODO: should probably be more accurate when inc is large
if (level_ >= targetlevel_) {
level_ = targetlevel_;
advance(ix_ + 1);
}
}
else if (staticcount_) {
;
}
else { // !rising
level_ -= inc_;
if (level_ <= targetlevel_) {
level_ = targetlevel_;
advance(ix_ + 1);
}
}
}
// TODO: this would be a good place to set level to 0 when under threshold
return level_;
} }
void Env::keydown(bool d) { void Env::keydown(bool d) {
if (down_ != d) { if (down_ != d) {
down_ = d; down_ = d;
advance(d ? 0 : 3); advance(d ? 0 : 3);
} }
} }
int Env::scaleoutlevel(int outlevel) { int Env::scaleoutlevel(int outlevel) {
return outlevel >= 20 ? 28 + outlevel : levellut[outlevel]; return outlevel >= 20 ? 28 + outlevel : levellut[outlevel];
} }
void Env::advance(int newix) { void Env::advance(int newix) {
ix_ = newix; ix_ = newix;
if (ix_ < 4) { if (ix_ < 4) {
int newlevel = levels_[ix_]; int newlevel = levels_[ix_];
int actuallevel = scaleoutlevel(newlevel) >> 1; int actuallevel = scaleoutlevel(newlevel) >> 1;
actuallevel = (actuallevel << 6) + outlevel_ - 4256; actuallevel = (actuallevel << 6) + outlevel_ - 4256;
actuallevel = actuallevel < 16 ? 16 : actuallevel; actuallevel = actuallevel < 16 ? 16 : actuallevel;
// level here is same as Java impl // level here is same as Java impl
targetlevel_ = actuallevel << 16; targetlevel_ = actuallevel << 16;
rising_ = (targetlevel_ > level_); rising_ = (targetlevel_ > level_);
// rate // rate
int qrate = (rates_[ix_] * 41) >> 6; int qrate = (rates_[ix_] * 41) >> 6;
qrate += rate_scaling_; qrate += rate_scaling_;
qrate = min(qrate, 63); qrate = min(qrate, 63);
inc_ = (4 + (qrate & 3)) << (2 + LG_N + (qrate >> 2));
#ifdef ACCURATE_ENVELOPE
// meh, this should be fixed elsewhere if (targetlevel_ == level_) {
inc_ = ((int64_t)inc_ * (int64_t)sr_multiplier) >> 24; // 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_ = (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++) { for (int i = 0; i < 4; i++) {
rates_[i] = r[i]; rates_[i] = r[i];
levels_[i] = l[i]; levels_[i] = l[i];
} }
outlevel_ = ol; outlevel_ = ol;
rate_scaling_ = rate_scaling; rate_scaling_ = rate_scaling;
if ( down_ ) { if ( down_ ) {
// for now we simply reset ourselve at level 3 // for now we simply reset ourselve at level 3
int newlevel = levels_[2]; int newlevel = levels_[2];
int actuallevel = scaleoutlevel(newlevel) >> 1; int actuallevel = scaleoutlevel(newlevel) >> 1;
actuallevel = (actuallevel << 6) - 4256; actuallevel = (actuallevel << 6) - 4256;
actuallevel = actuallevel < 16 ? 16 : actuallevel; actuallevel = actuallevel < 16 ? 16 : actuallevel;
targetlevel_ = actuallevel << 16; targetlevel_ = actuallevel << 16;
advance(2); advance(2);
} }
} }
void Env::getPosition(char *step) { void Env::getPosition(char *step) {
@ -135,7 +179,10 @@ void Env::transfer(Env &src) {
targetlevel_ = src.targetlevel_; targetlevel_ = src.targetlevel_;
rising_= src.rising_; rising_= src.rising_;
ix_ = src.ix_; ix_ = src.ix_;
inc_ = src.inc_;
down_ = src.down_; down_ = src.down_;
#ifdef ACCURATE_ENVELOPE
staticcount_ = src.staticcount_;
#endif
inc_ = src.inc_;
} }

@ -1,4 +1,5 @@
/* /*
* Copyright 2017 Pascal Gauthier.
* Copyright 2012 Google Inc. * Copyright 2012 Google Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -21,6 +22,8 @@
// DX7 envelope generation // DX7 envelope generation
#define ACCURATE_ENVELOPE
class Env { class Env {
public: public:
@ -33,7 +36,6 @@ class Env {
void update(const int rates[4], const int levels[4], int outlevel, void update(const int rates[4], const int levels[4], int outlevel,
int rate_scaling); int rate_scaling);
// Result is in Q24/doubling log format. Also, result is subsampled // Result is in Q24/doubling log format. Also, result is subsampled
// for every N samples. // for every N samples.
// A couple more things need to happen for this to be used as a gain // A couple more things need to happen for this to be used as a gain
@ -50,10 +52,11 @@ class Env {
void transfer(Env &src); void transfer(Env &src);
private: private:
// PG: This code is normalized to 44100, need to put a multiplier // PG: This code is normalized to 44100, need to put a multiplier
// if we are not using 44100. // if we are not using 44100.
static uint32_t sr_multiplier; static uint32_t sr_multiplier;
int rates_[4]; int rates_[4];
int levels_[4]; int levels_[4];
int outlevel_; int outlevel_;
@ -66,6 +69,9 @@ class Env {
bool rising_; bool rising_;
int ix_; int ix_;
int inc_; int inc_;
#ifdef ACCURATE_ENVELOPE
int staticcount_;
#endif
bool down_; bool down_;

@ -23,6 +23,7 @@
#include "fm_op_kernel.h" #include "fm_op_kernel.h"
#include "fm_core.h" #include "fm_core.h"
//using namespace std; //using namespace std;
const FmAlgorithm FmCore::algorithms[32] = { const FmAlgorithm FmCore::algorithms[32] = {

@ -95,4 +95,3 @@ void Lfo::keydown() {
} }
delaystate_ = 0; delaystate_ = 0;
} }

@ -57,7 +57,6 @@ inline static T max(const T& a, const T& b) {
return a > b ? a : b; return a > b ? a : b;
} }
#define QER(n,b) ( ((float)n)/(1<<b) ) #define QER(n,b) ( ((float)n)/(1<<b) )
#endif // __SYNTH_H #endif // __SYNTH_H

Loading…
Cancel
Save