1 // Copyright 2014 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 // Modal synthesis voice.
28 
29 #ifndef ELEMENTS_DSP_VOICE_H_
30 #define ELEMENTS_DSP_VOICE_H_
31 
32 #include "stmlib/stmlib.h"
33 
34 #include "stmlib/dsp/filter.h"
35 
36 #include "elements/dsp/dsp.h"
37 #include "elements/dsp/exciter.h"
38 #include "elements/dsp/multistage_envelope.h"
39 #include "elements/dsp/patch.h"
40 #include "elements/dsp/resonator.h"
41 #include "elements/dsp/string.h"
42 #include "elements/dsp/tube.h"
43 
44 #include "elements/dsp/fx/diffuser.h"
45 
46 namespace elements {
47 
48 const size_t kNumStrings = 5;
49 
50 enum ResonatorModel {
51   RESONATOR_MODEL_MODAL,
52   RESONATOR_MODEL_STRING,
53   RESONATOR_MODEL_STRINGS,
54 };
55 
56 class Voice {
57  public:
Voice()58   Voice() { }
~Voice()59   ~Voice() { }
60 
61   void Init();
62   void Process(
63       const Patch& patch,
64       float frequency,
65       float strength,
66       const bool gate_in,
67       const float* blow_in,
68       const float* strike_in,
69       float* raw,
70       float* center,
71       float* sides,
72       size_t size);
73   // For metering.
exciter_level()74   inline float exciter_level() const { return exciter_level_; }
Panic()75   void Panic() {
76     ResetResonator();
77   }
set_resonator_model(ResonatorModel resonator_model)78   void set_resonator_model(ResonatorModel resonator_model) {
79     resonator_model_ = resonator_model;
80   }
81 
82  private:
83   void ResetResonator();
GetGateFlags(bool gate_in)84   inline uint8_t GetGateFlags(bool gate_in) {
85     uint8_t flags = 0;
86     if (gate_in) {
87       if (!previous_gate_) {
88         flags |= EXCITER_FLAG_RISING_EDGE;
89       }
90       flags |= EXCITER_FLAG_GATE;
91     } else if (previous_gate_) {
92       flags = EXCITER_FLAG_FALLING_EDGE;
93     }
94     previous_gate_ = gate_in;
95     return flags;
96   }
97 
98   MultistageEnvelope envelope_;
99   Tube tube_;
100   Exciter bow_;
101   Exciter blow_;
102   Exciter strike_;
103   Diffuser diffuser_;
104   Resonator resonator_;
105   String string_[kNumStrings];
106   stmlib::DCBlocker dc_blocker_;
107 
108   float strength_;
109   float envelope_value_;
110 
111   float exciter_level_;
112 
113   float bow_buffer_[kMaxBlockSize];
114   float bow_strength_buffer_[kMaxBlockSize];
115   float blow_buffer_[kMaxBlockSize];
116   float strike_buffer_[kMaxBlockSize];
117   float external_buffer_[kMaxBlockSize];
118 
119   float diffuser_buffer_[1024];
120 
121   bool previous_gate_;
122 
123   ResonatorModel resonator_model_;
124   float chord_index_;
125 
126   DISALLOW_COPY_AND_ASSIGN(Voice);
127 };
128 
129 }  // namespace elements
130 
131 #endif  // ELEMENTS_DSP_VOICE_H_
132