Added USE_F32 for switching to float precission (not working yet).

chorus
Holger Wirtz 5 years ago
parent e7f87f5209
commit 94c5d375df
  1. 63
      MicroMDAEPiano.ino
  2. 8
      config.h
  3. 17
      mdaEPiano.cpp
  4. 96
      mdaEPiano.h

@ -22,7 +22,11 @@
*/ */
#include "config.h" #include "config.h"
#ifdef USE_F32
#include <OpenAudio_ArduinoLibrary.h> //for AudioConvert_I16toF32, AudioConvert_F32toI16, and AudioEffectGain_F32
#else
#include <Audio.h> #include <Audio.h>
#endif
#include <Wire.h> #include <Wire.h>
#include <SPI.h> #include <SPI.h>
#include <MIDI.h> #include <MIDI.h>
@ -43,7 +47,6 @@
#include <Bounce.h> #include <Bounce.h>
#include <Encoder.h> #include <Encoder.h>
#include "LiquidCrystalPlus_I2C.h" #include "LiquidCrystalPlus_I2C.h"
#include <OpenAudio_ArduinoLibrary.h> //for AudioConvert_I16toF32, AudioConvert_F32toI16, and AudioEffectGain_F32
// [I2C] SCL: Pin 19, SDA: Pin 18 (https://www.pjrc.com/teensy/td_libs_Wire.html) // [I2C] SCL: Pin 19, SDA: Pin 18 (https://www.pjrc.com/teensy/td_libs_Wire.html)
#define LCD_I2C_ADDRESS 0x27 #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 Bounce but1 = Bounce(BUT1_PIN, 10); // 10 ms debounce
// GUItool: begin automatically generated code // GUItool: begin automatically generated code
#ifdef USE_F32
AudioPlayQueue_F32 queue_r; //xy=494,404 AudioPlayQueue_F32 queue_r; //xy=494,404
AudioPlayQueue_F32 queue_l; //xy=494,404 AudioPlayQueue_F32 queue_l; //xy=494,404
AudioEffectCompressor_F32 comp_r; AudioConvert_F32toI16 float2Int_r;
AudioEffectCompressor_F32 comp_l; AudioConvert_F32toI16 float2Int_l;
AudioConvert_F32toI16 float2Int_r; #else
AudioConvert_F32toI16 float2Int_l; AudioPlayQueue queue_r; //xy=494,404
AudioPlayQueue queue_l; //xy=494,404
#endif
AudioAnalyzePeak peak_r; //xy=695,491 AudioAnalyzePeak peak_r; //xy=695,491
AudioAnalyzePeak peak_l; //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 patchCord0(queue_r, comp_r);
AudioConnection_F32 patchCord1(queue_l, comp_l); AudioConnection_F32 patchCord1(queue_l, comp_l);
AudioConnection_F32 patchCord2(comp_r, float2Int_r); AudioConnection_F32 patchCord2(comp_r, float2Int_r);
AudioConnection_F32 patchCord3(comp_l, float2Int_l); 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 #ifdef TEENSY_AUDIO_BOARD
AudioOutputI2S i2s1; //xy=1072,364 AudioOutputI2S i2s1; //xy=1072,364
#ifdef USE_F32
AudioConnection patchCord4(float2Int_r, peak_r); AudioConnection patchCord4(float2Int_r, peak_r);
AudioConnection patchCord5(float2Int_l, peak_l); AudioConnection patchCord5(float2Int_l, peak_l);
AudioConnection patchCord6(float2Int_r, 0, i2s1, 0); AudioConnection patchCord6(float2Int_r, 0, i2s1, 0);
AudioConnection patchCord7(float2Int_l, 0, i2s1, 1); 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 AudioControlSGTL5000 sgtl5000_1; //xy=700,536
#else #else
AudioOutputPT8211 pt8211_1; //xy=1079,320 AudioOutputPT8211 pt8211_1; //xy=1079,320
AudioAmplifier volume_r; //xy=818,370 AudioAmplifier volume_r; //xy=818,370
AudioAmplifier volume_l; //xy=818,411 AudioAmplifier volume_l; //xy=818,411
#ifdef USE_F32
AudioConnection patchCord4(float2Int_r, volume_r); AudioConnection patchCord4(float2Int_r, volume_r);
AudioConnection patchCord5(float2Int_l, volume_l); 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 patchCord6(volume_r, peak_r);
AudioConnection patchCord7(volume_l, peak_l); AudioConnection patchCord7(volume_l, peak_l);
AudioConnection patchCord8(volume_r, 0, pt8211_1, 1); 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 xrun = 0;
uint32_t overload = 0; uint32_t overload = 0;
uint32_t peak = 0; uint32_t peak = 0;
uint32_t audio_buffer_problem = 0;
uint16_t render_time_max = 0; uint16_t render_time_max = 0;
float vol = VOLUME; float vol = VOLUME;
float vol_right = 1.0; float vol_right = 1.0;
@ -173,7 +201,9 @@ void setup()
// start audio card // start audio card
AudioMemory(AUDIO_MEM); AudioMemory(AUDIO_MEM);
#ifdef USE_F32
AudioMemory_F32(AUDIO_MEM_F32); AudioMemory_F32(AUDIO_MEM_F32);
#endif
#ifdef TEENSY_AUDIO_BOARD #ifdef TEENSY_AUDIO_BOARD
sgtl5000_1.enable(); sgtl5000_1.enable();
@ -185,7 +215,8 @@ void setup()
sgtl5000_1.volume(1.0, 1.0); sgtl5000_1.volume(1.0, 1.0);
#endif #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) #if defined (DEBUG) && defined (SHOW_CPU_LOAD_MSEC)
// Initialize processor and memory measurements // 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 // 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 as limiter
setup_compressor(true, -15.0f, 5.0f, 0.005f, 0.200f); setup_compressor(true, -15.0f, 5.0f, 0.005f, 0.200f);
// setup compressor like an automatic volume control // setup compressor like an automatic volume control
//setup_compressor(true,-50.0,5.0,1.0,2.0); //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("<setup end>")); Serial.println(F("<setup end>"));
@ -230,8 +265,13 @@ void setup()
void loop() void loop()
{ {
#if defined(USE_F32)
float* audio_buffer_r; // pointer to AUDIO_BLOCK_SAMPLES * sizeof(float) float* audio_buffer_r; // pointer to AUDIO_BLOCK_SAMPLES * sizeof(float)
float* audio_buffer_l; // 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); const uint16_t audio_block_time_ms = 1000000 / (SAMPLE_RATE / AUDIO_BLOCK_SAMPLES);
// Main sound calculation // Main sound calculation
@ -239,9 +279,6 @@ void loop()
{ {
fill_audio_buffer = 0; 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 defined (DEBUG) && defined (SHOW_CPU_LOAD_MSEC)
if (cpu_mem_millis > SHOW_CPU_LOAD_MSEC) if (cpu_mem_millis > SHOW_CPU_LOAD_MSEC)
{ {
@ -289,10 +326,15 @@ void loop()
queue_r.playBuffer(); queue_r.playBuffer();
queue_l.playBuffer(); queue_l.playBuffer();
} }
else
{
audio_buffer_problem++;
}
handle_input(); 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) 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); 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.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); comp_r.setRelease_sec(release_sec, fs_Hz); comp_l.setRelease_sec(release_sec, fs_Hz);
} }
#endif
void handle_input(void) void handle_input(void)
{ {
@ -536,6 +579,8 @@ void show_cpu_and_mem_usage(void)
Serial.print(overload, DEC); Serial.print(overload, DEC);
Serial.print(F(" PEAK: ")); Serial.print(F(" PEAK: "));
Serial.print(peak, DEC); Serial.print(peak, DEC);
Serial.print(F(" AUDIO_BUF_ERR: "));
Serial.print(audio_buffer_problem, DEC);
Serial.println(); Serial.println();
AudioProcessorUsageMaxReset(); AudioProcessorUsageMaxReset();
AudioMemoryUsageMaxReset(); AudioMemoryUsageMaxReset();

@ -31,12 +31,12 @@
//#define TEENSY_AUDIO_BOARD 1 //#define TEENSY_AUDIO_BOARD 1
#define VOLUME 0.8 #define VOLUME 0.8
#define DEFAULT_MIDI_CHANNEL MIDI_CHANNEL_OMNI #define DEFAULT_MIDI_CHANNEL MIDI_CHANNEL_OMNI
#define AUDIO_MEM 300 #define AUDIO_MEM 16
#define AUDIO_MEM_F32 10 #define AUDIO_MEM_F32 16
#define SAMPLE_RATE 44100 #define SAMPLE_RATE 44100
#define REDUCE_LOUDNESS 0 #define REDUCE_LOUDNESS 1
#define USE_XFADE_DATA 1 #define USE_XFADE_DATA 1
//#define USE_COMP_F32 1
#if !defined(__MK66FX1M0__) // check for Teensy-3.6 #if !defined(__MK66FX1M0__) // check for Teensy-3.6
#undef USE_ONBOARD_USB_HOST #undef USE_ONBOARD_USB_HOST
#define NVOICES 32 #define NVOICES 32

@ -3,7 +3,7 @@
MicroMDAEPiano is a port of the MDA-EPiano sound engine 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. (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 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or 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); 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); setProgram(0);
} }
waves = (short*)epianoDataXfade; waves = (short*)epianoDataXfade;
//Waveform data and keymapping //Waveform data and keymapping
@ -194,7 +194,11 @@ float mdaEPiano::getParameter(int32_t index) {
return programs[curProgram].param[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; int16_t v;
float x, l, r, od = overdrive; float x, l, r, od = overdrive;
@ -223,7 +227,7 @@ void mdaEPiano::process(float *outputs_r, float *outputs_l)
} }
l += V->outl * x; l += V->outl * x;
r += V->outr * x; r += V->outr * x;
V++; V++;
} }
@ -237,8 +241,13 @@ void mdaEPiano::process(float *outputs_r, float *outputs_l)
l += l * lmod * lfo1; l += l * lmod * lfo1;
r += r * rmod * lfo1; //worth making all these local variables? r += r * rmod * lfo1; //worth making all these local variables?
#ifdef USE_F32
outputs_l[frame] += l; outputs_l[frame] += l;
outputs_r[frame] += r; outputs_r[frame] += r;
#else
outputs_l[frame] = static_cast<int16_t>(l * 0x7fff) >> REDUCE_LOUDNESS;
outputs_r[frame] = static_cast<int16_t>(r * 0x7fff) >> REDUCE_LOUDNESS;
#endif
} }
if (fabs(tl) < 1.0e-10) tl = 0.0f; //anti-denormal if (fabs(tl) < 1.0e-10) tl = 0.0f; //anti-denormal

