2 #include "AudioTools/CoreAudio/AudioStreams.h"
3 #include "AudioTools/AudioLibs/AudioFaustDSP.h"
20 with_output_buffer = useSeparateOutputBuffer;
26 with_output_buffer = useSeparateOutputBuffer;
33 #ifdef USE_MEMORY_MANAGER
59 this->bytes_per_frame = bytes_per_sample * cfg.
channels;
63 #ifdef USE_MEMORY_MANAGER
66 p_dsp = DSP::create();
78 p_dsp->buildUserInterface(&ui);
86 if (p_buffer==
nullptr){
87 p_buffer =
new FAUSTFLOAT*[cfg.
channels]();
89 if (with_output_buffer && p_buffer_out==
nullptr){
90 p_buffer_out =
new FAUSTFLOAT*[cfg.
channels]();
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");
107 p_dsp->instanceClear();
108 #ifdef USE_MEMORY_MANAGER
121 int samples = len / bytes_per_sample;
123 p_dsp->compute(samples,
nullptr, p_buffer);
127 convertFloatBufferToInt<int8_t>(samples, p_buffer, data);
130 convertFloatBufferToInt<int16_t>(samples, p_buffer, data);
133 convertFloatBufferToInt<int24_t>(samples, p_buffer, data);
136 convertFloatBufferToInt<int32_t>(samples, p_buffer, data);
146 size_t write(
const uint8_t *data,
size_t len)
override {
147 LOGD(
"FaustStream::write: %d", len);
150 return writeT<int8_t>(data, len);
152 return writeT<int16_t>(data, len);
154 return writeT<int24_t>(data, len);
156 return writeT<int32_t>(data, len);
163 int available()
override {
164 return DEFAULT_BUFFER_SIZE;
167 int availableForWrite()
override {
168 return DEFAULT_BUFFER_SIZE / bytes_per_frame;
173 return ui.getValue(label);
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");
184 virtual bool setMidiNote(
int note){
185 FAUSTFLOAT frq = noteToFrequency(note);
186 return setFrequency(frq);
189 virtual bool setFrequency(FAUSTFLOAT freq){
193 virtual FAUSTFLOAT frequency() {
197 virtual bool setBend(FAUSTFLOAT bend){
201 virtual FAUSTFLOAT bend() {
205 virtual bool setGain(FAUSTFLOAT gain){
209 virtual FAUSTFLOAT gain() {
213 virtual bool midiOn(
int note, FAUSTFLOAT gain){
215 return setMidiNote(note) && setGain(gain);
218 virtual bool midiOff(
int note){
220 return setMidiNote(note) && setGain(0.0);
224 bool is_init =
false;
225 bool is_read =
false;
226 bool is_write =
false;
227 bool gate_exists =
false;
228 bool with_output_buffer;
229 int bytes_per_sample;
231 int buffer_allocated;
232 float float_to_int_factor = 32767;
233 DSP *p_dsp =
nullptr;
235 Print *p_out=
nullptr;
236 FAUSTFLOAT** p_buffer=
nullptr;
237 FAUSTFLOAT** p_buffer_out=
nullptr;
245 int num_outputs = p_dsp->getNumOutputs();
246 if (cfg.channels!=num_outputs){
247 cfg.channels = num_outputs;
248 LOGW(
"Updating channels to %d", num_outputs);
252 if (num_outputs==cfg.channels){
255 LOGE(
"NumOutputs %d is not matching with number of channels %d", num_outputs, cfg.channels);
258 if (p_dsp->getNumInputs()!=0 && p_dsp->getNumInputs()!=cfg.channels){
259 LOGE(
"NumInputs is not matching with number of channels");
262 if (p_dsp->getNumInputs()>0){
266 LOGE(
"Faust expects input - you need to provide and AudioStream in the constructor");
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];
289 dataT[(j*cfg.channels)+i] = sample * float_to_int_factor;
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;
308 size_t writeT(
const uint8_t *write_data,
size_t len) {
312 int samples = len / bytes_per_sample;
313 int frames = samples / cfg.channels;
316 convertIntBufferToFloat<T>(samples, (
void*) write_data, p_buffer);
319 FAUSTFLOAT** p_float_buffer = with_output_buffer ? p_buffer_out : p_buffer;
320 p_dsp->compute(frames, p_buffer, p_float_buffer);
323 convertFloatBufferToInt<T>(samples, p_float_buffer, (
void*) write_data);
325 result = p_out->write(write_data, len);
333 if (samples>buffer_allocated){
334 if (p_buffer[0]!=
nullptr){
335 for (
int j=0;j<cfg.channels;j++){
337 p_buffer[j] =
nullptr;
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;
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];
352 buffer_allocated = samples;
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];
364 void deleteFloatBuffer() {
365 if (p_buffer!=
nullptr) {
366 for (
int j=0;j<cfg.channels;j++){
367 if (p_buffer[j]!=
nullptr)
delete p_buffer[j];
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];
376 delete[] p_buffer_out;
377 p_buffer_out =
nullptr;
381 FAUSTFLOAT noteToFrequency(uint8_t x) {
383 return 440.0 * pow(2.0f, (note-69)/12);
Minimum implementation of UI parameters. We only support the setting and getting of values.
Definition: AudioFaustDSP.h:52
virtual bool exists(const char *label)
checks if a label exists
Definition: AudioFaustDSP.h:130
Memory manager which uses psram when it is available.
Definition: AudioFaustDSP.h:181
minimal dsp base class needed by Faust
Definition: AudioFaustDSP.h:25