From 94c5d375df9ef81ca29e3ceb3b88c018a99f03ff Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Wed, 9 Jan 2019 18:44:54 +0100 Subject: [PATCH] Added USE_F32 for switching to float precission (not working yet). --- MicroMDAEPiano.ino | 63 +++++++++++++++++++++++++----- config.h | 8 ++-- mdaEPiano.cpp | 17 ++++++-- mdaEPiano.h | 96 ++++++++++++++++++++++++---------------------- 4 files changed, 121 insertions(+), 63 deletions(-) diff --git a/MicroMDAEPiano.ino b/MicroMDAEPiano.ino index 8998552..df24407 100644 --- a/MicroMDAEPiano.ino +++ b/MicroMDAEPiano.ino @@ -22,7 +22,11 @@ */ #include "config.h" +#ifdef USE_F32 +#include //for AudioConvert_I16toF32, AudioConvert_F32toI16, and AudioEffectGain_F32 +#else #include +#endif #include #include #include @@ -43,7 +47,6 @@ #include #include #include "LiquidCrystalPlus_I2C.h" -#include //for AudioConvert_I16toF32, AudioConvert_F32toI16, and AudioEffectGain_F32 // [I2C] SCL: Pin 19, SDA: Pin 18 (https://www.pjrc.com/teensy/td_libs_Wire.html) #define LCD_I2C_ADDRESS 0x27 @@ -54,31 +57,55 @@ Encoder enc1(ENC1_PIN_A, ENC1_PIN_B); Bounce but1 = Bounce(BUT1_PIN, 10); // 10 ms debounce // GUItool: begin automatically generated code +#ifdef USE_F32 AudioPlayQueue_F32 queue_r; //xy=494,404 AudioPlayQueue_F32 queue_l; //xy=494,404 -AudioEffectCompressor_F32 comp_r; -AudioEffectCompressor_F32 comp_l; -AudioConvert_F32toI16 float2Int_r; -AudioConvert_F32toI16 float2Int_l; +AudioConvert_F32toI16 float2Int_r; +AudioConvert_F32toI16 float2Int_l; +#else +AudioPlayQueue queue_r; //xy=494,404 +AudioPlayQueue queue_l; //xy=494,404 +#endif AudioAnalyzePeak peak_r; //xy=695,491 AudioAnalyzePeak peak_l; //xy=695,491 +#ifdef USE_F32 +#ifdef USE_COMP_F32 +AudioEffectCompressor_F32 comp_r; +AudioEffectCompressor_F32 comp_l; AudioConnection_F32 patchCord0(queue_r, comp_r); AudioConnection_F32 patchCord1(queue_l, comp_l); AudioConnection_F32 patchCord2(comp_r, float2Int_r); AudioConnection_F32 patchCord3(comp_l, float2Int_l); +#else +AudioConnection_F32 patchCord0(queue_r, float2Int_r); +AudioConnection_F32 patchCord1(queue_l, float2Int_l); +#endif +#endif #ifdef TEENSY_AUDIO_BOARD AudioOutputI2S i2s1; //xy=1072,364 +#ifdef USE_F32 AudioConnection patchCord4(float2Int_r, peak_r); AudioConnection patchCord5(float2Int_l, peak_l); AudioConnection patchCord6(float2Int_r, 0, i2s1, 0); AudioConnection patchCord7(float2Int_l, 0, i2s1, 1); +#else +AudioConnection patchCord4(queue_r, peak_r); +AudioConnection patchCord5(queue_l, peak_l); +AudioConnection patchCord6(queue_r, 0, i2s1, 0); +AudioConnection patchCord7(queue_l, 0, i2s1, 1); +#endif AudioControlSGTL5000 sgtl5000_1; //xy=700,536 #else AudioOutputPT8211 pt8211_1; //xy=1079,320 AudioAmplifier volume_r; //xy=818,370 AudioAmplifier volume_l; //xy=818,411 +#ifdef USE_F32 AudioConnection patchCord4(float2Int_r, volume_r); AudioConnection patchCord5(float2Int_l, volume_l); +#else +AudioConnection patchCord4(queue_r, volume_r); +AudioConnection patchCord5(queue_l, volume_l); +#endif AudioConnection patchCord6(volume_r, peak_r); AudioConnection patchCord7(volume_l, peak_l); AudioConnection patchCord8(volume_r, 0, pt8211_1, 1); @@ -91,6 +118,7 @@ uint8_t midi_channel = DEFAULT_MIDI_CHANNEL; uint32_t xrun = 0; uint32_t overload = 0; uint32_t peak = 0; +uint32_t audio_buffer_problem = 0; uint16_t render_time_max = 0; float vol = VOLUME; float vol_right = 1.0; @@ -173,7 +201,9 @@ void setup() // start audio card AudioMemory(AUDIO_MEM); +#ifdef USE_F32 AudioMemory_F32(AUDIO_MEM_F32); +#endif #ifdef TEENSY_AUDIO_BOARD sgtl5000_1.enable(); @@ -185,7 +215,8 @@ void setup() sgtl5000_1.volume(1.0, 1.0); #endif - set_volume(vol, vol_left, vol_right); + //set_volume(vol, vol_left, vol_right); + set_volume(1.0, 1.0, 1.0); #if defined (DEBUG) && defined (SHOW_CPU_LOAD_MSEC) // Initialize processor and memory measurements @@ -215,10 +246,14 @@ void setup() // DECAY,RELEASE,HARDNESS,TREBLE,PAN_TREM,LFO_RATE,VELOCITY_SENSE,STEREO,MAX_POLY,TUNE,DETUNE,OVERDRIVE +#if defined(USE_F32) && defined(USE_COMP_F32) // setup compressor as limiter setup_compressor(true, -15.0f, 5.0f, 0.005f, 0.200f); // setup compressor like an automatic volume control //setup_compressor(true,-50.0,5.0,1.0,2.0); + comp_r.setPreGain_dB(0.0); + comp_l.setPreGain_dB(0.0); +#endif Serial.println(F("")); @@ -230,8 +265,13 @@ void setup() void loop() { +#if defined(USE_F32) float* audio_buffer_r; // pointer to AUDIO_BLOCK_SAMPLES * sizeof(float) float* audio_buffer_l; // pointer to AUDIO_BLOCK_SAMPLES * sizeof(float) +#else + int16_t* audio_buffer_r; // pointer to AUDIO_BLOCK_SAMPLES * sizeof(int16_t) + int16_t* audio_buffer_l; // pointer to AUDIO_BLOCK_SAMPLES * sizeof(int16_t) +#endif const uint16_t audio_block_time_ms = 1000000 / (SAMPLE_RATE / AUDIO_BLOCK_SAMPLES); // Main sound calculation @@ -239,9 +279,6 @@ void loop() { fill_audio_buffer = 0; - audio_buffer_r = queue_r.getBuffer(); - audio_buffer_l = queue_l.getBuffer(); - #if defined (DEBUG) && defined (SHOW_CPU_LOAD_MSEC) if (cpu_mem_millis > SHOW_CPU_LOAD_MSEC) { @@ -289,10 +326,15 @@ void loop() queue_r.playBuffer(); queue_l.playBuffer(); } + else + { + audio_buffer_problem++; + } handle_input(); } +#if defined(USE_F32) && defined(USE_COMP_F32) void setup_compressor(boolean use_HP_filter, float knee_dBFS, float comp_ratio, float attack_sec, float release_sec) { comp_r.enableHPFilter(use_HP_filter); comp_l.enableHPFilter(use_HP_filter); @@ -303,6 +345,7 @@ void setup_compressor(boolean use_HP_filter, float knee_dBFS, float comp_ratio, comp_r.setAttack_sec(attack_sec, fs_Hz); comp_l.setAttack_sec(attack_sec, fs_Hz); comp_r.setRelease_sec(release_sec, fs_Hz); comp_l.setRelease_sec(release_sec, fs_Hz); } +#endif void handle_input(void) { @@ -536,6 +579,8 @@ void show_cpu_and_mem_usage(void) Serial.print(overload, DEC); Serial.print(F(" PEAK: ")); Serial.print(peak, DEC); + Serial.print(F(" AUDIO_BUF_ERR: ")); + Serial.print(audio_buffer_problem, DEC); Serial.println(); AudioProcessorUsageMaxReset(); AudioMemoryUsageMaxReset(); diff --git a/config.h b/config.h index 3d594e0..1ae996e 100644 --- a/config.h +++ b/config.h @@ -31,12 +31,12 @@ //#define TEENSY_AUDIO_BOARD 1 #define VOLUME 0.8 #define DEFAULT_MIDI_CHANNEL MIDI_CHANNEL_OMNI -#define AUDIO_MEM 300 -#define AUDIO_MEM_F32 10 +#define AUDIO_MEM 16 +#define AUDIO_MEM_F32 16 #define SAMPLE_RATE 44100 -#define REDUCE_LOUDNESS 0 +#define REDUCE_LOUDNESS 1 #define USE_XFADE_DATA 1 - +//#define USE_COMP_F32 1 #if !defined(__MK66FX1M0__) // check for Teensy-3.6 #undef USE_ONBOARD_USB_HOST #define NVOICES 32 diff --git a/mdaEPiano.cpp b/mdaEPiano.cpp index 74ea855..7cff176 100644 --- a/mdaEPiano.cpp +++ b/mdaEPiano.cpp @@ -3,7 +3,7 @@ MicroMDAEPiano is a port of the MDA-EPiano sound engine (https://sourceforge.net/projects/mda-vst/) for the Teensy-3.5/3.6 with audio shield. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or @@ -49,7 +49,7 @@ mdaEPiano::mdaEPiano() // mdaEPiano::mdaEPiano(audioMasterCallback audioMaster) fillpatch(i++, "(default)", 0.500f, 0.500f, 0.500f, 0.500f, 0.500f, 0.650f, 0.250f, 0.500f, 0.50f, 0.500f, 0.146f, 0.000f); setProgram(0); } - + waves = (short*)epianoDataXfade; //Waveform data and keymapping @@ -194,7 +194,11 @@ float mdaEPiano::getParameter(int32_t index) { return programs[curProgram].param[index]; } -void mdaEPiano::process(float *outputs_r, float *outputs_l) +#ifdef USE_F32 +void mdaEPiano::process(float* outputs_r, float* outputs_l) +#else +void mdaEPiano::process(int16_t* outputs_r, int16_t* outputs_l) +#endif { int16_t v; float x, l, r, od = overdrive; @@ -223,7 +227,7 @@ void mdaEPiano::process(float *outputs_r, float *outputs_l) } l += V->outl * x; r += V->outr * x; - + V++; } @@ -237,8 +241,13 @@ void mdaEPiano::process(float *outputs_r, float *outputs_l) l += l * lmod * lfo1; r += r * rmod * lfo1; //worth making all these local variables? +#ifdef USE_F32 outputs_l[frame] += l; outputs_r[frame] += r; +#else + outputs_l[frame] = static_cast(l * 0x7fff) >> REDUCE_LOUDNESS; + outputs_r[frame] = static_cast(r * 0x7fff) >> REDUCE_LOUDNESS; +#endif } if (fabs(tl) < 1.0e-10) tl = 0.0f; //anti-denormal diff --git a/mdaEPiano.h b/mdaEPiano.h index d432b4f..952dd35 100644 --- a/mdaEPiano.h +++ b/mdaEPiano.h @@ -3,7 +3,7 @@ MicroMDAEPiano is a port of the MDA-EPiano sound engine (https://sourceforge.net/projects/mda-vst/) for the Teensy-3.5/3.6 with audio shield. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or @@ -37,10 +37,10 @@ class mdaEPianoProgram { - friend class mdaEPiano; -private: - float param[NPARAMS]; - char name[24]; + friend class mdaEPiano; + private: + float param[NPARAMS]; + char name[24]; }; struct VOICE //voice state @@ -50,7 +50,7 @@ struct VOICE //voice state int32_t pos; int32_t end; int32_t loop; - + float env; //envelope float dec; @@ -75,46 +75,50 @@ struct KGRP //keygroup class mdaEPiano //: public AudioEffectX { -public: - mdaEPiano(); // mdaEPiano(audioMasterCallback audioMaster); - ~mdaEPiano(); - - virtual void process(float *outputs_r, float *outputs_l); - virtual bool processMidiMessage(uint8_t type, uint8_t data1, uint8_t data2); - virtual void setProgram(int32_t program); - virtual void setParameter(int32_t index, float value); - virtual float getParameter(int32_t index); - virtual void resume(); - - int32_t guiUpdate; - void guiGetDisplay(int32_t index, char *label); - -private: - void update(); //my parameter update - void noteOn(int32_t note, int32_t velocity); - void fillpatch(int32_t p, char *name, float p0, float p1, float p2, float p3, float p4, - float p5, float p6, float p7, float p8, float p9, float p10,float p11); - - mdaEPianoProgram* programs; - float Fs, iFs; - - #define EVENTBUFFER 120 - #define EVENTS_DONE 99999999 - int32_t notes[EVENTBUFFER + 8]; //list of delta|note|velocity for current block - - ///global internal variables - KGRP kgrp[34]; - VOICE voice[NVOICES]; - int32_t activevoices, poly; - short *waves; - float width; - int32_t size, sustain; - float lfo0, lfo1, dlfo, lmod, rmod; - float treb, tfrq, tl, tr; - float tune, fine, random, stretch, overdrive; - float muff, muffvel, sizevel, velsens, volume, modwhl; - - uint8_t curProgram; + public: + mdaEPiano(); // mdaEPiano(audioMasterCallback audioMaster); + ~mdaEPiano(); + +#ifdef USE_F32 + virtual void process(float *outputs_r, float *outputs_l); +#else + virtual void process(int16_t *outputs_r, int16_t *outputs_l); +#endif + virtual bool processMidiMessage(uint8_t type, uint8_t data1, uint8_t data2); + virtual void setProgram(int32_t program); + virtual void setParameter(int32_t index, float value); + virtual float getParameter(int32_t index); + virtual void resume(); + + int32_t guiUpdate; + void guiGetDisplay(int32_t index, char *label); + + private: + void update(); //my parameter update + void noteOn(int32_t note, int32_t velocity); + void fillpatch(int32_t p, char *name, float p0, float p1, float p2, float p3, float p4, + float p5, float p6, float p7, float p8, float p9, float p10, float p11); + + mdaEPianoProgram* programs; + float Fs, iFs; + +#define EVENTBUFFER 120 +#define EVENTS_DONE 99999999 + int32_t notes[EVENTBUFFER + 8]; //list of delta|note|velocity for current block + + ///global internal variables + KGRP kgrp[34]; + VOICE voice[NVOICES]; + int32_t activevoices, poly; + short *waves; + float width; + int32_t size, sustain; + float lfo0, lfo1, dlfo, lmod, rmod; + float treb, tfrq, tl, tr; + float tune, fine, random, stretch, overdrive; + float muff, muffvel, sizevel, velsens, volume, modwhl; + + uint8_t curProgram; }; #endif