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.
master
Raph Levien 12 years ago
parent f52201cc11
commit 64ad13bb4a
  1. 3
      cpp/src/dx7note.cc
  2. 12
      cpp/src/pitchenv.cc
  3. 4
      cpp/src/pitchenv.h
  4. 2
      cpp/src/synth_unit.cc

@ -170,7 +170,7 @@ void Dx7Note::init(const char patch[156], int midinote, int velocity) {
rates[i] = patch[126 + i]; rates[i] = patch[126 + i];
levels[i] = patch[130 + i]; levels[i] = patch[130 + i];
} }
pitchenv_.init(rates, levels); pitchenv_.set(rates, levels);
algorithm_ = patch[134]; algorithm_ = patch[134];
int feedback = patch[135]; int feedback = patch[135];
fb_shift_ = feedback != 0 ? 8 - feedback : 16; 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 level = env_[op].getsample();
int32_t gain = Exp2::lookup(level - (14 * (1 << 24))); int32_t gain = Exp2::lookup(level - (14 * (1 << 24)));
//int32_t gain = pow(2, 10 + level * (1.0 / (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].freq = Freqlut::lookup(basepitch_[op] + pitchmod);
params_[op].gain[1] = gain; params_[op].gain[1] = gain;
} }

@ -19,7 +19,13 @@
using namespace std; 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++) { for (int i = 0; i < 4; i++) {
rates_[i] = r[i]; rates_[i] = r[i];
levels_[i] = l[i]; levels_[i] = l[i];
@ -81,9 +87,7 @@ void PitchEnv::advance(int newix) {
targetlevel_ = pitchtab[newlevel] << 19; targetlevel_ = pitchtab[newlevel] << 19;
rising_ = (targetlevel_ > level_); rising_ = (targetlevel_ > level_);
// TODO: adapt to sample rate inc_ = ratetab[rates_[ix_]] * unit_;
// const is 1<<12 / 0.0104 * 44100
inc_ = ratetab[rates_[ix_]] * (8 * N);
} }
} }

@ -21,16 +21,18 @@
class PitchEnv { class PitchEnv {
public: public:
static void init(double sample_rate);
// The rates and levels arrays are calibrated to match the Dx7 parameters // The rates and levels arrays are calibrated to match the Dx7 parameters
// (ie, value 0..99). // (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 // Result is in Q24/octave
int32_t getsample(); int32_t getsample();
void keydown(bool down); void keydown(bool down);
private: private:
static int unit_;
int rates_[4]; int rates_[4];
int levels_[4]; int levels_[4];
int32_t level_; int32_t level_;

@ -29,6 +29,7 @@
#include "freqlut.h" #include "freqlut.h"
#include "sin.h" #include "sin.h"
#include "exp2.h" #include "exp2.h"
#include "pitchenv.h"
#include "patch.h" #include "patch.h"
#include "synth_unit.h" #include "synth_unit.h"
#include "aligned_buf.h" #include "aligned_buf.h"
@ -50,6 +51,7 @@ void SynthUnit::Init(double sample_rate) {
Exp2::init(); Exp2::init();
Sin::init(); Sin::init();
Lfo::init(sample_rate); Lfo::init(sample_rate);
PitchEnv::init(sample_rate);
} }
SynthUnit::SynthUnit(RingBuffer *ring_buffer) { SynthUnit::SynthUnit(RingBuffer *ring_buffer) {

Loading…
Cancel
Save