Exchanged engine to AUdioStream engine instead of queues.

Changed date for copyrights.
master
Holger Wirtz 4 years ago
parent f1ba1b68e5
commit 35904b7139
  1. 2
      EEPROMAnything.h
  2. 2
      Encoder4.h
  3. 123
      MicroMDAEPiano.ino
  4. 37
      UI.hpp
  5. 2
      config.h
  6. 2
      effect_modulated_delay.cpp
  7. 2
      effect_modulated_delay.h
  8. 2
      mdaEPianoDataXfade.h
  9. 2
      midi_devices.hpp
  10. 2
      midinotes.h
  11. 55
      source_micromdaepiano.h
  12. 8
      third-party/LiquidMenu/src/LiquidMenu_config.h

@ -4,7 +4,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.
(c)2019 H. Wirtz <wirtz@parasitstudio.de>
(c)2019-2020 H. Wirtz <wirtz@parasitstudio.de>
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

@ -4,7 +4,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.
(c)2019 H. Wirtz <wirtz@parasitstudio.de>
(c)2019-2020 H. Wirtz <wirtz@parasitstudio.de>
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

@ -4,7 +4,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.
(c)2019 H. Wirtz <wirtz@parasitstudio.de>
(c)2019-2020 H. Wirtz <wirtz@parasitstudio.de>
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
@ -28,6 +28,7 @@
#include <EEPROM.h>
#include "EEPROMAnything.h"
#include "mdaEPiano.h"
#include "source_micromdaepiano.h"
#include "effect_modulated_delay.h"
#ifdef USE_XFADE_DATA
#include "mdaEPianoDataXfade.h"
@ -43,8 +44,7 @@
//*************************************************************************************************
// Audio configuration
AudioPlayQueue queue_r;
AudioPlayQueue queue_l;
AudioSourceMicroMDAEPiano ep;
AudioAnalyzePeak peak_r;
AudioAnalyzePeak peak_l;
AudioEffectFreeverb freeverb_r;
@ -61,17 +61,17 @@ AudioFilterBiquad modchorus_filter_r;
AudioFilterBiquad modchorus_filter_l;
#endif
AudioSynthWaveform modulator;
AudioConnection patchCord0(queue_r, peak_r);
AudioConnection patchCord1(queue_l, peak_l);
AudioConnection patchCord2(queue_r, freeverb_r);
AudioConnection patchCord3(queue_l, freeverb_l);
AudioConnection patchCord4(queue_r, 0, modchorus_r, 0);
AudioConnection patchCord5(queue_l, 0, modchorus_l, 0);
AudioConnection patchCord0(ep, 0, peak_r, 0);
AudioConnection patchCord1(ep, 1, peak_l, 0);
AudioConnection patchCord2(ep, 0, freeverb_r, 0);
AudioConnection patchCord3(ep, 1, freeverb_l, 0);
AudioConnection patchCord4(ep, 0, modchorus_r, 0);
AudioConnection patchCord5(ep, 1, modchorus_l, 0);
AudioConnection patchCord6(modulator, 0, modchorus_r, 1);
AudioConnection patchCord7(modulator, inverter);
AudioConnection patchCord8(inverter, 0, modchorus_l, 1);
AudioConnection patchCord9(queue_r, 0, mixer_r, 0);
AudioConnection patchCord10(queue_l, 0, mixer_l, 0);
AudioConnection patchCord9(ep, 0, mixer_r, 0);
AudioConnection patchCord10(ep, 1, mixer_l, 0);
#if MOD_FILTER_OUTPUT != MOD_NO_FILTER_OUTPUT
AudioConnection patchCord11(modchorus_r, modchorus_filter_r);
AudioConnection patchCord12(modchorus_l, modchorus_filter_l);
@ -95,9 +95,6 @@ AudioConnection patchCord21(volume_r, 0, i2s1, 0);
AudioConnection patchCord22(volume_l, 0, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1;
// Objects
mdaEPiano* ep;
extern void init_menus(void);
extern int32_t encoder_value[NUM_ENCODER];
extern Bounce but[NUM_ENCODER];
@ -184,7 +181,7 @@ void setup()
// Debug output
Serial.println(F("MicroMDAEPiano based on https://sourceforge.net/projects/mda-vst"));
Serial.println(F("(c)2018/2019 H. Wirtz <wirtz@parasitstudio.de>"));
Serial.println(F("(c)2019-2020 H. Wirtz <wirtz@parasitstudio.de>"));
Serial.println(F("https://codeberg.org/dcoredump/MicroMDAEPiano"));
Serial.print(F("Data in PROGMEM: "));
Serial.print(sizeof(epianoDataXfade), DEC);
@ -192,9 +189,6 @@ void setup()
Serial.println();
Serial.println(F("<setup start>"));
// create EPiano object
ep = new mdaEPiano();
// set initial init configuration
set_complete_configuration();
@ -309,55 +303,6 @@ void setup()
void loop()
{
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)
// Main sound calculation
if (queue_r.available() && queue_l.available() && fill_audio_buffer > audio_block_time_us - 10)
{
fill_audio_buffer = 0;
#if defined (SHOW_DEBUG) && defined (SHOW_CPU_LOAD_MSEC)
if (cpu_mem_millis > SHOW_CPU_LOAD_MSEC)
{
show_cpu_and_mem_usage();
cpu_mem_millis = 0;
}
#endif
audio_buffer_r = queue_r.getBuffer();
if (audio_buffer_r == NULL)
{
Serial.println(F("E: audio_buffer_r allocation problems!"));
}
audio_buffer_l = queue_l.getBuffer();
if (audio_buffer_l == NULL)
{
Serial.println(F("E: audio_buffer_l allocation problems!"));
}
elapsedMicros t1;
ep->process(audio_buffer_r, audio_buffer_l);
uint32_t t2 = t1;
if (t2 > audio_block_time_us) // everything greater 2.9ms is a buffer underrun!
xrun++;
if (t2 > render_time_max)
render_time_max = t2;
if (peak_r.available())
{
if (peak_r.read() > 1.00)
peak++;
}
if (peak_l.available())
{
if (peak_l.read() > 1.00)
peak++;
}
queue_r.playBuffer();
queue_l.playBuffer();
}
check_midi_devices();
// CONTROL-RATE-EVENT-HANDLING
@ -366,17 +311,25 @@ void loop()
control_rate = 0;
handle_ui();
if ( eeprom_config_update_flag > 0 && ep->getActiveVoices() == 0) // write only to eeprom when no voice is active
if ( eeprom_config_update_flag > 0 && ep.getActiveVoices() == 0) // write only to eeprom when no voice is active
eeprom_config_update();
if (eeprom_master_volume_update_flag == true && eeprom_master_volume_update_timer > STORE_MASTER_VOLUME_MS && ep->getActiveVoices() == 0)
if (eeprom_master_volume_update_flag == true && eeprom_master_volume_update_timer > STORE_MASTER_VOLUME_MS && ep.getActiveVoices() == 0)
eeprom_master_volume_update();
}
#if defined (SHOW_DEBUG) && defined (SHOW_CPU_LOAD_MSEC)
if (cpu_mem_millis > SHOW_CPU_LOAD_MSEC)
{
show_cpu_and_mem_usage();
cpu_mem_millis = 0;
}
#endif
#ifdef DEBUG_AUDIO
if (debug_audio_timer > DEBUG_AUDIO)
{
ep->noteOn(60 + rand() % 108, rand() % 128);
ep.noteOn(60 + rand() % 108, rand() % 128);
debug_audio_timer = 0;
}
#endif
@ -389,7 +342,7 @@ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity)
{
if (checkMidiChannel(inChannel))
{
ep->noteOn(inNumber + configuration.transpose, inVelocity);
ep.noteOn(inNumber + configuration.transpose, inVelocity);
}
}
@ -397,7 +350,7 @@ void handleNoteOff(byte inChannel, byte inNumber, byte inVelocity)
{
if (checkMidiChannel(inChannel))
{
ep->noteOn(inNumber + configuration.transpose, 0);
ep.noteOn(inNumber + configuration.transpose, 0);
}
}
@ -415,41 +368,41 @@ void handleControlChange(byte inChannel, byte inData1, byte inData2)
set_reverb_level(map(inData2, 0, 127, ENC_REVERB_LEVEL_MIN, ENC_REVERB_LEVEL_MAX));
break;
case MIDI_CC_TREMOLO_DEPTH: // Tremolo level (same as modwheel)
inData1 = 1; // now it's modwheel and can be processd by ep->processMidiController :-)
inData1 = 1; // now it's modwheel and can be processd by ep.processMidiController :-)
break;
case MIDI_CC_CHORUS_SEND: // Chorus level
set_chorus_level(map(inData2, 0, 127, ENC_CHORUS_LEVEL_MIN, ENC_CHORUS_LEVEL_MAX));
break;
case MIDI_CC_DETUNE_DEPTH: // Detune level
ep->setDetune(mapfloat(float(inData2), 0, 127, 0.0, 1.0));
ep.setDetune(mapfloat(float(inData2), 0, 127, 0.0, 1.0));
break;
// Own MIDI-CC mapping
case MIDI_CC_EP_DECAY:
ep->setDecay(mapfloat(float(inData2), 0, 127, 0.0, 1.0));
ep.setDecay(mapfloat(float(inData2), 0, 127, 0.0, 1.0));
break;
case MIDI_CC_EP_RELEASE:
ep->setRelease(mapfloat(float(inData2), 0, 127, 0.0, 1.0));
ep.setRelease(mapfloat(float(inData2), 0, 127, 0.0, 1.0));
break;
case MIDI_CC_EP_HARDNESS:
ep->setHardness(mapfloat(float(inData2), 0, 127, 0.0, 1.0));
ep.setHardness(mapfloat(float(inData2), 0, 127, 0.0, 1.0));
break;
case MIDI_CC_EP_TREBLE:
ep->setTreble(mapfloat(float(inData2), 0, 127, 0.0, 1.0));
ep.setTreble(mapfloat(float(inData2), 0, 127, 0.0, 1.0));
break;
case MIDI_CC_EP_STEREO:
ep->setStereo(mapfloat(float(inData2), 0, 127, 0.0, 1.0));
ep.setStereo(mapfloat(float(inData2), 0, 127, 0.0, 1.0));
break;
case MIDI_CC_EP_TUNE:
ep->setTune(mapfloat(float(inData2), 0, 127, 0.0, 1.0));
ep.setTune(mapfloat(float(inData2), 0, 127, 0.0, 1.0));
break;
case MIDI_CC_EP_VELOCITY_SENSE:
ep->setVelocitySense(mapfloat(float(inData2), 0, 127, 0.0, 1.0));
ep.setVelocitySense(mapfloat(float(inData2), 0, 127, 0.0, 1.0));
break;
case MIDI_CC_EP_TREM_FRQ:
ep->setPanLFO(mapfloat(float(inData2), 0, 127, 0.0, 1.0));
ep.setPanLFO(mapfloat(float(inData2), 0, 127, 0.0, 1.0));
break;
case MIDI_CC_EP_OVERDRIVE:
ep->setOverdrive(mapfloat(float(inData2), 0, 127, 0.0, 1.0));
ep.setOverdrive(mapfloat(float(inData2), 0, 127, 0.0, 1.0));
break;
case MIDI_CC_COMP_GAIN:
set_comp_gain(map(inData2, 0, 127, ENC_COMP_GAIN_MIN, ENC_COMP_GAIN_MAX));
@ -503,7 +456,7 @@ void handleControlChange(byte inChannel, byte inData1, byte inData2)
set_mono(map(inData2, 0, 127, ENC_MONO_MIN, ENC_MONO_MAX));
break;
default:
ep->processMidiController(inData1, inData2);
ep.processMidiController(inData1, inData2);
break;
}
}
@ -780,7 +733,7 @@ void show_cpu_and_mem_usage(void)
Serial.print(F(" PEAK: "));
Serial.print(peak, DEC);
Serial.print(F(" ACTIVE_VOICES: "));
Serial.print(ep->getActiveVoices(), DEC);
Serial.print(ep.getActiveVoices(), DEC);
Serial.println();
AudioProcessorUsageMaxReset();
AudioMemoryUsageMaxReset();

