1 // Copyright 2013 Emilie Gillet.
2 //
3 // Author: Emilie Gillet (emilie.o.gillet@gmail.com)
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 // THE SOFTWARE.
22 //
23 // See http://creativecommons.org/licenses/MIT/ for more information.
24 //
25 // -----------------------------------------------------------------------------
26 //
27 // LFO.
28 
29 #ifndef PEAKS_MODULATIONS_LFO_H_
30 #define PEAKS_MODULATIONS_LFO_H_
31 
32 #include "stmlib/stmlib.h"
33 #include "stmlib/algorithms/pattern_predictor.h"
34 
35 #include "peaks/gate_processor.h"
36 
37 namespace peaks {
38 
39 enum LfoShape {
40   LFO_SHAPE_SINE,
41   LFO_SHAPE_TRIANGLE,
42   LFO_SHAPE_SQUARE,
43   LFO_SHAPE_STEPS,
44   LFO_SHAPE_NOISE,
45   LFO_SHAPE_LAST
46 };
47 
48 class Lfo {
49  public:
50   typedef int16_t (Lfo::*ComputeSampleFn)();
51 
Lfo()52   Lfo() { }
~Lfo()53   ~Lfo() { }
54 
55   void Init();
56   void Process(const GateFlags* gate_flags, int16_t* out, size_t size);
57 
Configure(uint16_t * parameter,ControlMode control_mode)58   void Configure(uint16_t* parameter, ControlMode control_mode) {
59     if (control_mode == CONTROL_MODE_HALF) {
60       if (sync_) {
61         set_shape_integer(parameter[0]);
62         set_parameter(parameter[1] - 32768);
63       } else {
64         set_rate(parameter[0]);
65         set_shape_parameter_preset(parameter[1]);
66       }
67       set_reset_phase(0);
68       set_level(40960);
69     } else {
70       if (sync_) {
71         set_level(parameter[0]);
72         set_shape_integer(parameter[1]);
73         set_parameter(parameter[2] - 32768);
74         set_reset_phase(parameter[3] - 32768);
75       } else {
76         set_level(40960);
77         set_rate(parameter[0]);
78         set_shape_integer(parameter[1]);
79         set_parameter(parameter[2] - 32768);
80         set_reset_phase(parameter[3] - 32768);
81       }
82     }
83   }
84 
set_rate(uint16_t rate)85   inline void set_rate(uint16_t rate) {
86     rate_ = rate;
87   }
88 
set_shape(LfoShape shape)89   inline void set_shape(LfoShape shape) {
90     shape_ = shape;
91   }
92 
set_shape_integer(uint16_t value)93   inline void set_shape_integer(uint16_t value) {
94     shape_ = static_cast<LfoShape>(value * LFO_SHAPE_LAST >> 16);
95   }
96 
97   void set_shape_parameter_preset(uint16_t value);
98 
set_parameter(int16_t parameter)99   inline void set_parameter(int16_t parameter) {
100     parameter_ = parameter;
101   }
102 
set_reset_phase(int16_t reset_phase)103   inline void set_reset_phase(int16_t reset_phase) {
104     reset_phase_ = static_cast<int32_t>(reset_phase) << 16;
105   }
106 
set_sync(bool sync)107   inline void set_sync(bool sync) {
108     if (!sync_ && sync) {
109       pattern_predictor_.Init();
110     }
111     sync_ = sync;
112   }
113 
set_level(uint16_t level)114   inline void set_level(uint16_t level) {
115     level_ = level >> 1;
116   }
117 
118  private:
119   int16_t ComputeSampleSine();
120   int16_t ComputeSampleTriangle();
121   int16_t ComputeSampleSquare();
122   int16_t ComputeSampleSteps();
123   int16_t ComputeSampleNoise();
124 
125   uint16_t rate_;
126   LfoShape shape_;
127   int16_t parameter_;
128   int32_t reset_phase_;
129   int32_t level_;
130 
131   bool sync_;
132   uint32_t sync_counter_;
133   stmlib::PatternPredictor<32, 8> pattern_predictor_;
134 
135   uint32_t phase_;
136   uint32_t phase_increment_;
137 
138   uint32_t period_;
139   uint32_t end_of_attack_;
140   uint32_t attack_factor_;
141   uint32_t decay_factor_;
142   int16_t previous_parameter_;
143 
144   int32_t value_;
145   int32_t next_value_;
146 
147   static ComputeSampleFn compute_sample_fn_table_[];
148 
149   DISALLOW_COPY_AND_ASSIGN(Lfo);
150 };
151 
152 }  // namespace peaks
153 
154 #endif  // PEAKS_MODULATIONS_LFO_H_
155