1 // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html
2 
3 #include "smmorphoutputmodule.hh"
4 #include "smmorphutils.hh"
5 
6 using namespace SpectMorph;
7 
8 namespace SpectMorph
9 {
10 
11 class SimpleEnvelope
12 {
13   double decrement;
14   double level;
15   enum class State {
16     ON,
17     RELEASE,
18     DONE
19   } state;
20 
21 public:
SimpleEnvelope(float mix_freq)22   SimpleEnvelope (float mix_freq)
23   {
24     const float release_ms = 150; /* FIXME: this should be set by the user */
25     decrement = (1000.0 / mix_freq) / release_ms;
26   }
27   void
retrigger()28   retrigger()
29   {
30     state = State::ON;
31     level = 1.0;
32   }
33   void
release()34   release()
35   {
36     state = State::RELEASE;
37   }
38   bool
done() const39   done() const
40   {
41     return state == State::DONE;
42   }
43   void
process(size_t n_values,float * values)44   process (size_t n_values, float *values)
45   {
46     if (state == State::ON)
47       {
48         return; // nothing
49       }
50     else if (state == State::RELEASE)
51       {
52         for (size_t i = 0; i < n_values; i++)
53           {
54             level -= decrement;
55             if (level > 0)
56               values[i] *= level;
57             else
58               values[i] = 0;
59           }
60         if (level < 0)
61           state = State::DONE;
62       }
63     else // state == State::DONE
64       {
65         zero_float_block (n_values, values);
66       }
67   }
68 };
69 
70 class EffectDecoderSource : public LiveDecoderSource
71 {
72   LiveDecoderSource *source;
73   Audio              m_audio;
74   float              m_skip;
75 public:
76   explicit EffectDecoderSource (LiveDecoderSource *source);
77 
78   void retrigger (int channel, float freq, int midi_velocity, float mix_freq) override;
79   Audio* audio() override;
80   AudioBlock* audio_block (size_t index) override;
81 
82   void set_skip (float m_skip);
83 };
84 
85 }
86 
87 void
retrigger(int channel,float freq,int midi_velocity,float mix_freq)88 EffectDecoderSource::retrigger (int channel, float freq, int midi_velocity, float mix_freq)
89 {
90   source->retrigger (channel, freq, midi_velocity, mix_freq);
91 }
92 
93 Audio*
audio()94 EffectDecoderSource::audio()
95 {
96   return &m_audio;
97 }
98 
99 AudioBlock*
audio_block(size_t index)100 EffectDecoderSource::audio_block (size_t index)
101 {
102   const double time_ms = index + m_skip; // 1ms frame step
103 
104   return MorphUtils::get_normalized_block_ptr (source, time_ms);
105 }
106 
107 void
set_skip(float skip)108 EffectDecoderSource::set_skip (float skip)
109 {
110   m_skip = skip;
111 }
112 
EffectDecoderSource(LiveDecoderSource * source)113 EffectDecoderSource::EffectDecoderSource (LiveDecoderSource *source) :
114   source (source),
115   m_skip (0)
116 {
117   m_audio.fundamental_freq     = 440;
118   m_audio.mix_freq             = 48000;
119   m_audio.frame_size_ms        = 1;
120   m_audio.frame_step_ms        = 1;
121   m_audio.zeropad              = 4;
122   m_audio.loop_type            = Audio::LOOP_NONE;
123 }
124 
EffectDecoder(LiveDecoderSource * source)125 EffectDecoder::EffectDecoder (LiveDecoderSource *source) :
126   original_source (source),
127   skip_source (new EffectDecoderSource (source))
128 {
129   chain_decoder.reset (new LiveDecoder (original_source));
130   use_skip_source = false;
131 }
132 
~EffectDecoder()133 EffectDecoder::~EffectDecoder()
134 {
135 }
136 
137 void
set_config(MorphOutput * output,float mix_freq)138 EffectDecoder::set_config (MorphOutput *output, float mix_freq)
139 {
140   if (output->adsr())
141     {
142       if (!use_skip_source) // enable skip source
143         {
144           chain_decoder.reset (new LiveDecoder (skip_source.get()));
145           chain_decoder->enable_start_skip (true);
146           use_skip_source = true;
147         }
148       skip_source->set_skip (output->adsr_skip());
149 
150       if (!adsr_envelope)
151         adsr_envelope.reset (new ADSREnvelope());
152 
153       adsr_envelope->set_config (output->adsr_attack(),
154                                  output->adsr_decay(),
155                                  output->adsr_sustain(),
156                                  output->adsr_release(),
157                                  mix_freq);
158     }
159   else
160     {
161       if (use_skip_source) // use original source (no skip)
162         {
163           chain_decoder.reset (new LiveDecoder (original_source));
164           use_skip_source = false;
165         }
166       adsr_envelope.reset();
167 
168       if (!simple_envelope)
169         simple_envelope.reset (new SimpleEnvelope (mix_freq));
170     }
171 
172   chain_decoder->enable_noise (output->noise());
173   chain_decoder->enable_sines (output->sines());
174 
175   if (output->unison()) // unison?
176     chain_decoder->set_unison_voices (output->unison_voices(), output->unison_detune());
177   else
178     chain_decoder->set_unison_voices (1, 0);
179 
180   chain_decoder->set_vibrato (output->vibrato(), output->vibrato_depth(), output->vibrato_frequency(), output->vibrato_attack());
181 }
182 
183 void
retrigger(int channel,float freq,int midi_velocity,float mix_freq)184 EffectDecoder::retrigger (int channel, float freq, int midi_velocity, float mix_freq)
185 {
186   g_assert (chain_decoder);
187 
188   if (adsr_envelope)
189     adsr_envelope->retrigger();
190   else
191     simple_envelope->retrigger();
192 
193   chain_decoder->retrigger (channel, freq, midi_velocity, mix_freq);
194 }
195 
196 void
process(size_t n_values,const float * freq_in,float * audio_out)197 EffectDecoder::process (size_t       n_values,
198                         const float *freq_in,
199                         float       *audio_out)
200 {
201   g_assert (chain_decoder);
202 
203   chain_decoder->process (n_values, freq_in, audio_out);
204 
205   if (adsr_envelope)
206     adsr_envelope->process (n_values, audio_out);
207   else
208     simple_envelope->process (n_values, audio_out);
209 }
210 
211 void
release()212 EffectDecoder::release()
213 {
214   if (adsr_envelope)
215     adsr_envelope->release();
216   else
217     simple_envelope->release();
218 }
219 
220 bool
done()221 EffectDecoder::done()
222 {
223   if (adsr_envelope)
224     return adsr_envelope->done();
225   else
226     return simple_envelope->done();
227 }
228 
229 double
time_offset_ms() const230 EffectDecoder::time_offset_ms() const
231 {
232   return chain_decoder->time_offset_ms();
233 }
234