@ -3,7 +3,7 @@
MicroMDAEPiano is a port of the MDA-EPiano sound engine 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. (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 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or the Free Software Foundation; either version 3 of the License, or
@ -37,10 +37,10 @@
class mdaEPianoProgram class mdaEPianoProgram
{ {
friend class mdaEPiano; friend class mdaEPiano;
private: private:
float param[NPARAMS]; float param[NPARAMS];
char name[24]; char name[24];
}; };
struct VOICE //voice state struct VOICE //voice state
@ -50,7 +50,7 @@ struct VOICE //voice state
int32_t pos; int32_t pos;
int32_t end; int32_t end;
int32_t loop; int32_t loop;
float env; //envelope float env; //envelope
float dec; float dec;
@ -75,46 +75,50 @@ struct KGRP //keygroup
class mdaEPiano //: public AudioEffectX class mdaEPiano //: public AudioEffectX
{ {
public: public:
mdaEPiano(); // mdaEPiano(audioMasterCallback audioMaster); mdaEPiano(); // mdaEPiano(audioMasterCallback audioMaster);
~mdaEPiano(); ~mdaEPiano();
virtual void process(float *outputs_r, float *outputs_l); #ifdef USE_F32
virtual bool processMidiMessage(uint8_t type, uint8_t data1, uint8_t data2); virtual void process(float *outputs_r, float *outputs_l);
virtual void setProgram(int32_t program); #else
virtual void setParameter(int32_t index, float value); virtual void process(int16_t *outputs_r, int16_t *outputs_l);
virtual float getParameter(int32_t index); #endif
virtual void resume(); virtual bool processMidiMessage(uint8_t type, uint8_t data1, uint8_t data2);
virtual void setProgram(int32_t program);
int32_t guiUpdate; virtual void setParameter(int32_t index, float value);
void guiGetDisplay(int32_t index, char *label); virtual float getParameter(int32_t index);
virtual void resume();
private:
void update(); //my parameter update int32_t guiUpdate;
void noteOn(int32_t note, int32_t velocity); void guiGetDisplay(int32_t index, char *label);
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); private:
void update(); //my parameter update
mdaEPianoProgram* programs; void noteOn(int32_t note, int32_t velocity);
float Fs, iFs; 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);
#define EVENTBUFFER 120
#define EVENTS_DONE 99999999 mdaEPianoProgram* programs;
int32_t notes[EVENTBUFFER + 8]; //list of delta|note|velocity for current block float Fs, iFs;
///global internal variables #define EVENTBUFFER 120
KGRP kgrp[34]; #define EVENTS_DONE 99999999
VOICE voice[NVOICES]; int32_t notes[EVENTBUFFER + 8]; //list of delta|note|velocity for current block
int32_t activevoices, poly;
short *waves; ///global internal variables
float width; KGRP kgrp[34];
int32_t size, sustain; VOICE voice[NVOICES];
float lfo0, lfo1, dlfo, lmod, rmod; int32_t activevoices, poly;
float treb, tfrq, tl, tr; short *waves;
float tune, fine, random, stretch, overdrive; float width;
float muff, muffvel, sizevel, velsens, volume, modwhl; int32_t size, sustain;
float lfo0, lfo1, dlfo, lmod, rmod;
uint8_t curProgram; float treb, tfrq, tl, tr;
float tune, fine, random, stretch, overdrive;
float muff, muffvel, sizevel, velsens, volume, modwhl;
uint8_t curProgram;
}; };
#endif #endif

Loading…
Cancel
Save