@ -4,7 +4,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.
(c)2019 H. Wirtz <wirtz@parasitstudio.de>
(c)2019-2020 H. Wirtz <wirtz@parasitstudio.de>
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
@ -45,6 +45,7 @@
#define UI_HPP_INCLUDED
#include <LiquidCrystal_I2C.h>
#include <LiquidMenu.h>
#include "source_micromdaepiano.h"
#define BOUNCE_WITH_PROMPT_DETECTION
#include <Bounce.h>
#include "Encoder4.h"
@ -121,6 +122,7 @@ extern void config_from_eeprom(void);
extern void eeprom_config_write(uint8_t value);
extern AudioControlSGTL5000 sgtl5000_1;
extern AudioSourceMicroMDAEPiano ep;
extern AudioEffectFreeverb freeverb_r;
extern AudioEffectFreeverb freeverb_l;
extern AudioSynthWaveform modulator;
@ -131,7 +133,6 @@ extern AudioMixer4 mixer_l;
extern AudioAmplifier volume_r;
extern AudioAmplifier volume_l;
extern AudioAmplifier inverter;
extern mdaEPiano* ep;
extern config_t configuration;
extern uint8_t sound;
extern uint8_t master_volume;
@ -1900,7 +1901,7 @@ void set_decay(uint8_t value)
Serial.println(value);
#endif
float tmp = mapfloat(float(value), ENC_DECAY_MIN, ENC_DECAY_MAX, 0.0, 1.0);
ep->setDecay(tmp);
ep.setDecay(tmp);
configuration.decay = value;
}
@ -1913,7 +1914,7 @@ void set_release(uint8_t value)
Serial.println(value);
#endif
float tmp = mapfloat(float(value), ENC_RELEASE_MIN, ENC_RELEASE_MAX, 0.0, 1.0);
ep->setRelease(tmp);
ep.setRelease(tmp);
configuration.release = value;
}
@ -1926,7 +1927,7 @@ void set_hardness(uint8_t value)
Serial.println(value);
#endif
float tmp = mapfloat(float(value), ENC_HARDNESS_MIN, ENC_HARDNESS_MAX, 0.0, 1.0);
ep->setHardness(tmp);
ep.setHardness(tmp);
configuration.hardness = value;
}
@ -1939,7 +1940,7 @@ void set_treble(uint8_t value)
Serial.println(value);
#endif
float tmp = mapfloat(float(value), ENC_TREBLE_MIN, ENC_TREBLE_MAX, 0.0, 1.0);
ep->setTreble(tmp);
ep.setTreble(tmp);
configuration.treble = value;
}
@ -1952,7 +1953,7 @@ void set_stereo(uint8_t value)
Serial.println(value);
#endif
float tmp = mapfloat(float(value), ENC_STEREO_MIN, ENC_STEREO_MAX, 0.0, 1.0);
ep->setStereo(tmp);
ep.setStereo(tmp);
configuration.stereo = value;
}
@ -1981,7 +1982,7 @@ void set_tune(int8_t value)
Serial.println(value);
#endif
float tmp = mapfloat(float(value), ENC_TUNE_MIN, ENC_TUNE_MAX, 0.0, 1.0);
ep->setTune(tmp);
ep.setTune(tmp);
configuration.tune = value;
}
@ -1994,7 +1995,7 @@ void set_detune(uint8_t value)
Serial.println(value);
#endif
float tmp = mapfloat(float(value), ENC_DETUNE_MIN, ENC_DETUNE_MAX, 0.0, 1.0);
ep->setDetune(tmp);
ep.setDetune(tmp);
configuration.detune = value;
}
@ -2007,7 +2008,7 @@ void set_velocity_sense(uint8_t value)
Serial.println(value);
#endif
float tmp = mapfloat(float(value), ENC_VELOCITY_SENSE_MIN, ENC_VELOCITY_SENSE_MAX, 0.0, 1.0);
ep->setVelocitySense(tmp);
ep.setVelocitySense(tmp);
configuration.velocity_sense = value;
}
@ -2020,7 +2021,7 @@ void set_pan_trem_frequency(int8_t value)
Serial.println(value);
#endif
float tmp = mapfloat(float(value), ENC_PAN_TREM_FREQUENCY_MIN, ENC_PAN_TREM_FREQUENCY_MAX, 0.0, 1.0);
ep->setPanLFO(tmp);
ep.setPanLFO(tmp);
configuration.pan_trem_frequency = value;
}
@ -2033,7 +2034,7 @@ void set_pan_trem_level(uint8_t value)
Serial.println(value);
#endif
float tmp = mapfloat(float(value), ENC_PAN_TREM_LEVEL_MIN, ENC_PAN_TREM_LEVEL_MAX, 0.0, 1.0);
ep->setPanTremolo(tmp);
ep.setPanTremolo(tmp);
configuration.pan_trem_level = value;
}
@ -2046,7 +2047,7 @@ void set_overdrive(uint8_t value)
Serial.println(value);
#endif
float tmp = mapfloat(float(value), ENC_OVERDRIVE_MIN, ENC_OVERDRIVE_MAX, 0.0, 1.0);
ep->setOverdrive(tmp);
ep.setOverdrive(tmp);
configuration.overdrive = value;
}
@ -2296,7 +2297,7 @@ void set_loudness(uint8_t value)
Serial.print(F("Set LOUDNESS "));
Serial.println(value);
#endif
ep->setLoudness(mapfloat(float(value), ENC_LOUDNESS_MIN, ENC_LOUDNESS_MAX, 0.0, 1.0));
ep.setLoudness(mapfloat(float(value), ENC_LOUDNESS_MIN, ENC_LOUDNESS_MAX, 0.0, 1.0));
//volume_r.gain(tmp);
//volume_l.gain(tmp);
configuration.loudness = value;
@ -2332,9 +2333,9 @@ void set_max_poly(uint8_t value)
Serial.print(F("Set MAX_POLY "));
Serial.println(value);
#endif
ep->setMaxPolyphony(value);
ep.setMaxPolyphony(value);
configuration.max_poly = value;
ep->reset_voices();
ep.reset_voices();
}
void set_mono(uint8_t mode)
@ -2347,13 +2348,13 @@ void set_mono(uint8_t mode)
if (mode == 0)
{
// stereo
ep->setStereo(mapfloat(float(configuration.stereo), ENC_STEREO_MIN, ENC_STEREO_MAX, 0.0, 1.0));
ep.setStereo(mapfloat(float(configuration.stereo), ENC_STEREO_MIN, ENC_STEREO_MAX, 0.0, 1.0));
inverter.gain(-1.0); // change phase for second modulated delay (faked stereo mode)
}
else
{
// mono
ep->setStereo(0.0);
ep.setStereo(0.0);
inverter.gain(1.0);
set_master_volume(master_volume);
}

