arduino-audio-tools
Loading...
Searching...
No Matches
AudioFaust.h
Go to the documentation of this file.
1#pragma once
4
5namespace audio_tools {
6
14template<class DSP>
15class FaustStream : public AudioStream {
16 public:
17
22
28
30 end();
32 delete p_dsp;
33#ifdef USE_MEMORY_MANAGER
34 DSP::classDestroy();
35#endif
36 }
37
38
41 return p_dsp;
42 }
43
46 def.channels = 2;
47 def.bits_per_sample = 16;
48 def.sample_rate = 44100;
49 return def;
50 }
51
52
55 TRACED();
56 bool result = true;
57 this->cfg = cfg;
58 this->bytes_per_sample = cfg.bits_per_sample / 8;
61
62 if (p_dsp==nullptr){
63#ifdef USE_MEMORY_MANAGER
64 DSP::fManager = new dsp_memory_manager();
65 DSP::memoryInfo();
66 p_dsp = DSP::create();
67#else
68 p_dsp = new DSP();
69#endif
70 }
71
72 if (p_dsp==nullptr){
73 LOGE("dsp is null");
74 return false;
75 }
76
77 DSP::classInit(cfg.sample_rate);
78 p_dsp->buildUserInterface(&ui);
79 p_dsp->init(cfg.sample_rate);
80 p_dsp->instanceInit(cfg.sample_rate);
81
82 // we do expect an output
83 result = checkChannels();
84
85 // allocate array of channel data
86 if (p_buffer==nullptr){
88 }
89 if (with_output_buffer && p_buffer_out==nullptr){
91 }
92
93 LOGI("is_read: %s", is_read?"true":"false");
94 LOGI("is_write: %s", is_write?"true":"false");
95 gate_exists = ui.exists("gate");
96 LOGI("gate_exists: %s", gate_exists?"true":"false");
97
98 return result;
99 }
100
101
103 void end() {
104 TRACED();
105 is_read = false;
106 is_write = false;
107 p_dsp->instanceClear();
108#ifdef USE_MEMORY_MANAGER
109 DSP::destroy(p_dsp);
110 p_dsp = nullptr;
111#endif
112
113 }
114
116 size_t readBytes(uint8_t *data, size_t len) override {
117 size_t result = 0;
118 if (is_read){
119 TRACED();
120 result = len;
121 int samples = len / bytes_per_sample;
122 allocateFloatBuffer(samples, false);
123 p_dsp->compute(samples, nullptr, p_buffer);
124 // convert from float to int
125 switch(cfg.bits_per_sample){
126 case 8:
128 break;
129 case 16:
131 break;
132 case 24:
134 break;
135 case 32:
137 break;
138 default:
139 TRACEE();
140 }
141 }
142 return result;
143 }
144
146 size_t write(const uint8_t *data, size_t len) override {
147 LOGD("FaustStream::write: %d", len);
148 switch(cfg.bits_per_sample){
149 case 8:
150 return writeT<int8_t>(data, len);
151 case 16:
152 return writeT<int16_t>(data, len);
153 case 24:
154 return writeT<int24_t>(data, len);
155 case 32:
156 return writeT<int32_t>(data, len);
157 default:
158 TRACEE();
159 }
160 return 0;
161 }
162
163 int available() override {
164 return DEFAULT_BUFFER_SIZE;
165 }
166
167 int availableForWrite() override {
168 return DEFAULT_BUFFER_SIZE / bytes_per_frame; // we limit the write size
169 }
170
172 virtual FAUSTFLOAT labelValue(const char*label) {
173 return ui.getValue(label);
174 }
175
177 virtual bool setLabelValue(const char*label, FAUSTFLOAT value){
178 if (!is_read && !is_write) LOGE("setLabelValue must be called after begin");
179 bool result = ui.setValue(label, value);
180 LOGI("setLabelValue('%s',%f) -> %s", label, value, result?"true":"false");
181 return result;
182 }
183
184 virtual bool setMidiNote(int note){
186 return setFrequency(frq);
187 }
188
189 virtual bool setFrequency(FAUSTFLOAT freq){
190 return setLabelValue("freq", freq);
191 }
192
194 return labelValue("freq");
195 }
196
197 virtual bool setBend(FAUSTFLOAT bend){
198 return setLabelValue("bend", bend);
199 }
200
201 virtual FAUSTFLOAT bend() {
202 return labelValue("bend");
203 }
204
205 virtual bool setGain(FAUSTFLOAT gain){
206 return setLabelValue("gain", gain);
207 }
208
209 virtual FAUSTFLOAT gain() {
210 return labelValue("gain");
211 }
212
213 virtual bool midiOn(int note, FAUSTFLOAT gain){
214 if (gate_exists) setLabelValue("gate",1.0);
215 return setMidiNote(note) && setGain(gain);
216 }
217
218 virtual bool midiOff(int note){
219 if (gate_exists) setLabelValue("gate",0.0);
220 return setMidiNote(note) && setGain(0.0);
221 }
222
223 protected:
224 bool is_init = false;
225 bool is_read = false;
226 bool is_write = false;
227 bool gate_exists = false;
232 float float_to_int_factor = 32767;
233 DSP *p_dsp = nullptr;
235 Print *p_out=nullptr;
239
242 bool result = true;
243
244 // update channels
245 int num_outputs = p_dsp->getNumOutputs();
248 LOGW("Updating channels to %d", num_outputs);
249 }
250
251 if (num_outputs>0){
253 is_read = true;
254 } else {
255 LOGE("NumOutputs %d is not matching with number of channels %d", num_outputs, cfg.channels);
256 result = false;
257 }
258 if (p_dsp->getNumInputs()!=0 && p_dsp->getNumInputs()!=cfg.channels){
259 LOGE("NumInputs is not matching with number of channels");
260 result = false;
261 }
262 if (p_dsp->getNumInputs()>0){
263 if (p_out!=nullptr){
264 is_write = true;
265 } else {
266 LOGE("Faust expects input - you need to provide and AudioStream in the constructor");
267 result = false;
268 }
269 }
270 }
271 return result;
272 }
273
275 template <class T>
277 T *dataT = (T*) data_out;
278 int frameCount = samples/cfg.channels;
279 for (int j=0; j<frameCount; j++){
280 for (int i=0;i<cfg.channels;i++){
281 float sample = p_float_in[i][j];
282 // clip input
283 if(sample > 1.0f){
284 sample = 1.0f;
285 }
286 if(sample < -1.0f){
287 sample = -1.0f;
288 }
289 dataT[(j*cfg.channels)+i] = sample * float_to_int_factor;
290 }
291 }
292 }
293
295 template <class T>
297 T *dataT = (T*) data_in;
298 int frameCount = samples/cfg.channels;
299 for(int j=0;j<frameCount;j++){
300 for(int i=0;i<cfg.channels;i++){
301 p_float_out[i][j] = static_cast<FAUSTFLOAT>(dataT[(j*cfg.channels)+i]) / float_to_int_factor;
302 }
303 }
304 }
305
307 template <class T>
308 size_t writeT(const uint8_t *write_data, size_t len) {
309 size_t result = 0;
310 if (is_write){
311 TRACED();
312 int samples = len / bytes_per_sample;
313 int frames = samples / cfg.channels;
314 // prepare float input for faust
317
318 // determine result
320 p_dsp->compute(frames, p_buffer, p_float_buffer);
321
322 // update buffer with data from faust
324 // write data to final output
325 result = p_out->write(write_data, len);
326 }
327 return result;
328 }
329
330
332 void allocateFloatBuffer(int samples, bool allocate_out){
333 if (samples>buffer_allocated){
334 if (p_buffer[0]!=nullptr){
335 for (int j=0;j<cfg.channels;j++){
336 delete[]p_buffer[j];
337 p_buffer[j] = nullptr;
338 }
339 }
340 if (p_buffer_out!=nullptr && p_buffer_out[0]!=nullptr){
341 for (int j=0;j<cfg.channels;j++){
342 delete[]p_buffer_out[j];
343 p_buffer_out[j] = nullptr;
344 }
345 }
346 }
347 if (p_buffer[0]==nullptr){
348 const int ch = cfg.channels;
349 for (int j=0;j<ch;j++){
350 p_buffer[j] = new FAUSTFLOAT[samples];
351 }
352 buffer_allocated = samples;
353 }
354 if (allocate_out){
355 if (p_buffer_out[0]==nullptr){
356 const int ch = cfg.channels;
357 for (int j=0;j<ch;j++){
358 p_buffer_out[j] = new FAUSTFLOAT[samples];
359 }
360 }
361 }
362 }
363
365 if (p_buffer!=nullptr) {
366 for (int j=0;j<cfg.channels;j++){
367 if (p_buffer[j]!=nullptr) delete p_buffer[j];
368 }
369 delete[] p_buffer;
370 p_buffer = nullptr;
371 }
372 if (p_buffer_out!=nullptr) {
373 for (int j=0;j<cfg.channels;j++){
374 if (p_buffer_out[j]!=nullptr) delete p_buffer_out[j];
375 }
376 delete[] p_buffer_out;
377 p_buffer_out = nullptr;
378 }
379 }
380
382 FAUSTFLOAT note = x;
383 return 440.0 * pow(2.0f, (note-69)/12);
384 }
385
386};
387
388
389} // namespace
390
391
#define FAUSTFLOAT
Definition AudioFaustDSP.h:9
#define LOGW(...)
Definition AudioLoggerIDF.h:29
#define TRACED()
Definition AudioLoggerIDF.h:31
#define LOGI(...)
Definition AudioLoggerIDF.h:28
#define TRACEE()
Definition AudioLoggerIDF.h:34
#define LOGD(...)
Definition AudioLoggerIDF.h:27
#define LOGE(...)
Definition AudioLoggerIDF.h:30
#define DEFAULT_BUFFER_SIZE
Definition avr.h:20
Minimum implementation of UI parameters. We only support the setting and getting of values.
Definition AudioFaustDSP.h:52
virtual float getValue(const char *label)
Definition AudioFaustDSP.h:63
virtual bool exists(const char *label)
checks if a label exists
Definition AudioFaustDSP.h:130
virtual bool setValue(const char *label, float value)
Definition AudioFaustDSP.h:70
Base class for all Audio Streams. It support the boolean operator to test if the object is ready with...
Definition BaseStream.h:123
Integration into Faust DSP see https://faust.grame.fr/ To generate code from faust,...
Definition AudioFaust.h:15
AudioInfo cfg
Definition AudioFaust.h:234
virtual bool midiOff(int note)
Definition AudioFaust.h:218
UI ui
Definition AudioFaust.h:238
int buffer_allocated
Definition AudioFaust.h:231
virtual bool setFrequency(FAUSTFLOAT freq)
Definition AudioFaust.h:189
virtual FAUSTFLOAT gain()
Definition AudioFaust.h:209
size_t readBytes(uint8_t *data, size_t len) override
Used if FaustStream is used as audio source.
Definition AudioFaust.h:116
virtual FAUSTFLOAT frequency()
Definition AudioFaust.h:193
int available() override
Definition AudioFaust.h:163
FAUSTFLOAT ** p_buffer
Definition AudioFaust.h:236
FAUSTFLOAT ** p_buffer_out
Definition AudioFaust.h:237
size_t write(const uint8_t *data, size_t len) override
Used if FaustStream is used as audio sink or filter.
Definition AudioFaust.h:146
AudioInfo defaultConfig()
Definition AudioFaust.h:44
FaustStream(Print &out, bool useSeparateOutputBuffer=true)
Constructor for Faust as signal Processor - changing an input signal and sending it to out.
Definition AudioFaust.h:24
bool gate_exists
Definition AudioFaust.h:227
int availableForWrite() override
Definition AudioFaust.h:167
FaustStream(bool useSeparateOutputBuffer=true)
Constructor for Faust as Audio Source.
Definition AudioFaust.h:19
virtual FAUSTFLOAT labelValue(const char *label)
Determines the value of a parameter.
Definition AudioFaust.h:172
bool is_read
Definition AudioFaust.h:225
virtual FAUSTFLOAT bend()
Definition AudioFaust.h:201
int bytes_per_sample
Definition AudioFaust.h:229
bool is_init
Definition AudioFaust.h:224
void convertFloatBufferToInt(int samples, FAUSTFLOAT **p_float_in, void *data_out)
Converts the float buffer to int values.
Definition AudioFaust.h:276
void deleteFloatBuffer()
Definition AudioFaust.h:364
void convertIntBufferToFloat(int samples, void *data_in, FAUSTFLOAT **p_float_out)
Converts the int buffer to float values.
Definition AudioFaust.h:296
virtual bool setGain(FAUSTFLOAT gain)
Definition AudioFaust.h:205
float float_to_int_factor
Definition AudioFaust.h:232
bool checkChannels()
Checks the input and output channels and updates the is_write or is_read scenario flags.
Definition AudioFaust.h:241
virtual bool setMidiNote(int note)
Definition AudioFaust.h:184
Print * p_out
Definition AudioFaust.h:235
DSP * p_dsp
Definition AudioFaust.h:233
virtual bool setBend(FAUSTFLOAT bend)
Definition AudioFaust.h:197
void end()
Ends the processing.
Definition AudioFaust.h:103
bool with_output_buffer
Definition AudioFaust.h:228
virtual bool midiOn(int note, FAUSTFLOAT gain)
Definition AudioFaust.h:213
size_t writeT(const uint8_t *write_data, size_t len)
Used if FaustStream is used as audio sink or filter.
Definition AudioFaust.h:308
dsp * getDSP()
Provides a pointer to the actual dsp object.
Definition AudioFaust.h:40
FAUSTFLOAT noteToFrequency(uint8_t x)
Definition AudioFaust.h:381
void allocateFloatBuffer(int samples, bool allocate_out)
Allocate the buffer that is needed by faust.
Definition AudioFaust.h:332
~FaustStream()
Definition AudioFaust.h:29
bool is_write
Definition AudioFaust.h:226
int bytes_per_frame
Definition AudioFaust.h:230
bool begin(AudioInfo cfg)
Checks the parameters and starts the processing.
Definition AudioFaust.h:54
virtual bool setLabelValue(const char *label, FAUSTFLOAT value)
Defines the value of a parameter.
Definition AudioFaust.h:177
static int64_t maxValue(int value_bits_per_sample)
provides the biggest number for the indicated number of bits
Definition AudioTypes.h:301
Definition NoArduino.h:62
virtual size_t write(const uint8_t *data, size_t len)
Definition NoArduino.h:126
Memory manager which uses psram when it is available.
Definition AudioFaustDSP.h:181
minimal dsp base class needed by Faust
Definition AudioFaustDSP.h:25
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
size_t writeData(Print *p_out, T *data, int samples, int maxSamples=512)
Definition AudioTypes.h:512
Basic Audio information which drives e.g. I2S.
Definition AudioTypes.h:55
sample_rate_t sample_rate
Sample Rate: e.g 44100.
Definition AudioTypes.h:57
uint16_t channels
Number of channels: 2=stereo, 1=mono.
Definition AudioTypes.h:59
uint8_t bits_per_sample
Number of bits per sample (int16_t = 16 bits)
Definition AudioTypes.h:61