diff --git a/_audio_effect_8h_source.html b/_audio_effect_8h_source.html index 0b7944bd25..7cf86aa224 100644 --- a/_audio_effect_8h_source.html +++ b/_audio_effect_8h_source.html @@ -73,406 +73,549 @@
2 #include "AudioEffects/AudioParameters.h"
3 #include "AudioEffects/PitchShift.h"
4 #include "AudioTools/AudioLogger.h"
-
5 #include <stdint.h>
-
6 
-
7 namespace audio_tools {
-
8 
-
9 // we use int16_t for our effects
-
10 typedef int16_t effect_t;
-
11 
-
19 class AudioEffect {
-
20 public:
-
21  AudioEffect() = default;
-
22  virtual ~AudioEffect() = default;
-
23 
-
25  virtual effect_t process(effect_t in) = 0;
-
26 
-
28  virtual void setActive(bool value) { active_flag = value; }
-
29 
-
31  virtual bool active() { return active_flag; }
-
32 
-
33  virtual AudioEffect *clone() = 0;
-
34 
-
36  int id() { return id_value; }
-
37 
-
39  void setId(int id) { this->id_value = id; }
-
40 
-
41 protected:
-
42  bool active_flag = true;
-
43  int id_value = -1;
-
44 
-
45  void copyParent(AudioEffect *copy) {
-
46  id_value = copy->id_value;
-
47  active_flag = copy->active_flag;
-
48  }
-
49 
-
51  int16_t clip(int32_t in, int16_t clipLimit = 32767,
-
52  int16_t resultLimit = 32767) {
-
53  int32_t result = in;
-
54  if (result > clipLimit) {
-
55  result = resultLimit;
-
56  }
-
57  if (result < -clipLimit) {
-
58  result = -resultLimit;
-
59  }
-
60  return result;
-
61  }
-
62 };
-
63 
-
72 class Boost : public AudioEffect {
-
73 public:
-
76  Boost(float volume = 1.0) { effect_value = volume; }
-
77 
-
78  Boost(const Boost &copy) = default;
-
79 
-
80  float volume() { return effect_value; }
-
81 
-
82  void setVolume(float volume) { effect_value = volume; }
-
83 
-
84  effect_t process(effect_t input) {
-
85  if (!active())
-
86  return input;
-
87  int32_t result = effect_value * input;
-
88  // clip to int16_t
-
89  return clip(result);
-
90  }
-
91 
-
92  Boost *clone() { return new Boost(*this); }
-
93 
-
94 protected:
-
95  float effect_value;
-
96 };
-
97 
-
105 class Distortion : public AudioEffect {
-
106 public:
-
108  Distortion(int16_t clipThreashold = 4990, int16_t maxInput = 6500) {
-
109  p_clip_threashold = clipThreashold;
-
110  max_input = maxInput;
-
111  }
-
112 
-
113  Distortion(const Distortion &copy) = default;
-
114 
-
115  void setClipThreashold(int16_t th) { p_clip_threashold = th; }
-
116 
-
117  int16_t clipThreashold() { return p_clip_threashold; }
-
118 
-
119  void setMaxInput(int16_t maxInput) { max_input = maxInput; }
-
120 
-
121  int16_t maxInput() { return max_input; }
-
122 
-
123  effect_t process(effect_t input) {
-
124  if (!active())
-
125  return input;
-
126  // the input signal is 16bits (values from -32768 to +32768
-
127  // the value of input is clipped to the distortion_threshold value
-
128  return clip(input, p_clip_threashold, max_input);
-
129  }
-
130 
-
131  Distortion *clone() { return new Distortion(*this); }
-
132 
-
133 protected:
-
134  int16_t p_clip_threashold;
-
135  int16_t max_input;
-
136 };
-
137 
-
145 class Fuzz : public AudioEffect {
-
146 public:
-
148  Fuzz(float fuzzEffectValue = 6.5, uint16_t maxOut = 300) {
-
149  p_effect_value = fuzzEffectValue;
-
150  max_out = maxOut;
-
151  }
-
152 
-
153  Fuzz(const Fuzz &copy) = default;
-
154 
-
155  void setFuzzEffectValue(float v) { p_effect_value = v; }
-
156 
-
157  float fuzzEffectValue() { return p_effect_value; }
-
158 
-
159  void setMaxOut(uint16_t v) { max_out = v; }
-
160 
-
161  uint16_t maxOut() { return max_out; }
-
162 
-
163  effect_t process(effect_t input) {
-
164  if (!active())
-
165  return input;
-
166  float v = p_effect_value;
-
167  int32_t result = clip(v * input);
-
168  return map(result * v, -32768, +32767, -max_out, max_out);
-
169  }
-
170 
-
171  Fuzz *clone() { return new Fuzz(*this); }
-
172 
-
173 protected:
-
174  float p_effect_value;
-
175  uint16_t max_out;
-
176 };
-
177 
-
185 class Tremolo : public AudioEffect {
-
186 public:
-
189  Tremolo(int16_t duration_ms = 2000, uint8_t depthPercent = 50,
-
190  uint32_t sampleRate = 44100) {
-
191  this->duration_ms = duration_ms;
-
192  this->sampleRate = sampleRate;
-
193  this->p_percent = depthPercent;
-
194  int32_t rate_count = sampleRate * duration_ms / 1000;
-
195  rate_count_half = rate_count / 2;
-
196  }
-
197 
-
198  Tremolo(const Tremolo &copy) = default;
-
199 
-
200  void setDuration(int16_t ms) {
-
201  int32_t rate_count = sampleRate * ms / 1000;
-
202  rate_count_half = rate_count / 2;
-
203  }
-
204 
-
205  int16_t duration() { return duration_ms; }
-
206 
-
207  void setDepth(uint8_t percent) { p_percent = percent; }
-
208 
-
209  uint8_t depth() { return p_percent; }
-
210 
-
211  effect_t process(effect_t input) {
-
212  if (!active())
-
213  return input;
-
214 
-
215  // limit value to max 100% and calculate factors
-
216  float tremolo_depth = p_percent > 100 ? 1.0 : 0.01 * p_percent;
-
217  float signal_depth = (100.0 - p_percent) / 100.0;
-
218 
-
219  float tremolo_factor = tremolo_depth / rate_count_half;
-
220  int32_t out = (signal_depth * input) + (tremolo_factor * count * input);
-
221 
-
222  // saw tooth shaped counter
-
223  count += inc;
-
224  if (count >= rate_count_half) {
-
225  inc = -1;
-
226  } else if (count <= 0) {
-
227  inc = +1;
-
228  }
-
229 
-
230  return clip(out);
-
231  }
-
232 
-
233  Tremolo *clone() { return new Tremolo(*this); }
-
234 
-
235 protected:
-
236  int16_t duration_ms;
-
237  uint32_t sampleRate;
-
238  int32_t count = 0;
-
239  int16_t inc = 1;
-
240  int32_t rate_count_half; // number of samples for on raise and fall
-
241  uint8_t p_percent;
-
242 };
-
243 
-
252 class Delay : public AudioEffect {
-
253 public:
-
255  Delay(uint16_t duration_ms = 1000, float depth = 0.5,
-
256  float feedbackAmount = 1.0, uint32_t sampleRate = 44100,
-
257  bool zeroIfBufferEmpty = false) {
-
258  setSampleRate(sampleRate);
-
259  setFeedback(feedbackAmount);
-
260  setDepth(depth);
-
261  setDuration(duration_ms);
-
262  }
-
263 
-
264  Delay(const Delay &copy) {
-
265  setSampleRate(copy.sampleRate);
-
266  setFeedback(copy.feedback);
-
267  setDepth(copy.depth);
-
268  setDuration(copy.duration);
-
269  };
-
270 
-
271  void setDuration(int16_t dur) {
-
272  duration = dur;
-
273  updateBufferSize();
-
274  }
-
275 
-
276  int16_t getDuration() { return duration; }
-
277 
-
278  void setDepth(float value) {
-
279  depth = value;
-
280  if (depth > 1.0)
-
281  depth = 1.0;
-
282  if (depth < 0)
-
283  depth = 0.0;
-
284  }
-
285 
-
286  float getDepth() { return depth; }
-
287 
-
288  void setFeedback(float feed) {
-
289  feedback = feed;
-
290  if (feedback > 1.0)
-
291  feedback = 1.0;
-
292  if (feedback < 0)
-
293  feedback = 0.0;
-
294  }
-
295 
-
296  float getFeedback() { return feedback; }
-
297 
-
298  void setSampleRate(int32_t sample) {
-
299  sampleRate = sample;
-
300  updateBufferSize();
-
301  }
-
302 
-
303  float getSampleRate() { return sampleRate; }
-
304 
-
305  effect_t process(effect_t input) {
-
306  if (!active())
-
307  return input;
-
308 
-
309  // Read last audio sample in each delay line
-
310  int32_t delayed_value = buffer[delay_line_index];
-
311 
-
312  // Mix the above with current audio and write the results back to output
-
313  int32_t out = ((1.0 - depth) * input) + (depth * delayed_value);
-
314 
-
315  // Update each delay line
-
316  buffer[delay_line_index] = clip(feedback * (delayed_value + input));
-
317 
-
318  // Finally, update the delay line index
-
319  if (delay_line_index++ >= delay_len_samples) {
-
320  delay_line_index = 0;
-
321  }
-
322  return clip(out);
-
323  }
-
324 
-
325  Delay *clone() { return new Delay(*this); }
-
326 
-
327 protected:
-
328  Vector<effect_t> buffer{0};
-
329  float feedback = 0.0, duration = 0.0, sampleRate = 0.0, depth = 0.0;
-
330  size_t delay_len_samples = 0;
-
331  size_t delay_line_index = 0;
-
332 
-
333  void updateBufferSize() {
-
334  if (sampleRate > 0 && duration > 0) {
-
335  size_t newSampleCount = sampleRate * duration / 1000;
-
336  if (newSampleCount != delay_len_samples) {
-
337  delay_len_samples = newSampleCount;
-
338  buffer.resize(delay_len_samples);
-
339  memset(buffer.data(),0,delay_len_samples*sizeof(effect_t));
-
340  LOGD("sample_count: %u", (unsigned)delay_len_samples);
-
341  }
-
342  }
-
343  }
-
344 };
-
345 
-
361 class ADSRGain : public AudioEffect {
-
362 public:
-
363  ADSRGain(float attack = 0.001, float decay = 0.001, float sustainLevel = 0.5,
-
364  float release = 0.005, float boostFactor = 1.0) {
-
365  this->factor = boostFactor;
-
366  adsr = new ADSR(attack, decay, sustainLevel, release);
-
367  }
-
368 
-
369  ADSRGain(const ADSRGain &ref) {
-
370  adsr = new ADSR(*(ref.adsr));
-
371  factor = ref.factor;
-
372  copyParent((AudioEffect *)&ref);
-
373  };
-
374 
-
375  virtual ~ADSRGain() { delete adsr; }
-
376 
-
377  void setAttackRate(float a) { adsr->setAttackRate(a); }
-
378 
-
379  float attackRate() { return adsr->attackRate(); }
-
380 
-
381  void setDecayRate(float d) { adsr->setDecayRate(d); }
-
382 
-
383  float decayRate() { return adsr->decayRate(); }
-
384 
-
385  void setSustainLevel(float s) { adsr->setSustainLevel(s); }
-
386 
-
387  float sustainLevel() { return adsr->sustainLevel(); }
-
388 
-
389  void setReleaseRate(float r) { adsr->setReleaseRate(r); }
-
390 
-
391  float releaseRate() { return adsr->releaseRate(); }
-
392 
-
393  void keyOn(float tgt = 0) { adsr->keyOn(tgt); }
-
394 
-
395  void keyOff() { adsr->keyOff(); }
-
396 
-
397  effect_t process(effect_t input) {
-
398  effect_t result = factor * adsr->tick() * input;
-
399  return result;
-
400  }
-
401 
-
402  bool isActive() { return adsr->isActive(); }
-
403 
-
404  ADSRGain *clone() { return new ADSRGain(*this); }
-
405 
-
406 protected:
-
407  ADSR *adsr;
-
408  float factor;
-
409 };
-
410 
-
417 class PitchShift : public AudioEffect {
-
418 public:
-
421  PitchShift(float shift_value = 1.0, int buffer_size = 1000) {
-
422  effect_value = shift_value;
-
423  size = buffer_size;
-
424  buffer.resize(buffer_size);
-
425  buffer.setIncrement(shift_value);
-
426  }
-
427 
-
428  PitchShift(const PitchShift &ref) {
-
429  size = ref.size;
-
430  effect_value = ref.effect_value;
-
431  buffer.resize(size);
-
432  buffer.setIncrement(effect_value);
-
433  };
-
434 
-
435  float value() { return effect_value; }
-
436 
-
437  void setValue(float value) {
-
438  effect_value = value;
-
439  buffer.setIncrement(value);
-
440  }
-
441 
-
442  effect_t process(effect_t input) {
-
443  if (!active())
-
444  return input;
-
445  buffer.write(input);
-
446  return buffer.read();
-
447  }
-
448 
-
449  PitchShift *clone() { return new PitchShift(*this); }
-
450 
-
451 protected:
-
452  VariableSpeedRingBuffer<int16_t> buffer;
-
453  float effect_value;
-
454  int size;
-
455 };
-
456 } // namespace audio_tools
-
audio_tools::ADSRGain
ADSR Envelope: Attack, Decay, Sustain and Release. Attack is the time taken for initial run-up oeffec...
Definition: AudioEffect.h:361
-
audio_tools::ADSRGain::process
effect_t process(effect_t input)
calculates the effect output from the input
Definition: AudioEffect.h:397
+
5 #include "AudioTools/AudioTypes.h"
+
6 #include <stdint.h>
+
7 
+
8 namespace audio_tools {
+
9 
+
10 // we use int16_t for our effects
+
11 typedef int16_t effect_t;
+
12 
+
20 class AudioEffect {
+
21 public:
+
22  AudioEffect() = default;
+
23  virtual ~AudioEffect() = default;
+
24 
+
26  virtual effect_t process(effect_t in) = 0;
+
27 
+
29  virtual void setActive(bool value) { active_flag = value; }
+
30 
+
32  virtual bool active() { return active_flag; }
+
33 
+
34  virtual AudioEffect *clone() = 0;
+
35 
+
37  int id() { return id_value; }
+
38 
+
40  void setId(int id) { this->id_value = id; }
+
41 
+
42 protected:
+
43  bool active_flag = true;
+
44  int id_value = -1;
+
45 
+
46  void copyParent(AudioEffect *copy) {
+
47  id_value = copy->id_value;
+
48  active_flag = copy->active_flag;
+
49  }
+
50 
+
52  int16_t clip(int32_t in, int16_t clipLimit = 32767,
+
53  int16_t resultLimit = 32767) {
+
54  int32_t result = in;
+
55  if (result > clipLimit) {
+
56  result = resultLimit;
+
57  }
+
58  if (result < -clipLimit) {
+
59  result = -resultLimit;
+
60  }
+
61  return result;
+
62  }
+
63 };
+
64 
+
73 class Boost : public AudioEffect {
+
74 public:
+
77  Boost(float volume = 1.0) { effect_value = volume; }
+
78 
+
79  Boost(const Boost &copy) = default;
+
80 
+
81  float volume() { return effect_value; }
+
82 
+
83  void setVolume(float volume) { effect_value = volume; }
+
84 
+
85  effect_t process(effect_t input) {
+
86  if (!active())
+
87  return input;
+
88  int32_t result = effect_value * input;
+
89  // clip to int16_t
+
90  return clip(result);
+
91  }
+
92 
+
93  Boost *clone() { return new Boost(*this); }
+
94 
+
95 protected:
+
96  float effect_value;
+
97 };
+
98 
+
106 class Distortion : public AudioEffect {
+
107 public:
+
109  Distortion(int16_t clipThreashold = 4990, int16_t maxInput = 6500) {
+
110  p_clip_threashold = clipThreashold;
+
111  max_input = maxInput;
+
112  }
+
113 
+
114  Distortion(const Distortion &copy) = default;
+
115 
+
116  void setClipThreashold(int16_t th) { p_clip_threashold = th; }
+
117 
+
118  int16_t clipThreashold() { return p_clip_threashold; }
+
119 
+
120  void setMaxInput(int16_t maxInput) { max_input = maxInput; }
+
121 
+
122  int16_t maxInput() { return max_input; }
+
123 
+
124  effect_t process(effect_t input) {
+
125  if (!active())
+
126  return input;
+
127  // the input signal is 16bits (values from -32768 to +32768
+
128  // the value of input is clipped to the distortion_threshold value
+
129  return clip(input, p_clip_threashold, max_input);
+
130  }
+
131 
+
132  Distortion *clone() { return new Distortion(*this); }
+
133 
+
134 protected:
+
135  int16_t p_clip_threashold;
+
136  int16_t max_input;
+
137 };
+
138 
+
146 class Fuzz : public AudioEffect {
+
147 public:
+
149  Fuzz(float fuzzEffectValue = 6.5, uint16_t maxOut = 300) {
+
150  p_effect_value = fuzzEffectValue;
+
151  max_out = maxOut;
+
152  }
+
153 
+
154  Fuzz(const Fuzz &copy) = default;
+
155 
+
156  void setFuzzEffectValue(float v) { p_effect_value = v; }
+
157 
+
158  float fuzzEffectValue() { return p_effect_value; }
+
159 
+
160  void setMaxOut(uint16_t v) { max_out = v; }
+
161 
+
162  uint16_t maxOut() { return max_out; }
+
163 
+
164  effect_t process(effect_t input) {
+
165  if (!active())
+
166  return input;
+
167  float v = p_effect_value;
+
168  int32_t result = clip(v * input);
+
169  return map(result * v, -32768, +32767, -max_out, max_out);
+
170  }
+
171 
+
172  Fuzz *clone() { return new Fuzz(*this); }
+
173 
+
174 protected:
+
175  float p_effect_value;
+
176  uint16_t max_out;
+
177 };
+
178 
+
186 class Tremolo : public AudioEffect {
+
187 public:
+
190  Tremolo(int16_t duration_ms = 2000, uint8_t depthPercent = 50,
+
191  uint32_t sampleRate = 44100) {
+
192  this->duration_ms = duration_ms;
+
193  this->sampleRate = sampleRate;
+
194  this->p_percent = depthPercent;
+
195  int32_t rate_count = sampleRate * duration_ms / 1000;
+
196  rate_count_half = rate_count / 2;
+
197  }
+
198 
+
199  Tremolo(const Tremolo &copy) = default;
+
200 
+
201  void setDuration(int16_t ms) {
+
202  int32_t rate_count = sampleRate * ms / 1000;
+
203  rate_count_half = rate_count / 2;
+
204  }
+
205 
+
206  int16_t duration() { return duration_ms; }
+
207 
+
208  void setDepth(uint8_t percent) { p_percent = percent; }
+
209 
+
210  uint8_t depth() { return p_percent; }
+
211 
+
212  effect_t process(effect_t input) {
+
213  if (!active())
+
214  return input;
+
215 
+
216  // limit value to max 100% and calculate factors
+
217  float tremolo_depth = p_percent > 100 ? 1.0 : 0.01 * p_percent;
+
218  float signal_depth = (100.0 - p_percent) / 100.0;
+
219 
+
220  float tremolo_factor = tremolo_depth / rate_count_half;
+
221  int32_t out = (signal_depth * input) + (tremolo_factor * count * input);
+
222 
+
223  // saw tooth shaped counter
+
224  count += inc;
+
225  if (count >= rate_count_half) {
+
226  inc = -1;
+
227  } else if (count <= 0) {
+
228  inc = +1;
+
229  }
+
230 
+
231  return clip(out);
+
232  }
+
233 
+
234  Tremolo *clone() { return new Tremolo(*this); }
+
235 
+
236 protected:
+
237  int16_t duration_ms;
+
238  uint32_t sampleRate;
+
239  int32_t count = 0;
+
240  int16_t inc = 1;
+
241  int32_t rate_count_half; // number of samples for on raise and fall
+
242  uint8_t p_percent;
+
243 };
+
244 
+
253 class Delay : public AudioEffect {
+
254 public:
+
256  Delay(uint16_t duration_ms = 1000, float depth = 0.5,
+
257  float feedbackAmount = 1.0, uint32_t sampleRate = 44100,
+
258  bool zeroIfBufferEmpty = false) {
+
259  setSampleRate(sampleRate);
+
260  setFeedback(feedbackAmount);
+
261  setDepth(depth);
+
262  setDuration(duration_ms);
+
263  }
+
264 
+
265  Delay(const Delay &copy) {
+
266  setSampleRate(copy.sampleRate);
+
267  setFeedback(copy.feedback);
+
268  setDepth(copy.depth);
+
269  setDuration(copy.duration);
+
270  };
+
271 
+
272  void setDuration(int16_t dur) {
+
273  duration = dur;
+
274  updateBufferSize();
+
275  }
+
276 
+
277  int16_t getDuration() { return duration; }
+
278 
+
279  void setDepth(float value) {
+
280  depth = value;
+
281  if (depth > 1.0)
+
282  depth = 1.0;
+
283  if (depth < 0)
+
284  depth = 0.0;
+
285  }
+
286 
+
287  float getDepth() { return depth; }
+
288 
+
289  void setFeedback(float feed) {
+
290  feedback = feed;
+
291  if (feedback > 1.0)
+
292  feedback = 1.0;
+
293  if (feedback < 0)
+
294  feedback = 0.0;
+
295  }
+
296 
+
297  float getFeedback() { return feedback; }
+
298 
+
299  void setSampleRate(int32_t sample) {
+
300  sampleRate = sample;
+
301  updateBufferSize();
+
302  }
+
303 
+
304  float getSampleRate() { return sampleRate; }
+
305 
+
306  effect_t process(effect_t input) {
+
307  if (!active())
+
308  return input;
+
309 
+
310  // Read last audio sample in each delay line
+
311  int32_t delayed_value = buffer[delay_line_index];
+
312 
+
313  // Mix the above with current audio and write the results back to output
+
314  int32_t out = ((1.0 - depth) * input) + (depth * delayed_value);
+
315 
+
316  // Update each delay line
+
317  buffer[delay_line_index] = clip(feedback * (delayed_value + input));
+
318 
+
319  // Finally, update the delay line index
+
320  if (delay_line_index++ >= delay_len_samples) {
+
321  delay_line_index = 0;
+
322  }
+
323  return clip(out);
+
324  }
+
325 
+
326  Delay *clone() { return new Delay(*this); }
+
327 
+
328 protected:
+
329  Vector<effect_t> buffer{0};
+
330  float feedback = 0.0, duration = 0.0, sampleRate = 0.0, depth = 0.0;
+
331  size_t delay_len_samples = 0;
+
332  size_t delay_line_index = 0;
+
333 
+
334  void updateBufferSize() {
+
335  if (sampleRate > 0 && duration > 0) {
+
336  size_t newSampleCount = sampleRate * duration / 1000;
+
337  if (newSampleCount != delay_len_samples) {
+
338  delay_len_samples = newSampleCount;
+
339  buffer.resize(delay_len_samples);
+
340  memset(buffer.data(),0,delay_len_samples*sizeof(effect_t));
+
341  LOGD("sample_count: %u", (unsigned)delay_len_samples);
+
342  }
+
343  }
+
344  }
+
345 };
+
346 
+
362 class ADSRGain : public AudioEffect {
+
363 public:
+
364  ADSRGain(float attack = 0.001, float decay = 0.001, float sustainLevel = 0.5,
+
365  float release = 0.005, float boostFactor = 1.0) {
+
366  this->factor = boostFactor;
+
367  adsr = new ADSR(attack, decay, sustainLevel, release);
+
368  }
+
369 
+
370  ADSRGain(const ADSRGain &ref) {
+
371  adsr = new ADSR(*(ref.adsr));
+
372  factor = ref.factor;
+
373  copyParent((AudioEffect *)&ref);
+
374  };
+
375 
+
376  virtual ~ADSRGain() { delete adsr; }
+
377 
+
378  void setAttackRate(float a) { adsr->setAttackRate(a); }
+
379 
+
380  float attackRate() { return adsr->attackRate(); }
+
381 
+
382  void setDecayRate(float d) { adsr->setDecayRate(d); }
+
383 
+
384  float decayRate() { return adsr->decayRate(); }
+
385 
+
386  void setSustainLevel(float s) { adsr->setSustainLevel(s); }
+
387 
+
388  float sustainLevel() { return adsr->sustainLevel(); }
+
389 
+
390  void setReleaseRate(float r) { adsr->setReleaseRate(r); }
+
391 
+
392  float releaseRate() { return adsr->releaseRate(); }
+
393 
+
394  void keyOn(float tgt = 0) { adsr->keyOn(tgt); }
+
395 
+
396  void keyOff() { adsr->keyOff(); }
+
397 
+
398  effect_t process(effect_t input) {
+
399  effect_t result = factor * adsr->tick() * input;
+
400  return result;
+
401  }
+
402 
+
403  bool isActive() { return adsr->isActive(); }
+
404 
+
405  ADSRGain *clone() { return new ADSRGain(*this); }
+
406 
+
407 protected:
+
408  ADSR *adsr;
+
409  float factor;
+
410 };
+
411 
+
418 class PitchShift : public AudioEffect {
+
419 public:
+
422  PitchShift(float shift_value = 1.0, int buffer_size = 1000) {
+
423  effect_value = shift_value;
+
424  size = buffer_size;
+
425  buffer.resize(buffer_size);
+
426  buffer.setIncrement(shift_value);
+
427  }
+
428 
+
429  PitchShift(const PitchShift &ref) {
+
430  size = ref.size;
+
431  effect_value = ref.effect_value;
+
432  buffer.resize(size);
+
433  buffer.setIncrement(effect_value);
+
434  };
+
435 
+
436  float value() { return effect_value; }
+
437 
+
438  void setValue(float value) {
+
439  effect_value = value;
+
440  buffer.setIncrement(value);
+
441  }
+
442 
+
443  effect_t process(effect_t input) {
+
444  if (!active())
+
445  return input;
+
446  buffer.write(input);
+
447  return buffer.read();
+
448  }
+
449 
+
450  PitchShift *clone() { return new PitchShift(*this); }
+
451 
+
452 protected:
+
453  VariableSpeedRingBuffer<int16_t> buffer;
+
454  float effect_value;
+
455  int size;
+
456 };
+
457 
+
458 
+
466 class Compressor : public AudioEffect {
+
467 
+
468  Compressor(const Compressor &copy) = default;
+
469 
+
470  Compressor(uint32_t sampleRate = 44100, int32_t attackMs=30, int32_t releaseMs=20, int32_t holdMs=10, uint8_t thresholdPercent=10, float compressionRatio=0.5){
+
471  //assuming 1 sample = 1/96kHz = ~10us
+
472  //Attack -> 30 ms -> 3000
+
473  //Release -> 20 ms -> 2000
+
474  //Hold -> 10ms -> 1000
+
475  sample_rate = sample_rate * attackMs / 1000;
+
476  attack_count = sample_rate * attackMs / 1000;
+
477  release_count = sample_rate * releaseMs / 1000;
+
478  hold_count = sample_rate * holdMs / 1000;
+
479 
+
480  //threshold -20dB below limit -> 0.1 * 2^31
+
481  threshold = 0.01f * thresholdPercent * NumberConverter::maxValueT<effect_t>();
+
482  //compression ratio: 6:1 -> -6dB = 0.5
+
483  gainreduce = compressionRatio;
+
484  //initial gain = 1.0 -> no compression
+
485  gain = 1.0f;
+
486  recalculate();
+
487  }
+
488 
+
489  Compressor *clone() { return new Compressor(*this); }
+
490 
+
491  void setAttack(int32_t attackMs){
+
492  attack_count = sample_rate * attackMs / 1000;
+
493  recalculate();
+
494  }
+
495 
+
496  void setRelease(int32_t releaseMs){
+
497  release_count = sample_rate * releaseMs / 1000;
+
498  recalculate();
+
499  }
+
500 
+
501  void setHold(int32_t holdMs){
+
502  hold_count = sample_rate * holdMs / 1000;
+
503  recalculate();
+
504  }
+
505 
+
506  void setThresholdPercent(uint8_t thresholdPercent){
+
507  threshold = 0.01f * thresholdPercent * NumberConverter::maxValueT<effect_t>();
+
508  }
+
509 
+
510  void setCompressionRatio(float compressionRatio){
+
511  if (compressionRatio<1.0){
+
512  gainreduce = compressionRatio;
+
513  }
+
514  recalculate();
+
515  }
+
516 
+
517  effect_t process(effect_t inSample) {
+
518  float inSampleF = (float)inSample;
+
519 
+
520  if (fabs(inSampleF) > threshold) {
+
521  if (gain >= gainreduce) {
+
522  if (State==S_NoOperation) {
+
523  State=S_Attack;
+
524  timeout = attack_count;
+
525  }
+
526  else if (State==S_Release) {
+
527  State=S_Attack;
+
528  timeout = attack_count;
+
529  }
+
530  }
+
531  if (State==S_GainReduction) timeout = hold_count;
+
532 
+
533  }
+
534 
+
535  if (fabs(inSampleF) < threshold && gain <= 1.0f) {
+
536  if ( timeout==0 && State==S_GainReduction) {
+
537  State=S_Release;
+
538  timeout = release_count;
+
539  }
+
540  }
+
541 
+
542  switch (State) {
+
543  case S_Attack:
+
544  if ( timeout>0 && gain > gainreduce) {
+
545  gain -= gain_step_attack;
+
546  timeout--;
+
547  }
+
548  else {
+
549  State=S_GainReduction;
+
550  timeout = hold_count;
+
551  }
+
552  break;
+
553 
+
554 
+
555  case S_GainReduction:
+
556  if ( timeout>0) timeout--;
+
557  else {
+
558  State=S_Release;
+
559  timeout = release_count;
+
560  }
+
561  break;
+
562 
+
563 
+
564  case S_Release:
+
565  if ( timeout>0 && gain<1.0f) {
+
566  timeout--;
+
567  gain += gain_step_release;
+
568  }
+
569  else {
+
570  State=S_NoOperation;
+
571  }
+
572  break;
+
573 
+
574  case S_NoOperation:
+
575  if (gain < 1.0f) gain = 1.0F;
+
576  break;
+
577 
+
578  default:
+
579 
+
580  break;
+
581 
+
582  }
+
583 
+
584  float outSampleF = inSample*gain;
+
585 
+
586  return (int) outSampleF;
+
587  }
+
588 
+
589 protected:
+
590  enum CompStates {S_NoOperation, S_Attack, S_GainReduction, S_Release };
+
591  enum CompStates State = S_NoOperation;
+
592 
+
593  int32_t attack_count, release_count, hold_count, timeout;
+
594  float gainreduce, gain_step_attack, gain_step_release, gain, threshold;
+
595  uint32_t sample_rate;
+
596 
+
597  void recalculate() {
+
598  gain_step_attack = (1.0f - gainreduce) / attack_count;
+
599  gain_step_release = (1.0f - gainreduce) / release_count;
+
600  }
+
601 
+
602 };
+
603 
+
604 
+
605 } // namespace audio_tools
+
audio_tools::ADSRGain
ADSR Envelope: Attack, Decay, Sustain and Release. Attack is the time taken for initial run-up oeffec...
Definition: AudioEffect.h:362
+
audio_tools::ADSRGain::process
effect_t process(effect_t input)
calculates the effect output from the input
Definition: AudioEffect.h:398
audio_tools::ADSR
Generates ADSR values between 0.0 and 1.0.
Definition: AudioParameters.h:51
-
audio_tools::AudioEffect
Abstract Base class for Sound Effects.
Definition: AudioEffect.h:19
-
audio_tools::AudioEffect::active
virtual bool active()
determines if the effect is active
Definition: AudioEffect.h:31
-
audio_tools::AudioEffect::setActive
virtual void setActive(bool value)
sets the effect active/inactive
Definition: AudioEffect.h:28
-
audio_tools::AudioEffect::setId
void setId(int id)
Allows to identify an effect.
Definition: AudioEffect.h:39
-
audio_tools::AudioEffect::id
int id()
Allows to identify an effect.
Definition: AudioEffect.h:36
+
audio_tools::AudioEffect
Abstract Base class for Sound Effects.
Definition: AudioEffect.h:20
+
audio_tools::AudioEffect::active
virtual bool active()
determines if the effect is active
Definition: AudioEffect.h:32
+
audio_tools::AudioEffect::setActive
virtual void setActive(bool value)
sets the effect active/inactive
Definition: AudioEffect.h:29
+
audio_tools::AudioEffect::setId
void setId(int id)
Allows to identify an effect.
Definition: AudioEffect.h:40
+
audio_tools::AudioEffect::id
int id()
Allows to identify an effect.
Definition: AudioEffect.h:37
audio_tools::AudioEffect::process
virtual effect_t process(effect_t in)=0
calculates the effect output from the input
-
audio_tools::AudioEffect::clip
int16_t clip(int32_t in, int16_t clipLimit=32767, int16_t resultLimit=32767)
generic clipping method
Definition: AudioEffect.h:51
-
audio_tools::Boost
Boost AudioEffect.
Definition: AudioEffect.h:72
-
audio_tools::Boost::process
effect_t process(effect_t input)
calculates the effect output from the input
Definition: AudioEffect.h:84
-
audio_tools::Boost::Boost
Boost(float volume=1.0)
Definition: AudioEffect.h:76
-
audio_tools::Delay
Delay/Echo AudioEffect. See https://wiki.analog.com/resources/tools-software/sharc-audio-module/barem...
Definition: AudioEffect.h:252
-
audio_tools::Delay::Delay
Delay(uint16_t duration_ms=1000, float depth=0.5, float feedbackAmount=1.0, uint32_t sampleRate=44100, bool zeroIfBufferEmpty=false)
e.g. depth=0.5, ms=1000, sampleRate=44100
Definition: AudioEffect.h:255
-
audio_tools::Delay::process
effect_t process(effect_t input)
calculates the effect output from the input
Definition: AudioEffect.h:305
-
audio_tools::Distortion
Distortion AudioEffect.
Definition: AudioEffect.h:105
-
audio_tools::Distortion::Distortion
Distortion(int16_t clipThreashold=4990, int16_t maxInput=6500)
Distortion Constructor: e.g. use clipThreashold 4990 and maxInput=6500.
Definition: AudioEffect.h:108
-
audio_tools::Distortion::process
effect_t process(effect_t input)
calculates the effect output from the input
Definition: AudioEffect.h:123
-
audio_tools::Fuzz
Fuzz AudioEffect.
Definition: AudioEffect.h:145
-
audio_tools::Fuzz::process
effect_t process(effect_t input)
calculates the effect output from the input
Definition: AudioEffect.h:163
-
audio_tools::Fuzz::Fuzz
Fuzz(float fuzzEffectValue=6.5, uint16_t maxOut=300)
Fuzz Constructor: use e.g. effectValue=6.5; maxOut = 300.
Definition: AudioEffect.h:148
-
audio_tools::PitchShift
Shifts the pitch by the indicated step size: e.g. 2 doubles the pitch.
Definition: AudioEffect.h:417
-
audio_tools::PitchShift::process
effect_t process(effect_t input)
calculates the effect output from the input
Definition: AudioEffect.h:442
-
audio_tools::PitchShift::PitchShift
PitchShift(float shift_value=1.0, int buffer_size=1000)
Definition: AudioEffect.h:421
-
audio_tools::Tremolo
Tremolo AudioEffect.
Definition: AudioEffect.h:185
-
audio_tools::Tremolo::process
effect_t process(effect_t input)
calculates the effect output from the input
Definition: AudioEffect.h:211
-
audio_tools::Tremolo::Tremolo
Tremolo(int16_t duration_ms=2000, uint8_t depthPercent=50, uint32_t sampleRate=44100)
Definition: AudioEffect.h:189
+
audio_tools::AudioEffect::clip
int16_t clip(int32_t in, int16_t clipLimit=32767, int16_t resultLimit=32767)
generic clipping method
Definition: AudioEffect.h:52
+
audio_tools::Boost
Boost AudioEffect.
Definition: AudioEffect.h:73
+
audio_tools::Boost::process
effect_t process(effect_t input)
calculates the effect output from the input
Definition: AudioEffect.h:85
+
audio_tools::Boost::Boost
Boost(float volume=1.0)
Definition: AudioEffect.h:77
+
audio_tools::Compressor
Compressor inspired by https://github.com/YetAnotherElectronicsChannel/STM32_DSP_COMPRESSOR/blob/mast...
Definition: AudioEffect.h:466
+
audio_tools::Delay
Delay/Echo AudioEffect. See https://wiki.analog.com/resources/tools-software/sharc-audio-module/barem...
Definition: AudioEffect.h:253
+
audio_tools::Delay::Delay
Delay(uint16_t duration_ms=1000, float depth=0.5, float feedbackAmount=1.0, uint32_t sampleRate=44100, bool zeroIfBufferEmpty=false)
e.g. depth=0.5, ms=1000, sampleRate=44100
Definition: AudioEffect.h:256
+
audio_tools::Delay::process
effect_t process(effect_t input)
calculates the effect output from the input
Definition: AudioEffect.h:306
+
audio_tools::Distortion
Distortion AudioEffect.
Definition: AudioEffect.h:106
+
audio_tools::Distortion::Distortion
Distortion(int16_t clipThreashold=4990, int16_t maxInput=6500)
Distortion Constructor: e.g. use clipThreashold 4990 and maxInput=6500.
Definition: AudioEffect.h:109
+
audio_tools::Distortion::process
effect_t process(effect_t input)
calculates the effect output from the input
Definition: AudioEffect.h:124
+
audio_tools::Fuzz
Fuzz AudioEffect.
Definition: AudioEffect.h:146
+
audio_tools::Fuzz::process
effect_t process(effect_t input)
calculates the effect output from the input
Definition: AudioEffect.h:164
+
audio_tools::Fuzz::Fuzz
Fuzz(float fuzzEffectValue=6.5, uint16_t maxOut=300)
Fuzz Constructor: use e.g. effectValue=6.5; maxOut = 300.
Definition: AudioEffect.h:149
+
audio_tools::PitchShift
Shifts the pitch by the indicated step size: e.g. 2 doubles the pitch.
Definition: AudioEffect.h:418
+
audio_tools::PitchShift::process
effect_t process(effect_t input)
calculates the effect output from the input
Definition: AudioEffect.h:443
+
audio_tools::PitchShift::PitchShift
PitchShift(float shift_value=1.0, int buffer_size=1000)
Definition: AudioEffect.h:422
+
audio_tools::Tremolo
Tremolo AudioEffect.
Definition: AudioEffect.h:186
+
audio_tools::Tremolo::process
effect_t process(effect_t input)
calculates the effect output from the input
Definition: AudioEffect.h:212
+
audio_tools::Tremolo::Tremolo
Tremolo(int16_t duration_ms=2000, uint8_t depthPercent=50, uint32_t sampleRate=44100)
Definition: AudioEffect.h:190
audio_tools::VariableSpeedRingBuffer::read
T read()
reads a single value
Definition: PitchShift.h:238
audio_tools::VariableSpeedRingBuffer::write
bool write(T sample)
write add an entry to the buffer
Definition: PitchShift.h:255
audio_tools
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition: AnalogAudio.h:10
diff --git a/_audio_effects_8h_source.html b/_audio_effects_8h_source.html index 0f70258873..b119ea93b0 100644 --- a/_audio_effects_8h_source.html +++ b/_audio_effects_8h_source.html @@ -498,7 +498,7 @@
audio_tools::AudioEffectCommon::addEffect
void addEffect(AudioEffect &effect)
Adds an effect object (by reference)
Definition: AudioEffects.h:27
audio_tools::AudioEffectCommon::findEffect
AudioEffect * findEffect(int id)
Finds an effect by id.
Definition: AudioEffects.h:50
audio_tools::AudioEffectCommon::clear
void clear()
deletes all defined effects
Definition: AudioEffects.h:39
-
audio_tools::AudioEffect
Abstract Base class for Sound Effects.
Definition: AudioEffect.h:19
+
audio_tools::AudioEffect
Abstract Base class for Sound Effects.
Definition: AudioEffect.h:20
audio_tools::AudioEffectStream
EffectsStream supporting variable bits_per_sample. This class is only available when __cplusplus >= 2...
Definition: AudioEffects.h:395
audio_tools::AudioEffectStreamT
EffectsStreamT: the template class describes an input or output stream to which one or multiple effec...
Definition: AudioEffects.h:208
audio_tools::AudioEffectStreamT::size
size_t size()
Provides the actual number of defined effects.
Definition: AudioEffects.h:363
diff --git a/_audio_effects_suite_8h_source.html b/_audio_effects_suite_8h_source.html index c9ce67b86c..a5aa2a7c5d 100644 --- a/_audio_effects_suite_8h_source.html +++ b/_audio_effects_suite_8h_source.html @@ -1191,7 +1191,7 @@
1586 };
1587 
1588 } // namespace effectsuite_tools
-
audio_tools::AudioEffect
Abstract Base class for Sound Effects.
Definition: AudioEffect.h:19
+
audio_tools::AudioEffect
Abstract Base class for Sound Effects.
Definition: AudioEffect.h:20
audio_tools::DelayEffectBase
A Base class for delay based digital effects. Provides the basic methods that are shared amongst Flan...
Definition: AudioEffectsSuite.h:396
audio_tools::DelayEffectBase::setDelayBuffReadIndex
void setDelayBuffReadIndex(effectsuite_t index)
Definition: AudioEffectsSuite.h:559
audio_tools::DelayEffectBase::~DelayEffectBase
~DelayEffectBase()
Definition: AudioEffectsSuite.h:412
diff --git a/_audio_f_e_c_8h_source.html b/_audio_f_e_c_8h_source.html index e86f152e0e..9bb88232b7 100644 --- a/_audio_f_e_c_8h_source.html +++ b/_audio_f_e_c_8h_source.html @@ -72,6 +72,7 @@
1 #pragma once
2 // Forward Error Corrections
3 #include "AudioFEC/FECReedSolomon.h"
+
4 #include "AudioFEC/FECHamming.h"