/* * Copyright 2017 Pascal Gauthier. * Copyright 2012 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef __ENV_H #define __ENV_H #include "synth.h" // DX7 envelope generation #define ACCURATE_ENVELOPE class Env { public: // The rates and levels arrays are calibrated to match the Dx7 parameters // (ie, value 0..99). The outlevel parameter is calibrated in microsteps // (ie units of approx .023 dB), with 99 * 32 = nominal full scale. The // rate_scaling parameter is in qRate units (ie 0..63). void init(const int rates[4], const int levels[4], int32_t outlevel, int rate_scaling); void update(const int rates[4], const int levels[4], int32_t 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 // value. First, the # of outputs scaling needs to be applied. Also, // modulation. // Then, of course, log to linear. int32_t getsample(); void keydown(bool down); static int scaleoutlevel(int outlevel); void getPosition(char *step); static void init_sr(FRAC_NUM sample_rate); 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; int rates_[4]; int levels_[4]; int outlevel_; int rate_scaling_; // Level is stored so that 2^24 is one doubling, ie 16 more bits than // the DX7 itself (fraction is stored in level rather than separate // counter) int32_t level_; int targetlevel_; bool rising_; int ix_; int inc_; #ifdef ACCURATE_ENVELOPE int staticcount_; #endif bool down_; void advance(int newix); }; #endif // __ENV_H