Skip to content

Commit a5ee1ce

Browse files
committed
AudioEffectStream
1 parent 3a73bd5 commit a5ee1ce

File tree

2 files changed

+133
-5
lines changed

2 files changed

+133
-5
lines changed

src/AudioBasic/Int24.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class int24_t {
3939
set((int32_t)in);
4040
}
4141

42-
#if defined(STM32) || defined(ESP32C3)
42+
#if defined(STM32) || defined(ESP32C3) || defined(TARGET_RP2040)
4343

4444
int24_t(const int &in) {
4545
set(in);

src/AudioEffects/AudioEffects.h

Lines changed: 132 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#pragma once
2-
2+
#include <variant>
33
#include "AudioBasic/Collections.h"
44
#include "AudioEffects/SoundGenerator.h"
55
#include "AudioEffects/AudioEffect.h"
@@ -226,8 +226,13 @@ class AudioEffectStreamT : public AudioStreamX {
226226

227227
bool begin(AudioBaseInfo cfg){
228228
info = cfg;
229-
active = true;
230-
return true;
229+
if (sizeof(T)==cfg.bits_per_sample/8){
230+
active = true;
231+
} else {
232+
LOGE("bits_per_sample not consistent: %d",cfg.bits_per_sample);
233+
active = false;
234+
}
235+
return active;
231236
}
232237

233238
void end() override {
@@ -374,13 +379,136 @@ class AudioEffectStreamT : public AudioStreamX {
374379
Print *p_print=nullptr;
375380
};
376381

382+
#if __cplusplus >= 201703L
377383
/**
378-
* @brief EffectsStream using effect_t (=int16_t) samples
384+
* @brief EffectsStream supporting variable bits_per_sample.
385+
* This class is only available when __cplusplus >= 201703L
379386
* @ingroup effects transform
380387
* @author Phil Schatzmann
381388
* @copyright GPLv3
382389
**/
383390

391+
class AudioEffectStream : public AudioStreamX {
392+
AudioEffectStream() = default;
393+
394+
AudioEffectStream(Stream &io){
395+
setOutput(io);
396+
setInput(io);
397+
}
398+
399+
AudioEffectStream(Print &out){
400+
setOutput(out);
401+
}
402+
403+
AudioBaseInfo defaultConfig() {
404+
AudioBaseInfo cfg;
405+
cfg.sample_rate = 44100;
406+
cfg.bits_per_sample = 16;
407+
cfg.channels = 2;
408+
return cfg;
409+
}
410+
411+
bool begin(AudioBaseInfo cfg){
412+
info = cfg;
413+
switch(cfg.bits_per_sample){
414+
case 16:
415+
variant.emplace<0>();
416+
break;
417+
case 24:
418+
variant.emplace<1>();
419+
break;
420+
case 32:
421+
variant.emplace<2>();
422+
break;
423+
default:
424+
LOGE("Unspported bits_per_sample: %d", cfg.bits_per_sample);
425+
return false;
426+
}
427+
std::visit( [this](auto&& e) {return e.setOutput(*p_print);}, variant );
428+
std::visit( [this](auto&& e) {return e.setInput(*p_io);}, variant );
429+
return std::visit( [cfg](auto&& e) {return e.begin(cfg);}, variant );
430+
}
431+
432+
void end() override {
433+
std::visit( [](auto&& e) {e.end();}, variant );
434+
}
435+
436+
void setInput(Stream &io){
437+
p_io = &io;
438+
}
439+
440+
void setOutput(Stream &io){
441+
p_io = &io;
442+
}
443+
444+
void setOutput(Print &print){
445+
p_print = &print;
446+
}
447+
448+
/**
449+
* Provides the audio data by reading the assinged Stream and applying
450+
* the effects on that input
451+
*/
452+
size_t readBytes(uint8_t *buffer, size_t length) override {
453+
return std::visit( [buffer, length](auto&& e) {return e.readBytes(buffer, length);}, variant );
454+
}
455+
456+
/**
457+
* Writes the samples passed in the buffer and applies the effects before writing the
458+
* result to the output defined in the constructor.
459+
*/
460+
size_t write(const uint8_t *buffer, size_t length) override {
461+
return std::visit( [buffer, length](auto&& e) {return e.write(buffer, length);}, variant );
462+
}
463+
464+
int available() override {
465+
return std::visit( [](auto&& e) {return e.available();}, variant );
466+
}
467+
468+
int availableForWrite() override {
469+
return std::visit( [](auto&& e) {return e.availableForWrite();}, variant );
470+
}
471+
472+
/// Adds an effect object (by reference)
473+
void addEffect(AudioEffect &effect){
474+
addEffect(&effect);
475+
}
476+
477+
/// Adds an effect using a pointer
478+
void addEffect(AudioEffect *effect){
479+
std::visit( [effect](auto&& e) {e.addEffect(effect);}, variant );
480+
}
481+
482+
/// deletes all defined effects
483+
void clear() {
484+
std::visit( [](auto&& e) {e.clear();}, variant );
485+
}
486+
487+
/// Provides the actual number of defined effects
488+
size_t size() {
489+
return std::visit( [](auto&& e) {return e.size();}, variant );
490+
}
491+
492+
/// gets an effect by index
493+
AudioEffect* operator [](int idx){
494+
return std::visit( [idx](auto&& e) {return e[idx];}, variant );
495+
}
496+
497+
/// Finds an effect by id
498+
AudioEffect* findEffect(int id){
499+
return std::visit( [id](auto&& e) {return e.findEffect(id);}, variant );
500+
}
501+
502+
protected:
503+
std::variant<AudioEffectStreamT<int16_t>, AudioEffectStreamT<int24_t>,AudioEffectStreamT<int32_t>> variant;
504+
Stream *p_io=nullptr;
505+
Print *p_print=nullptr;
506+
507+
};
508+
509+
#else
510+
// Use int16_t as only supported data type
384511
using AudioEffectStream = AudioEffectStreamT<effect_t>;
512+
#endif
385513

386514
} // namespace

0 commit comments

Comments
 (0)