From 64ad13bb4a2ae86e026883d3dfdd6f6472bfb3b3 Mon Sep 17 00:00:00 2001 From: Raph Levien Date: Sun, 2 Jun 2013 18:09:40 -0700 Subject: [PATCH] Calibrate pitch envelope The rate was too slow, and not adaptive to sample rate. However, the "TAKE OFF" sample still sounds too fast, so more investigation is necessary. --- cpp/src/dx7note.cc | 3 +-- cpp/src/pitchenv.cc | 12 ++++++++---- cpp/src/pitchenv.h | 4 +++- cpp/src/synth_unit.cc | 2 ++ 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/cpp/src/dx7note.cc b/cpp/src/dx7note.cc index caf3e0d..dc33e90 100644 --- a/cpp/src/dx7note.cc +++ b/cpp/src/dx7note.cc @@ -170,7 +170,7 @@ void Dx7Note::init(const char patch[156], int midinote, int velocity) { rates[i] = patch[126 + i]; levels[i] = patch[130 + i]; } - pitchenv_.init(rates, levels); + pitchenv_.set(rates, levels); algorithm_ = patch[134]; int feedback = patch[135]; fb_shift_ = feedback != 0 ? 8 - feedback : 16; @@ -190,7 +190,6 @@ void Dx7Note::compute(int32_t *buf, int32_t lfo_val, int32_t lfo_delay) { int32_t level = env_[op].getsample(); int32_t gain = Exp2::lookup(level - (14 * (1 << 24))); //int32_t gain = pow(2, 10 + level * (1.0 / (1 << 24))); - // TODO: probably don't apply pitch env to fixed freq params_[op].freq = Freqlut::lookup(basepitch_[op] + pitchmod); params_[op].gain[1] = gain; } diff --git a/cpp/src/pitchenv.cc b/cpp/src/pitchenv.cc index 146421f..6c0780f 100644 --- a/cpp/src/pitchenv.cc +++ b/cpp/src/pitchenv.cc @@ -19,7 +19,13 @@ using namespace std; -void PitchEnv::init(const int r[4], const int l[4]) { +int PitchEnv::unit_; + +void PitchEnv::init(double sample_rate) { + unit_ = N * (1 << 24) / (21.3 * sample_rate) + 0.5; +} + +void PitchEnv::set(const int r[4], const int l[4]) { for (int i = 0; i < 4; i++) { rates_[i] = r[i]; levels_[i] = l[i]; @@ -81,9 +87,7 @@ void PitchEnv::advance(int newix) { targetlevel_ = pitchtab[newlevel] << 19; rising_ = (targetlevel_ > level_); - // TODO: adapt to sample rate - // const is 1<<12 / 0.0104 * 44100 - inc_ = ratetab[rates_[ix_]] * (8 * N); + inc_ = ratetab[rates_[ix_]] * unit_; } } diff --git a/cpp/src/pitchenv.h b/cpp/src/pitchenv.h index 65893db..a0c99df 100644 --- a/cpp/src/pitchenv.h +++ b/cpp/src/pitchenv.h @@ -21,16 +21,18 @@ class PitchEnv { public: + static void init(double sample_rate); // The rates and levels arrays are calibrated to match the Dx7 parameters // (ie, value 0..99). - void init(const int rates[4], const int levels[4]); + void set(const int rates[4], const int levels[4]); // Result is in Q24/octave int32_t getsample(); void keydown(bool down); private: + static int unit_; int rates_[4]; int levels_[4]; int32_t level_; diff --git a/cpp/src/synth_unit.cc b/cpp/src/synth_unit.cc index bc9e564..f2b3ec1 100644 --- a/cpp/src/synth_unit.cc +++ b/cpp/src/synth_unit.cc @@ -29,6 +29,7 @@ #include "freqlut.h" #include "sin.h" #include "exp2.h" +#include "pitchenv.h" #include "patch.h" #include "synth_unit.h" #include "aligned_buf.h" @@ -50,6 +51,7 @@ void SynthUnit::Init(double sample_rate) { Exp2::init(); Sin::init(); Lfo::init(sample_rate); + PitchEnv::init(sample_rate); } SynthUnit::SynthUnit(RingBuffer *ring_buffer) {