2 #include "AudioEffects/AudioParameters.h"
3 #include "AudioEffects/PitchShift.h"
4 #include "AudioTools/AudioLogger.h"
5 #include "AudioTools/AudioTypes.h"
11 typedef int16_t effect_t;
26 virtual effect_t
process(effect_t in) = 0;
29 virtual void setActive(
bool value) { active_flag = value; }
32 virtual bool active() {
return active_flag; }
37 int id() {
return id_value; }
40 void setId(
int id) { this->id_value =
id; }
43 bool active_flag =
true;
47 id_value = copy->id_value;
48 active_flag = copy->active_flag;
52 int16_t
clip(int32_t in, int16_t clipLimit = 32767,
53 int16_t resultLimit = 32767) {
55 if (result > clipLimit) {
58 if (result < -clipLimit) {
59 result = -resultLimit;
84 int32_t result =
volume() * input;
103 Distortion(int16_t clipThreashold = 4990, int16_t maxInput = 6500) {
104 p_clip_threashold = clipThreashold;
105 max_input = maxInput;
110 void setClipThreashold(int16_t th) { p_clip_threashold = th; }
112 int16_t clipThreashold() {
return p_clip_threashold; }
114 void setMaxInput(int16_t maxInput) { max_input = maxInput; }
116 int16_t maxInput() {
return max_input; }
123 return clip(input, p_clip_threashold, max_input);
129 int16_t p_clip_threashold;
143 Fuzz(
float fuzzEffectValue = 6.5, uint16_t maxOut = 300) {
144 p_effect_value = fuzzEffectValue;
150 void setFuzzEffectValue(
float v) { p_effect_value = v; }
152 float fuzzEffectValue() {
return p_effect_value; }
154 void setMaxOut(uint16_t v) { max_out = v; }
156 uint16_t maxOut() {
return max_out; }
161 float v = p_effect_value;
162 int32_t result =
clip(v * input);
163 return map(result * v, -32768, +32767, -max_out, max_out);
166 Fuzz *clone() {
return new Fuzz(*
this); }
169 float p_effect_value;
184 Tremolo(int16_t duration_ms = 2000, uint8_t depthPercent = 50,
185 uint32_t sampleRate = 44100) {
186 this->duration_ms = duration_ms;
187 this->sampleRate = sampleRate;
188 this->p_percent = depthPercent;
189 int32_t rate_count = sampleRate * duration_ms / 1000;
190 rate_count_half = rate_count / 2;
195 void setDuration(int16_t ms) {
196 this->duration_ms = ms;
197 int32_t rate_count = sampleRate * ms / 1000;
198 rate_count_half = rate_count / 2;
201 int16_t duration() {
return duration_ms; }
203 void setDepth(uint8_t percent) { p_percent = percent; }
205 uint8_t depth() {
return p_percent; }
212 float tremolo_depth = p_percent > 100 ? 1.0 : 0.01 * p_percent;
213 float signal_depth = (100.0 - p_percent) / 100.0;
215 float tremolo_factor = tremolo_depth / rate_count_half;
216 int32_t out = (signal_depth * input) + (tremolo_factor * count * input);
220 if (count >= rate_count_half) {
222 }
else if (count <= 0) {
236 int32_t rate_count_half;
251 Delay(uint16_t duration_ms = 1000,
float depth = 0.5,
252 float feedbackAmount = 1.0, uint32_t sampleRate = 44100) {
253 setSampleRate(sampleRate);
254 setFeedback(feedbackAmount);
256 setDuration(duration_ms);
260 setSampleRate(copy.sampleRate);
261 setFeedback(copy.feedback);
262 setDepth(copy.depth);
263 setDuration(copy.duration);
266 void setDuration(int16_t dur) {
271 int16_t getDuration() {
return duration; }
273 void setDepth(
float value) {
281 float getDepth() {
return depth; }
283 void setFeedback(
float feed) {
291 float getFeedback() {
return feedback; }
293 void setSampleRate(int32_t sample) {
298 float getSampleRate() {
return sampleRate; }
305 int32_t delayed_value = buffer[delay_line_index];
308 int32_t out = ((1.0 - depth) * input) + (depth * delayed_value);
311 buffer[delay_line_index] =
clip(feedback * (delayed_value + input));
314 if (delay_line_index++ >= delay_len_samples) {
315 delay_line_index = 0;
323 Vector<effect_t> buffer{0};
324 float feedback = 0.0, duration = 0.0, sampleRate = 0.0, depth = 0.0;
325 size_t delay_len_samples = 0;
326 size_t delay_line_index = 0;
328 void updateBufferSize() {
329 if (sampleRate > 0 && duration > 0) {
330 size_t newSampleCount = sampleRate * duration / 1000;
331 if (newSampleCount != delay_len_samples) {
332 delay_len_samples = newSampleCount;
333 buffer.resize(delay_len_samples);
334 memset(buffer.data(),0,delay_len_samples*
sizeof(effect_t));
335 LOGD(
"sample_count: %u", (
unsigned)delay_len_samples);
358 ADSRGain(
float attack = 0.001,
float decay = 0.001,
float sustainLevel = 0.5,
359 float release = 0.005,
float boostFactor = 1.0) {
360 this->factor = boostFactor;
361 adsr =
new ADSR(attack, decay, sustainLevel, release);
365 adsr =
new ADSR(*(ref.adsr));
370 virtual ~
ADSRGain() {
delete adsr; }
372 void setAttackRate(
float a) { adsr->setAttackRate(a); }
374 float attackRate() {
return adsr->attackRate(); }
376 void setDecayRate(
float d) { adsr->setDecayRate(d); }
378 float decayRate() {
return adsr->decayRate(); }
380 void setSustainLevel(
float s) { adsr->setSustainLevel(s); }
382 float sustainLevel() {
return adsr->sustainLevel(); }
384 void setReleaseRate(
float r) { adsr->setReleaseRate(r); }
386 float releaseRate() {
return adsr->releaseRate(); }
388 void keyOn(
float tgt = 0) { adsr->keyOn(tgt); }
390 void keyOff() { adsr->keyOff(); }
395 effect_t result = factor * adsr->tick() * input;
399 bool isActive() {
return adsr->isActive(); }
401 ADSRGain *clone() {
return new ADSRGain(*
this); }
418 PitchShift(
float shift_value = 1.0,
int buffer_size = 1000) {
419 effect_value = shift_value;
421 buffer.resize(buffer_size);
422 buffer.setIncrement(shift_value);
427 effect_value = ref.effect_value;
429 buffer.setIncrement(effect_value);
432 float value() {
return effect_value; }
434 void setValue(
float value) {
435 effect_value = value;
436 buffer.setIncrement(value);
443 return buffer.
read();
449 VariableSpeedRingBuffer<int16_t> buffer;
468 Compressor(uint32_t sampleRate = 44100, uint16_t attackMs=30, uint16_t releaseMs=20, uint16_t holdMs=10, uint8_t thresholdPercent=10,
float compressionRatio=0.5){
473 sample_rate = sample_rate * attackMs / 1000;
474 attack_count = sample_rate * attackMs / 1000;
475 release_count = sample_rate * releaseMs / 1000;
476 hold_count = sample_rate * holdMs / 1000;
479 threshold = 0.01f * thresholdPercent * NumberConverter::maxValueT<effect_t>();
481 gainreduce = compressionRatio;
489 attack_count = sample_rate * attackMs / 1000;
495 release_count = sample_rate * releaseMs / 1000;
501 hold_count = sample_rate * holdMs / 1000;
507 threshold = 0.01f * thresholdPercent * NumberConverter::maxValueT<effect_t>();
512 if (compressionRatio<1.0){
513 gainreduce = compressionRatio;
522 return compress(input);
528 enum CompStates {S_NoOperation, S_Attack, S_GainReduction, S_Release };
529 enum CompStates state = S_NoOperation;
531 int32_t attack_count, release_count, hold_count, timeout;
532 float gainreduce, gain_step_attack, gain_step_release, gain, threshold;
533 uint32_t sample_rate;
536 gain_step_attack = (1.0f - gainreduce) / attack_count;
537 gain_step_release = (1.0f - gainreduce) / release_count;
540 float compress(
float inSampleF){
541 if (fabs(inSampleF) > threshold) {
542 if (gain >= gainreduce) {
543 if (state==S_NoOperation) {
545 timeout = attack_count;
547 else if (state==S_Release) {
549 timeout = attack_count;
552 if (state==S_GainReduction) timeout = hold_count;
556 if (fabs(inSampleF) < threshold && gain <= 1.0f) {
557 if ( timeout==0 && state==S_GainReduction) {
559 timeout = release_count;
565 if ( timeout>0 && gain > gainreduce) {
566 gain -= gain_step_attack;
570 state=S_GainReduction;
571 timeout = hold_count;
576 case S_GainReduction:
577 if ( timeout>0) timeout--;
580 timeout = release_count;
586 if ( timeout>0 && gain<1.0f) {
588 gain += gain_step_release;
596 if (gain < 1.0f) gain = 1.0f;
604 float outSampleF = gain * inSampleF;