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

pull/2/head
Holger Wirtz 7 years ago
parent 58f8f4c3f8
commit 8efb5f4406
  1. 15
      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. 42
      src/msfa/dx7note.cc
  8. 4
      src/msfa/dx7note.h
  9. 59
      src/msfa/env.cc
  10. 8
      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
#ifdef _WIN32
#if _MSC_VER < 1800
double log2(double n) {
return log(n) / log(2.0);
}
double round(double n) {
return n < 0.0 ? ceil(n - 0.5) : floor(n + 0.5);
}
#endif
__declspec(align(16)) const int zeros[N] = {0};
#else
const int32_t __attribute__ ((aligned(16))) zeros[N] = {0};
@ -76,7 +78,6 @@ static inline uint16_t sinLog(uint16_t phi) {
}
EngineMkI::EngineMkI() {
TRACE("Hi");
float bitReso = SINLOG_TABLESIZE;
for(int i=0;i<SINLOG_TABLESIZE;i++) {
@ -118,15 +119,11 @@ EngineMkI::EngineMkI() {
TRACE("SINEXTTABLE: %s", buffer);
TRACE("****************************************");
#endif
TRACE("Bye");
}
inline int32_t mkiSin(int32_t phase, uint16_t env) {
uint16_t expVal = sinLog(phase >> (22 - SINLOG_BITDEPTH)) + (env);
#ifdef MKIDEBUG
int16_t expValShow = expVal;
#endif
//int16_t expValShow = expVal;
const bool isSigned = 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;
}
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;
FmAlgorithm alg = algorithms[algorithm];
bool has_contents[3] = { true, false, false };
@ -330,14 +327,14 @@ void EngineMkI::render(int32_t *output, FmOpParams *params, int algorithm, int32
switch ( algorithm ) {
// three operator feedback, process exception for ALGO 4
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[2].phase += params[2].freq << LG_N; // yuk yuk
op += 2; // ignore the 2 other operators
break;
// two operator feedback, process exception for ALGO 6
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
op++; // ignore next operator;
break;

@ -29,7 +29,7 @@ class EngineMkI : public FmCore {
public:
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,
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,
int32_t *fb_buf, int feedback_shift) {
int32_t *fb_buf, int32_t feedback_shift) {
const int kLevelThresh = 507; // really ????
const FmAlgorithm alg = algorithms[algorithm];
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;
if (mode == 0) {
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];
if (fine) {
// (1 << 24) / log(2)
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.
logfreq += 12606 * (detune - 7);
// // This was measured at 7.213Hz per count at 9600Hz, but the exact
// // value is somewhat dependent on midinote. Close enough for now.
// //logfreq += 12606 * (detune -7);
} else {
// ((1 << 24) * log(10) / log(2) * .01) << 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 levels[4];
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 detune = patch[off + 20];
int32_t freq = osc_freq(midinote, mode, coarse, fine, detune);
opMode[op] = mode;
basepitch_[op] = freq;
ampmodsens_[op] = ampmodsenstab[patch[off + 14] & 3];
}
@ -186,7 +193,7 @@ 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 pmod_1 = (((int64_t) pmd) * (int64_t) senslfo) >> 39;
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);
int32_t pitch_mod = max(pmod_1, pmod_2);
pitch_mod = pitchenv_.getsample() + (pitch_mod * (senslfo < 0 ? -1 : 1));
@ -196,20 +203,21 @@ void Dx7Note::compute(int32_t *buf, int32_t lfo_val, int32_t lfo_delay, const Co
int32_t pb = (pitchbend - 0x2000);
if (pb != 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 {
int stp = 12 / ctrls->values_[kControllerPitchStep];
pb = pb * stp / 8191;
pb = (pb * (8191 / stp)) << 11;
}
}
pitch_mod += pb;
pitch_mod += ctrls->masterTune;
int32_t pitch_base = pb + ctrls->masterTune;
pitch_mod += pitch_base;
// ==== AMP MOD ====
uint32_t amod_1 = ((int64_t) ampmoddepth_ * (int64_t) lfo_delay) >> 8; // Q24 :D
amod_1 = ((int64_t) amod_1 * (int64_t) lfo_val) >> 24;
uint32_t amod_2 = ((int64_t) ctrls->amp_mod * (int64_t) lfo_val) >> 7; // Q?? :|
lfo_val = (1<<24) - lfo_val;
uint32_t amod_1 = (uint32_t)(((int64_t) ampmoddepth_ * (int64_t) lfo_delay) >> 8); // Q24 :D
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);
// ==== 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 ====
for (int op = 0; op < 6; op++) {
//if ( ctrls->opSwitch[op] == '0' ) {
// if ( ctrls->opSwitch[op] == '0' ) {
if (!(ctrls->opSwitch & (1<<op))) {
env_[op].getsample(); // advance the envelop even if it is not playing
params_[op].level_in = 0;
} else {
//int32_t gain = pow(2, 10 + level * (1.0 / (1 << 24)));
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();
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.
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;
}
params_[op].level_in = level;
@ -259,6 +271,7 @@ void Dx7Note::update(const uint8_t patch[156], int midinote, int velocity) {
int detune = patch[off + 20];
basepitch_[op] = osc_freq(midinote, mode, coarse, fine, detune);
ampmodsens_[op] = ampmodsenstab[patch[off + 14] & 3];
opMode[op] = mode;
for (int i = 0; i < 4; i++) {
rates[i] = patch[off + i];
@ -316,4 +329,3 @@ void Dx7Note::oscSync() {
params_[i].phase = 0;
}
}

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

@ -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_;
}

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

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

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

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

Loading…
Cancel
Save