2 #include "AudioParameters.h"
3 #include "PitchShift.h"
4 #include "AudioLogger.h"
5 #include "AudioTools/CoreAudio/AudioTypes.h"
6 #include "AudioTools/CoreAudio/AudioOutput.h"
12 typedef int16_t effect_t;
27 virtual effect_t
process(effect_t in) = 0;
30 virtual void setActive(
bool value) { active_flag = value; }
33 virtual bool active() {
return active_flag; }
38 int id() {
return id_value; }
41 void setId(
int id) { this->id_value =
id; }
44 bool active_flag =
true;
48 id_value = copy->id_value;
49 active_flag = copy->active_flag;
53 int16_t
clip(int32_t in, int16_t clipLimit = 32767,
54 int16_t resultLimit = 32767) {
56 if (result > clipLimit) {
59 if (result < -clipLimit) {
60 result = -resultLimit;
85 int32_t result =
volume() * input;
104 Distortion(int16_t clipThreashold = 4990, int16_t maxInput = 6500) {
105 p_clip_threashold = clipThreashold;
106 max_input = maxInput;
111 void setClipThreashold(int16_t th) { p_clip_threashold = th; }
113 int16_t clipThreashold() {
return p_clip_threashold; }
115 void setMaxInput(int16_t maxInput) { max_input = maxInput; }
117 int16_t maxInput() {
return max_input; }
124 return clip(input, p_clip_threashold, max_input);
130 int16_t p_clip_threashold;
144 Fuzz(
float fuzzEffectValue = 6.5, uint16_t maxOut = 300) {
145 p_effect_value = fuzzEffectValue;
151 void setFuzzEffectValue(
float v) { p_effect_value = v; }
153 float fuzzEffectValue() {
return p_effect_value; }
155 void setMaxOut(uint16_t v) { max_out = v; }
157 uint16_t maxOut() {
return max_out; }
162 float v = p_effect_value;
163 int32_t result =
clip(v * input);
164 return map(result * v, -32768, +32767, -max_out, max_out);
167 Fuzz *clone() {
return new Fuzz(*
this); }
170 float p_effect_value;
185 Tremolo(int16_t duration_ms = 2000, uint8_t depthPercent = 50,
186 uint32_t sampleRate = 44100) {
187 this->duration_ms = duration_ms;
188 this->sampleRate = sampleRate;
189 this->p_percent = depthPercent;
190 int32_t rate_count = sampleRate * duration_ms / 1000;
191 rate_count_half = rate_count / 2;
196 void setDuration(int16_t ms) {
197 this->duration_ms = ms;
198 int32_t rate_count = sampleRate * ms / 1000;
199 rate_count_half = rate_count / 2;
202 int16_t duration() {
return duration_ms; }
204 void setDepth(uint8_t percent) { p_percent = percent; }
206 uint8_t depth() {
return p_percent; }
213 float tremolo_depth = p_percent > 100 ? 1.0 : 0.01 * p_percent;
214 float signal_depth = (100.0 - p_percent) / 100.0;
216 float tremolo_factor = tremolo_depth / rate_count_half;
217 int32_t out = (signal_depth * input) + (tremolo_factor * count * input);
221 if (count >= rate_count_half) {
223 }
else if (count <= 0) {
237 int32_t rate_count_half;
252 Delay(uint16_t duration_ms = 1000,
float depth = 0.5,
253 float feedbackAmount = 1.0, uint32_t sampleRate = 44100) {
254 setSampleRate(sampleRate);
255 setFeedback(feedbackAmount);
257 setDuration(duration_ms);
261 setSampleRate(copy.sampleRate);
262 setFeedback(copy.feedback);
263 setDepth(copy.depth);
264 setDuration(copy.duration);
267 void setDuration(int16_t dur) {
272 int16_t getDuration() {
return duration; }
274 void setDepth(
float value) {
282 float getDepth() {
return depth; }
284 void setFeedback(
float feed) {
292 float getFeedback() {
return feedback; }
294 void setSampleRate(int32_t sample) {
299 float getSampleRate() {
return sampleRate; }
306 int32_t delayed_value = buffer[delay_line_index];
309 int32_t out = ((1.0f - depth) * input) + (depth * delayed_value);
312 buffer[delay_line_index] =
clip(feedback * (delayed_value + input));
315 if (delay_line_index++ >= delay_len_samples) {
316 delay_line_index = 0;
324 Vector<effect_t> buffer{0};
325 float feedback = 0.0f, duration = 0.0f, sampleRate = 0.0f, depth = 0.0f;
326 size_t delay_len_samples = 0;
327 size_t delay_line_index = 0;
329 void updateBufferSize() {
330 if (sampleRate > 0 && duration > 0) {
331 size_t newSampleCount = sampleRate * duration / 1000;
332 if (newSampleCount != delay_len_samples) {
333 delay_len_samples = newSampleCount;
334 buffer.resize(delay_len_samples);
335 memset(buffer.data(),0,delay_len_samples*
sizeof(effect_t));
336 LOGD(
"sample_count: %u", (
unsigned)delay_len_samples);
359 ADSRGain(
float attack = 0.001,
float decay = 0.001,
float sustainLevel = 0.5,
360 float release = 0.005,
float boostFactor = 1.0) {
361 this->factor = boostFactor;
362 adsr =
new ADSR(attack, decay, sustainLevel, release);
366 adsr =
new ADSR(*(ref.adsr));
371 virtual ~
ADSRGain() {
delete adsr; }
373 void setAttackRate(
float a) { adsr->setAttackRate(a); }
375 float attackRate() {
return adsr->attackRate(); }
377 void setDecayRate(
float d) { adsr->setDecayRate(d); }
379 float decayRate() {
return adsr->decayRate(); }
381 void setSustainLevel(
float s) { adsr->setSustainLevel(s); }
383 float sustainLevel() {
return adsr->sustainLevel(); }
385 void setReleaseRate(
float r) { adsr->setReleaseRate(r); }
387 float releaseRate() {
return adsr->releaseRate(); }
389 void keyOn(
float tgt = 0) { adsr->keyOn(tgt); }
391 void keyOff() { adsr->keyOff(); }
396 effect_t result = factor * adsr->tick() * input;
400 bool isActive() {
return adsr->isActive(); }
402 ADSRGain *clone() {
return new ADSRGain(*
this); }
419 PitchShift(
float shift_value = 1.0,
int buffer_size = 1000) {
420 effect_value = shift_value;
422 buffer.resize(buffer_size);
423 buffer.setIncrement(shift_value);
428 effect_value = ref.effect_value;
430 buffer.setIncrement(effect_value);
433 float value() {
return effect_value; }
435 void setValue(
float value) {
436 effect_value = value;
437 buffer.setIncrement(value);
444 return buffer.
read();
450 VariableSpeedRingBuffer<int16_t> buffer;
469 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){
474 sample_rate = sample_rate * attackMs / 1000;
475 attack_count = sample_rate * attackMs / 1000;
476 release_count = sample_rate * releaseMs / 1000;
477 hold_count = sample_rate * holdMs / 1000;
480 threshold = 0.01f * thresholdPercent * NumberConverter::maxValueT<effect_t>();
482 gainreduce = compressionRatio;
490 attack_count = sample_rate * attackMs / 1000;
496 release_count = sample_rate * releaseMs / 1000;
502 hold_count = sample_rate * holdMs / 1000;
508 threshold = 0.01f * thresholdPercent * NumberConverter::maxValueT<effect_t>();
513 if (compressionRatio < 1.0f){
514 gainreduce = compressionRatio;
523 return compress(input);
529 enum CompStates {S_NoOperation, S_Attack, S_GainReduction, S_Release };
530 enum CompStates state = S_NoOperation;
532 int32_t attack_count, release_count, hold_count, timeout;
533 float gainreduce, gain_step_attack, gain_step_release, gain, threshold;
534 uint32_t sample_rate;
537 gain_step_attack = (1.0f - gainreduce) / attack_count;
538 gain_step_release = (1.0f - gainreduce) / release_count;
541 float compress(
float inSampleF){
542 if (fabs(inSampleF) > threshold) {
543 if (gain >= gainreduce) {
544 if (state==S_NoOperation) {
546 timeout = attack_count;
548 else if (state==S_Release) {
550 timeout = attack_count;
553 if (state==S_GainReduction) timeout = hold_count;
557 if (fabs(inSampleF) < threshold && gain <= 1.0f) {
558 if ( timeout==0 && state==S_GainReduction) {
560 timeout = release_count;
566 if ( timeout>0 && gain > gainreduce) {
567 gain -= gain_step_attack;
571 state=S_GainReduction;
572 timeout = hold_count;
577 case S_GainReduction:
578 if ( timeout>0) timeout--;
581 timeout = release_count;
587 if ( timeout>0 && gain<1.0f) {
589 gain += gain_step_release;
597 if (gain < 1.0f) gain = 1.0f;
605 float outSampleF = gain * inSampleF;