mirror of
https://github.com/jhbruhn/eurorack.git
synced 2025-03-14 18:55:48 +00:00
Add fake tides
This commit is contained in:
parent
a7b31cb9e7
commit
d7294bbc12
7 changed files with 581 additions and 4 deletions
81
pure_adsr/hysteresis_quantizer.h
Normal file
81
pure_adsr/hysteresis_quantizer.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
// Copyright 2015 Emilie Gillet.
|
||||
//
|
||||
// Author: Emilie Gillet (emilie.o.gillet@gmail.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
// See http://creativecommons.org/licenses/MIT/ for more information.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Quantize a float in [0, 1] to an integer in [0, num_steps[. Apply hysteresis
|
||||
// to prevent jumps near the decision boundary.
|
||||
|
||||
#ifndef STMLIB_DSP_HYSTERESIS_QUANTIZER_H_
|
||||
#define STMLIB_DSP_HYSTERESIS_QUANTIZER_H_
|
||||
|
||||
#include <avrlib/avrlib.h>
|
||||
|
||||
namespace pure_adsr {
|
||||
|
||||
class HysteresisQuantizer {
|
||||
public:
|
||||
HysteresisQuantizer() { }
|
||||
~HysteresisQuantizer() { }
|
||||
|
||||
void Init() {
|
||||
quantized_value_ = 0;
|
||||
}
|
||||
|
||||
inline int Process(float value, int num_steps) {
|
||||
return Process(value, num_steps, 0.25f);
|
||||
}
|
||||
|
||||
inline int Process(float value, int num_steps, float hysteresis) {
|
||||
return Process(0, value, num_steps, hysteresis);
|
||||
}
|
||||
|
||||
inline int Process(int base, float value, int num_steps, float hysteresis) {
|
||||
value *= static_cast<float>(num_steps - 1);
|
||||
value += static_cast<float>(base);
|
||||
float hysteresis_feedback = value > static_cast<float>(quantized_value_)
|
||||
? -hysteresis
|
||||
: hysteresis;
|
||||
int q = static_cast<int>(value + hysteresis_feedback + 0.5f);
|
||||
if(q < 0) q = 0;
|
||||
if(q > num_steps - 1) q = num_steps - 1;
|
||||
quantized_value_ = q;
|
||||
return q;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T& Lookup(const T* array, float value, int num_steps) {
|
||||
return array[Process(value, num_steps)];
|
||||
}
|
||||
|
||||
private:
|
||||
int quantized_value_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(HysteresisQuantizer);
|
||||
};
|
||||
|
||||
} // namespace stmlib
|
||||
|
||||
#endif // STMLIB_DSP_HYSTERESIS_QUANTIZER_H_
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
#include "pure_adsr/io_buffer.h"
|
||||
#include "pure_adsr/mini_sequencer.h"
|
||||
#include "pure_adsr/multistage_envelope.h"
|
||||
#include "pure_adsr/tides.h"
|
||||
|
||||
using namespace avrlib;
|
||||
using namespace pure_adsr;
|
||||
|
@ -20,7 +21,7 @@ using namespace pure_adsr;
|
|||
typedef enum {
|
||||
MODE_ADSR,
|
||||
MODE_SEQ,
|
||||
MODE_LFO
|
||||
MODE_TIDES
|
||||
} Mode;
|
||||
|
||||
typedef SpiMaster<Gpio<PortB, 2>, MSB_FIRST, 2> dac1Spi;
|
||||
|
@ -38,6 +39,7 @@ typedef AdcInputScanner AnalogInputs;
|
|||
|
||||
MultistageEnvelope envelope;
|
||||
MiniSequencer sequencer;
|
||||
Tides tides;
|
||||
|
||||
IOBuffer io_buffer;
|
||||
int16_t output_buffer[kBlockSize];
|
||||
|
@ -55,6 +57,7 @@ void Process(IOBuffer::Block* block, size_t size)
|
|||
pot_values[i] = read_value;
|
||||
envelope.Configure(pot_values, CONTROL_MODE_FULL);
|
||||
sequencer.Configure(pot_values, CONTROL_MODE_FULL);
|
||||
tides.Configure(pot_values, CONTROL_MODE_FULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,7 +69,9 @@ void Process(IOBuffer::Block* block, size_t size)
|
|||
break;
|
||||
case MODE_SEQ:
|
||||
sequencer.Process(block->input[i], output_buffer, size);
|
||||
default:
|
||||
break;
|
||||
case MODE_TIDES:
|
||||
tides.Process(block->input[i], output_buffer, size);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -101,6 +106,7 @@ void Init()
|
|||
pots[4 - (i + 1)] = AnalogInputs::Read8(i) << 8;
|
||||
envelope.Configure(pots, CONTROL_MODE_FULL);
|
||||
sequencer.Configure(pots, CONTROL_MODE_FULL);
|
||||
tides.Configure(pots, CONTROL_MODE_FULL);
|
||||
|
||||
Timer<2>::Start();
|
||||
}
|
||||
|
@ -128,7 +134,7 @@ TIMER_0_TICK
|
|||
mode = MODE_SEQ;
|
||||
break;
|
||||
case 1:
|
||||
mode = MODE_LFO;
|
||||
mode = MODE_TIDES;
|
||||
break;
|
||||
case 2:
|
||||
mode = MODE_ADSR;
|
||||
|
|
|
@ -215,10 +215,46 @@ const prog_uint32_t lut_res_env_increments[] PROGMEM = {
|
|||
253893, 249198, 244605, 240110, 235713, 231409, 227198, 223077,
|
||||
219043,
|
||||
};
|
||||
const prog_uint32_t lut_res_env_increments_slow[] PROGMEM = {
|
||||
35046933, 33184343, 31436989, 29796754, 28256163, 26808323, 25446875, 24165949,
|
||||
22960121, 21824376, 20754076, 19744924, 18792940, 17894435, 17045985, 16244414,
|
||||
15486770, 14770309, 14092480, 13450909, 12843386, 12267850, 11722382, 11205191,
|
||||
10714605, 10249065, 9807112, 9387383, 8988604, 8609583, 8249203, 7906418,
|
||||
7580249, 7269776, 6974139, 6692528, 6424184, 6168395, 5924489, 5691837,
|
||||
5469847, 5257961, 5055654, 4862432, 4677829, 4501406, 4332750, 4171471,
|
||||
4017200, 3869589, 3728311, 3593055, 3463528, 3339453, 3220568, 3106625,
|
||||
2997389, 2892639, 2792164, 2695765, 2603253, 2514449, 2429184, 2347295,
|
||||
2268632, 2193047, 2120405, 2050573, 1983428, 1918852, 1856732, 1796962,
|
||||
1739439, 1684069, 1630758, 1579418, 1529968, 1482327, 1436419, 1392173,
|
||||
1349520, 1308394, 1268733, 1230477, 1193569, 1157955, 1123584, 1090404,
|
||||
1058371, 1027437, 997560, 968699, 940814, 913868, 887824, 862647,
|
||||
838306, 814767, 792001, 769979, 748673, 728057, 708104, 688790,
|
||||
670093, 651989, 634458, 617477, 601028, 585092, 569649, 554684,
|
||||
540178, 526116, 512482, 499262, 486440, 474003, 461939, 450233,
|
||||
438875, 427852, 417153, 406766, 396683, 386891, 377383, 368148,
|
||||
359177, 350462, 341994, 333766, 325770, 317997, 310442, 303096,
|
||||
295954, 289009, 282255, 275685, 269295, 263077, 257028, 251142,
|
||||
245413, 239837, 234409, 229126, 223981, 218972, 214094, 209343,
|
||||
204715, 200207, 195816, 191537, 187368, 183304, 179344, 175484,
|
||||
171722, 168054, 164477, 160990, 157589, 154272, 151037, 147882,
|
||||
144803, 141800, 138869, 136010, 133219, 130496, 127837, 125242,
|
||||
122709, 120236, 117821, 115462, 113160, 110911, 108714, 106568,
|
||||
104472, 102424, 100423, 98468, 96557, 94690, 92865, 91081,
|
||||
89338, 87633, 85967, 84338, 82744, 81187, 79663, 78173,
|
||||
76716, 75290, 73895, 72531, 71196, 69890, 68612, 67362,
|
||||
66138, 64940, 63767, 62620, 61496, 60396, 59320, 58265,
|
||||
57233, 56222, 55232, 54262, 53313, 52382, 51471, 50579,
|
||||
49704, 48847, 48008, 47185, 46379, 45589, 44815, 44056,
|
||||
43313, 42584, 41869, 41168, 40481, 39808, 39148, 38500,
|
||||
37865, 37243, 36632, 36033, 35446, 34869, 34304, 33750,
|
||||
33206, 32672, 32148, 31634, 31130, 30635, 30150, 29673,
|
||||
29205,
|
||||
};
|
||||
|
||||
|
||||
const prog_uint32_t* const lookup_table_32_table[] = {
|
||||
lut_res_env_increments,
|
||||
lut_res_env_increments_slow,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ extern const prog_uint16_t lut_res_env_expo[] PROGMEM;
|
|||
extern const prog_uint16_t lut_res_env_quartic[] PROGMEM;
|
||||
extern const prog_uint16_t lut_res_raised_cosine[] PROGMEM;
|
||||
extern const prog_uint32_t lut_res_env_increments[] PROGMEM;
|
||||
extern const prog_uint32_t lut_res_env_increments_slow[] PROGMEM;
|
||||
#define STR_RES_DUMMY 0 // dummy
|
||||
#define LUT_RES_ENV_LINEAR 0
|
||||
#define LUT_RES_ENV_LINEAR_SIZE 257
|
||||
|
@ -55,6 +56,8 @@ extern const prog_uint32_t lut_res_env_increments[] PROGMEM;
|
|||
#define LUT_RES_RAISED_COSINE_SIZE 257
|
||||
#define LUT_RES_ENV_INCREMENTS 0
|
||||
#define LUT_RES_ENV_INCREMENTS_SIZE 257
|
||||
#define LUT_RES_ENV_INCREMENTS_SLOW 1
|
||||
#define LUT_RES_ENV_INCREMENTS_SLOW_SIZE 257
|
||||
|
||||
} // namespace pure_adsr
|
||||
|
||||
|
|
|
@ -61,6 +61,20 @@ lookup_tables_32.append(
|
|||
('env_increments', values)
|
||||
)
|
||||
|
||||
|
||||
max_time = 60.0 # seconds
|
||||
min_time = 0.05
|
||||
gamma = 0.175
|
||||
min_increment = excursion / (max_time * sample_rate)
|
||||
max_increment = excursion / (min_time * sample_rate)
|
||||
|
||||
rates = numpy.linspace(numpy.power(max_increment, -gamma),
|
||||
numpy.power(min_increment, -gamma), num_values)
|
||||
|
||||
values = numpy.power(rates, -1/gamma).astype(int)
|
||||
lookup_tables_32.append(
|
||||
('env_increments_slow', values)
|
||||
)
|
||||
"""----------------------------------------------------------------------------
|
||||
Envelope curves
|
||||
-----------------------------------------------------------------------------"""
|
||||
|
@ -69,7 +83,6 @@ env_linear = numpy.arange(0, 257.0) / 256.0
|
|||
env_linear[-1] = env_linear[-2]
|
||||
env_quartic = env_linear ** 3.32
|
||||
env_expo = 1.0 - numpy.exp(-4 * env_linear)
|
||||
|
||||
lookup_tables.append(('env_linear', env_linear / env_linear.max() * 65535.0))
|
||||
lookup_tables.append(('env_expo', env_expo / env_expo.max() * 65535.0))
|
||||
lookup_tables.append(
|
||||
|
|
89
pure_adsr/tides.cc
Normal file
89
pure_adsr/tides.cc
Normal file
|
@ -0,0 +1,89 @@
|
|||
// Copyright 2013 Emilie Gillet.
|
||||
//
|
||||
// Author: Emilie Gillet (emilie.o.gillet@gmail.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
// See http://creativecommons.org/licenses/MIT/ for more information.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Multistage envelope.
|
||||
|
||||
#include "pure_adsr/tides.h"
|
||||
|
||||
#include "pure_adsr/resources.h"
|
||||
|
||||
namespace pure_adsr {
|
||||
|
||||
void Tides::Init()
|
||||
{
|
||||
set_adsr(0, 8192, 16384, 32767);
|
||||
segment_ = num_segments_;
|
||||
phase_ = 0;
|
||||
phase_increment_ = 0;
|
||||
start_value_ = 0;
|
||||
value_ = 0;
|
||||
hard_reset_ = false;
|
||||
quant.Init();
|
||||
}
|
||||
|
||||
void Tides::Process(
|
||||
const GateFlags* gate_flags, int16_t* out, size_t size)
|
||||
{
|
||||
while (size--) {
|
||||
GateFlags gate_flag = *gate_flags++;
|
||||
if (gate_flag & GATE_FLAG_RISING) {
|
||||
start_value_ = (segment_ == num_segments_ || hard_reset_)
|
||||
? level_[0]
|
||||
: value_;
|
||||
segment_ = 0;
|
||||
phase_ = 0;
|
||||
} else if (gate_flag & GATE_FLAG_FALLING && sustain_point_) {
|
||||
start_value_ = value_;
|
||||
segment_ = sustain_point_;
|
||||
phase_ = 0;
|
||||
} else if (phase_ < phase_increment_) {
|
||||
start_value_ = level_[segment_ + 1];
|
||||
++segment_;
|
||||
phase_ = 0;
|
||||
if (segment_ == loop_end_) {
|
||||
segment_ = loop_start_;
|
||||
}
|
||||
}
|
||||
|
||||
bool done = segment_ == num_segments_;
|
||||
bool sustained = sustain_point_ && segment_ == sustain_point_ && gate_flag & GATE_FLAG_HIGH;
|
||||
|
||||
phase_increment_ = sustained || done ? 0 : pgm_read_dword(lut_res_env_increments_slow + (time_[segment_] >> 8));
|
||||
|
||||
int32_t a = start_value_;
|
||||
int32_t b = level_[segment_ + 1];
|
||||
|
||||
uint32_t x = pgm_read_word(lookup_table_table[LUT_RES_ENV_LINEAR + shape_[segment_]] + (phase_ >> 24));
|
||||
uint32_t y = pgm_read_word(lookup_table_table[LUT_RES_ENV_LINEAR + shape_[segment_]] + (phase_ >> 24) + 1);
|
||||
uint16_t t = x + ((y - x) * static_cast<uint32_t>((phase_ >> 8) & 0xffff) >> 16);
|
||||
|
||||
value_ = a + ((b - a) * (t >> 1) >> 15);
|
||||
phase_ += phase_increment_;
|
||||
*out++ = value_;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace peaks
|
349
pure_adsr/tides.h
Normal file
349
pure_adsr/tides.h
Normal file
|
@ -0,0 +1,349 @@
|
|||
// Copyright 2013 Emilie Gillet.
|
||||
//
|
||||
// Author: Emilie Gillet (emilie.o.gillet@gmail.com)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
// See http://creativecommons.org/licenses/MIT/ for more information.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Multistage envelope.
|
||||
|
||||
#ifndef PEAKS_MODULATIONS_TIDES_H_
|
||||
#define PEAKS_MODULATIONS_TIDES_H_
|
||||
|
||||
#include "pure_adsr/gate_processor.h"
|
||||
#include "pure_adsr/hysteresis_quantizer.h"
|
||||
#include "pure_adsr/multistage_envelope.h"
|
||||
#include <avrlib/avrlib.h>
|
||||
#include <stddef.h>
|
||||
|
||||
namespace pure_adsr {
|
||||
|
||||
class Tides {
|
||||
public:
|
||||
Tides() {}
|
||||
~Tides() {}
|
||||
|
||||
void Init();
|
||||
void Process(const GateFlags* gate_flags, int16_t* out, size_t size);
|
||||
|
||||
void Configure(uint16_t* parameter, ControlMode control_mode)
|
||||
{
|
||||
set_ar_loop(parameter[0], parameter[1]);
|
||||
|
||||
uint8_t waveform_mode = quant.Process(parameter[2] / 65536.0f, 5);
|
||||
|
||||
switch (waveform_mode) {
|
||||
case 0:
|
||||
shape_[0] = ENV_SHAPE_QUARTIC;
|
||||
shape_[1] = ENV_SHAPE_EXPONENTIAL;
|
||||
break;
|
||||
case 1:
|
||||
shape_[0] = ENV_SHAPE_QUARTIC;
|
||||
shape_[1] = ENV_SHAPE_QUARTIC;
|
||||
break;
|
||||
case 2:
|
||||
shape_[0] = ENV_SHAPE_LINEAR;
|
||||
shape_[1] = ENV_SHAPE_LINEAR;
|
||||
break;
|
||||
case 3:
|
||||
shape_[0] = ENV_SHAPE_EXPONENTIAL;
|
||||
shape_[1] = ENV_SHAPE_EXPONENTIAL;
|
||||
break;
|
||||
case 4:
|
||||
shape_[0] = ENV_SHAPE_EXPONENTIAL;
|
||||
shape_[1] = ENV_SHAPE_QUARTIC;
|
||||
break;
|
||||
}
|
||||
|
||||
if (segment_ > num_segments_) {
|
||||
segment_ = 0;
|
||||
phase_ = 0;
|
||||
value_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline void set_time(uint16_t segment, uint16_t time)
|
||||
{
|
||||
time_[segment] = time;
|
||||
}
|
||||
|
||||
inline void set_level(uint16_t segment, int16_t level)
|
||||
{
|
||||
level_[segment] = level;
|
||||
}
|
||||
|
||||
inline void set_num_segments(uint16_t num_segments)
|
||||
{
|
||||
num_segments_ = num_segments;
|
||||
}
|
||||
|
||||
inline void set_sustain_point(uint16_t sustain_point)
|
||||
{
|
||||
sustain_point_ = sustain_point;
|
||||
}
|
||||
|
||||
inline void set_adsr(
|
||||
uint16_t attack,
|
||||
uint16_t decay,
|
||||
uint16_t sustain,
|
||||
uint16_t release)
|
||||
{
|
||||
num_segments_ = 3;
|
||||
sustain_point_ = 2;
|
||||
|
||||
level_[0] = 0;
|
||||
level_[1] = 32767;
|
||||
level_[2] = sustain;
|
||||
level_[3] = 0;
|
||||
|
||||
time_[0] = attack;
|
||||
time_[1] = decay;
|
||||
time_[2] = release;
|
||||
|
||||
shape_[0] = ENV_SHAPE_QUARTIC;
|
||||
shape_[1] = ENV_SHAPE_EXPONENTIAL;
|
||||
shape_[2] = ENV_SHAPE_EXPONENTIAL;
|
||||
|
||||
loop_start_ = loop_end_ = 0;
|
||||
}
|
||||
|
||||
inline void set_ad(uint16_t attack, uint16_t decay)
|
||||
{
|
||||
num_segments_ = 2;
|
||||
sustain_point_ = 0;
|
||||
|
||||
level_[0] = 0;
|
||||
level_[1] = 32767;
|
||||
level_[2] = 0;
|
||||
|
||||
time_[0] = attack;
|
||||
time_[1] = decay;
|
||||
|
||||
shape_[0] = ENV_SHAPE_EXPONENTIAL;
|
||||
shape_[1] = ENV_SHAPE_EXPONENTIAL;
|
||||
|
||||
loop_start_ = loop_end_ = 0;
|
||||
}
|
||||
|
||||
inline void set_adr(
|
||||
uint16_t attack,
|
||||
uint16_t decay,
|
||||
uint16_t sustain,
|
||||
uint16_t release)
|
||||
{
|
||||
num_segments_ = 3;
|
||||
sustain_point_ = 0;
|
||||
|
||||
level_[0] = 0;
|
||||
level_[1] = 32767;
|
||||
level_[2] = sustain;
|
||||
level_[3] = 0;
|
||||
|
||||
time_[0] = attack;
|
||||
time_[1] = decay;
|
||||
time_[2] = release;
|
||||
|
||||
shape_[0] = ENV_SHAPE_LINEAR;
|
||||
shape_[1] = ENV_SHAPE_LINEAR;
|
||||
shape_[2] = ENV_SHAPE_LINEAR;
|
||||
|
||||
loop_start_ = loop_end_ = 0;
|
||||
}
|
||||
|
||||
inline void set_ar(uint16_t attack, uint16_t decay)
|
||||
{
|
||||
num_segments_ = 2;
|
||||
sustain_point_ = 1;
|
||||
|
||||
level_[0] = 0;
|
||||
level_[1] = 32767;
|
||||
level_[2] = 0;
|
||||
|
||||
time_[0] = attack;
|
||||
time_[1] = decay;
|
||||
|
||||
shape_[0] = ENV_SHAPE_LINEAR;
|
||||
shape_[1] = ENV_SHAPE_LINEAR;
|
||||
|
||||
loop_start_ = loop_end_ = 0;
|
||||
}
|
||||
|
||||
inline void set_adsar(
|
||||
uint16_t attack,
|
||||
uint16_t decay,
|
||||
uint16_t sustain,
|
||||
uint16_t release)
|
||||
{
|
||||
num_segments_ = 4;
|
||||
sustain_point_ = 2;
|
||||
|
||||
level_[0] = 0;
|
||||
level_[1] = 32767;
|
||||
level_[2] = sustain;
|
||||
level_[3] = 32767;
|
||||
level_[4] = 0;
|
||||
|
||||
time_[0] = attack;
|
||||
time_[1] = decay;
|
||||
time_[2] = attack;
|
||||
time_[3] = release;
|
||||
|
||||
shape_[0] = ENV_SHAPE_LINEAR;
|
||||
shape_[1] = ENV_SHAPE_LINEAR;
|
||||
shape_[2] = ENV_SHAPE_LINEAR;
|
||||
shape_[3] = ENV_SHAPE_LINEAR;
|
||||
|
||||
loop_start_ = loop_end_ = 0;
|
||||
}
|
||||
|
||||
inline void set_adar(
|
||||
uint16_t attack,
|
||||
uint16_t decay,
|
||||
uint16_t sustain,
|
||||
uint16_t release)
|
||||
{
|
||||
num_segments_ = 4;
|
||||
sustain_point_ = 0;
|
||||
|
||||
level_[0] = 0;
|
||||
level_[1] = 32767;
|
||||
level_[2] = sustain;
|
||||
level_[3] = 32767;
|
||||
level_[4] = 0;
|
||||
|
||||
time_[0] = attack;
|
||||
time_[1] = decay;
|
||||
time_[2] = attack;
|
||||
time_[3] = release;
|
||||
|
||||
shape_[0] = ENV_SHAPE_LINEAR;
|
||||
shape_[1] = ENV_SHAPE_LINEAR;
|
||||
shape_[2] = ENV_SHAPE_LINEAR;
|
||||
shape_[3] = ENV_SHAPE_LINEAR;
|
||||
|
||||
loop_start_ = loop_end_ = 0;
|
||||
}
|
||||
|
||||
inline void set_ad_loop(uint16_t attack, uint16_t decay)
|
||||
{
|
||||
num_segments_ = 2;
|
||||
sustain_point_ = 0;
|
||||
|
||||
level_[0] = 0;
|
||||
level_[1] = 32767;
|
||||
level_[2] = 0;
|
||||
|
||||
time_[0] = attack;
|
||||
time_[1] = decay;
|
||||
|
||||
shape_[0] = ENV_SHAPE_LINEAR;
|
||||
shape_[1] = ENV_SHAPE_LINEAR;
|
||||
|
||||
loop_start_ = 0;
|
||||
loop_end_ = 2;
|
||||
}
|
||||
|
||||
inline void set_adr_loop(
|
||||
uint16_t attack,
|
||||
uint16_t decay,
|
||||
uint16_t sustain,
|
||||
uint16_t release)
|
||||
{
|
||||
num_segments_ = 3;
|
||||
sustain_point_ = 0;
|
||||
|
||||
level_[0] = 0;
|
||||
level_[1] = 32767;
|
||||
level_[2] = sustain;
|
||||
level_[3] = 0;
|
||||
|
||||
time_[0] = attack;
|
||||
time_[1] = decay;
|
||||
time_[2] = release;
|
||||
|
||||
shape_[0] = ENV_SHAPE_LINEAR;
|
||||
shape_[1] = ENV_SHAPE_LINEAR;
|
||||
shape_[2] = ENV_SHAPE_LINEAR;
|
||||
|
||||
loop_start_ = 0;
|
||||
loop_end_ = 3;
|
||||
}
|
||||
|
||||
inline void set_adar_loop(
|
||||
uint16_t attack,
|
||||
uint16_t decay,
|
||||
uint16_t sustain,
|
||||
uint16_t release)
|
||||
{
|
||||
num_segments_ = 4;
|
||||
sustain_point_ = 0;
|
||||
|
||||
level_[0] = 0;
|
||||
level_[1] = 32767;
|
||||
level_[2] = sustain;
|
||||
level_[3] = 32767;
|
||||
level_[4] = 0;
|
||||
|
||||
time_[0] = attack;
|
||||
time_[1] = decay;
|
||||
time_[2] = attack;
|
||||
time_[3] = release;
|
||||
|
||||
shape_[0] = ENV_SHAPE_LINEAR;
|
||||
shape_[1] = ENV_SHAPE_LINEAR;
|
||||
shape_[2] = ENV_SHAPE_LINEAR;
|
||||
shape_[3] = ENV_SHAPE_LINEAR;
|
||||
|
||||
loop_start_ = 0;
|
||||
loop_end_ = 4;
|
||||
}
|
||||
|
||||
inline void set_hard_reset(bool hard_reset)
|
||||
{
|
||||
hard_reset_ = hard_reset;
|
||||
}
|
||||
|
||||
private:
|
||||
int16_t level_[kMaxNumSegments];
|
||||
uint16_t time_[kMaxNumSegments];
|
||||
EnvelopeShape shape_[kMaxNumSegments];
|
||||
|
||||
int16_t segment_;
|
||||
int16_t start_value_;
|
||||
int16_t value_;
|
||||
|
||||
uint32_t phase_;
|
||||
uint32_t phase_increment_;
|
||||
|
||||
uint16_t num_segments_;
|
||||
uint16_t sustain_point_;
|
||||
uint16_t loop_start_;
|
||||
uint16_t loop_end_;
|
||||
|
||||
bool hard_reset_;
|
||||
HysteresisQuantizer quant;
|
||||
DISALLOW_COPY_AND_ASSIGN(Tides);
|
||||
};
|
||||
|
||||
} // namespace peaks
|
||||
|
||||
#endif // PEAKS_MODULATIONS_MULTISTAGE_ENVELOPE_H_
|
Loading…
Reference in a new issue