@ -4,7 +4,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.
(c)2019 H. Wirtz <wirtz@parasitstudio.de>
(c)2019-2020 H. Wirtz <wirtz@parasitstudio.de>
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

@ -1,6 +1,6 @@
/* Audio Library for Teensy 3.X
Copyright (c) 2014, Pete (El Supremo)
Copyright (c) 2019, Holger Wirtz
Copyright (c) 2019-2020, Holger Wirtz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

@ -1,6 +1,6 @@
/* Audio Library for Teensy 3.X
Copyright (c) 2014, Pete (El Supremo)
Copyright (c) 2019, Holger Wirtz
Copyright (c) 2019-2020, Holger Wirtz
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

@ -4,8 +4,6 @@
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.
(c)2019 H. Wirtz <wirtz@parasitstudio.de>
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

@ -4,7 +4,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.
(c)2019 H. Wirtz <wirtz@parasitstudio.de>
(c)2019-2020 H. Wirtz <wirtz@parasitstudio.de>
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

@ -4,7 +4,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.
(c)2019 H. Wirtz <wirtz@parasitstudio.de>
(c)2019-2020 H. Wirtz <wirtz@parasitstudio.de>
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

@ -0,0 +1,55 @@
#pragma once
#include "config.h"
#include "mdaEPiano.h"
#include <AudioStream.h>
class AudioSourceMicroMDAEPiano : public AudioStream, public mdaEPiano {
public:
const uint16_t audio_block_time_us = 1000000 / (SAMPLE_RATE / AUDIO_BLOCK_SAMPLES);
uint32_t xrun = 0;
uint16_t render_time_max = 0;
AudioSourceMicroMDAEPiano() : AudioStream(0, NULL), mdaEPiano() { };
void update(void)
{
if (in_update == true)
{
xrun++;
return;
}
else
in_update = true;
elapsedMicros render_time;
audio_block_t *lblock;
audio_block_t *rblock;
lblock = allocate();
rblock = allocate();
if (!lblock || !rblock)
{
in_update = false;
return;
}
process(rblock->data, lblock->data);
if (render_time > audio_block_time_us) // everything greater audio_block_time_us (2.9ms for buffer size of 128) is a buffer underrun!
xrun++;
if (render_time > render_time_max)
render_time_max = render_time;
transmit(lblock, 0);
transmit(rblock, 1);
release(lblock);
release(rblock);
in_update = false;
};
private:
volatile bool in_update = false;
};

@ -61,16 +61,16 @@ used in the library, also configures the debugging messages.
const uint8_t MAX_VARIABLES = 5; ///< @note Default: 5
/// Configures the number of available functions per line.
const uint8_t MAX_FUNCTIONS = 8; ///< @note Default: 8
const uint8_t MAX_FUNCTIONS = 42; ///< @note Default: 8
/// Configures the number of available lines per screen.
const uint8_t MAX_LINES = 12; ///< @note Default: 12
const uint8_t MAX_LINES = 20; ///< @note Default: 12
/// Configures the number of available screens per menu.
const uint8_t MAX_SCREENS = 14; ///< @note Default: 14
const uint8_t MAX_SCREENS = 2; ///< @note Default: 14
/// Configures the number of available menus per menus system.
const uint8_t MAX_MENUS = 8; ///< @note Default: 8
const uint8_t MAX_MENUS = 45; ///< @note Default: 8
// Turns the debugging messages on or off.
#define LIQUIDMENU_DEBUG false ///< @note Default: false

Loading…
Cancel
Save