Removed old UI code.

Added new UI code based on LiquidMenu.
dev
Holger Wirtz 6 years ago
parent 8e6a00ff45
commit 58466a8471
  1. 43
      EEPROMAnything.h
  2. 86
      LiquidCrystalPlus_I2C.h
  3. 173
      MicroMDAEPiano.ino
  4. 35
      UI.cpp
  5. 57
      UI.hpp
  6. 23
      config.h
  7. 5
      mdaEPiano.cpp
  8. 2
      mdaEPiano.h

@ -21,26 +21,31 @@
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#ifndef UI_H_INCLUDED // Idea from: https://playground.arduino.cc/Code/EEPROMWriteAnything/
#define UI_H_INCLUDED
/* #include <EEPROM.h>
#include "config.h" #include <Arduino.h> // for type definitions
#include "LiquidCrystalPlus_I2C.h"
#include <Bounce.h> uint32_t crc32(uint8_t* calc_start, uint16_t calc_bytes);
#include "Encoder4.h"
template <class T> int EEPROM_writeAnything(int ee, const T& value)
{
uint8_t* p = (uint8_t*)(const void*)&value;
uint16_t i;
uint32_t checksum=crc32(p+4,sizeof(value)-4);
class UI *p=checksum;
for (i = 0; i < sizeof(value); i++)
EEPROM.update(ee++, *p++);
return i;
}
template <class T> int EEPROM_readAnything(int ee, T& value)
{ {
public: uint8_t* p = (uint8_t*)(void*)&value;
UI(); unsigned int i;
~UI(); for (i = 0; i < sizeof(value); i++)
*p++ = EEPROM.read(ee++);
private: return i;
LiquidCrystalPlus_I2C lcd;
Encoder4 enc[2];
int32_t enc_val[2];
Bounce but[2];
} }
*/
#endif

@ -1,86 +0,0 @@
/*
MicroMDAEPiano
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
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef LIQUIDCRYSTALPLUS_I2C_H_INCLUDED
#define LIQUIDCRYSTALPLUS_I2C_H_INCLUDED
#include <LiquidCrystal_I2C.h> // https://www.arduinolibraries.info/libraries/liquid-crystal-i2-c
#define STRING_BUF_SIZE 21
class LiquidCrystalPlus_I2C : public LiquidCrystal_I2C
{
public:
using LiquidCrystal_I2C::LiquidCrystal_I2C;
void show(uint8_t y, uint8_t x, uint8_t fs, char *str)
{
_show(y, x, fs, str, false, false);
}
void show(uint8_t y, uint8_t x, uint8_t fs, long num)
{
char _buf10[STRING_BUF_SIZE];
_show(y, x, fs, itoa(num, _buf10, 10), true, true);
}
private:
void _show(uint8_t pos_y, uint8_t pos_x, uint8_t field_size, char *str, bool justify_right, bool fill_zero)
{
{
char tmp[STRING_BUF_SIZE];
char *s = tmp;
uint8_t l = strlen(str);
memset(tmp, 0, sizeof(tmp));
if (fill_zero == true)
memset(tmp, '0', field_size);
else
memset(tmp, 0x20, field_size - 1); // blank
if (l > field_size)
l = field_size;
if (justify_right == true)
s += field_size - l;
strncpy(s, str, l);
setCursor(pos_x, pos_y);
print(tmp);
#ifdef DEBUG
Serial.print(pos_y, DEC);
Serial.print(F("/"));
Serial.print(pos_x, DEC);
Serial.print(F(": ["));
Serial.print(tmp);
Serial.println(F("]"));
#endif
}
}
};
#endif

@ -27,6 +27,7 @@
#include <SPI.h> #include <SPI.h>
#include <MIDI.h> #include <MIDI.h>
#include <EEPROM.h> #include <EEPROM.h>
#include "EEPROMAnything.h"
#include <limits.h> #include <limits.h>
#include "mdaEPiano.h" #include "mdaEPiano.h"
#ifdef USE_XFADE_DATA #ifdef USE_XFADE_DATA
@ -38,6 +39,7 @@
#include "Encoder4.h" #include "Encoder4.h"
#include <LiquidCrystal_I2C.h> #include <LiquidCrystal_I2C.h>
#include <LiquidMenu.h> #include <LiquidMenu.h>
#include "UI.hpp"
#include "midi_devices.hpp" #include "midi_devices.hpp"
//************************************************************************************************* //*************************************************************************************************
@ -102,18 +104,17 @@ float vol = VOLUME;
float vol_right = 1.0; float vol_right = 1.0;
float vol_left = 1.0; float vol_left = 1.0;
elapsedMicros fill_audio_buffer; elapsedMicros fill_audio_buffer;
elapsedMillis control_rate;
elapsedMillis autostore;
const uint16_t audio_block_time_us = 1000000 / (SAMPLE_RATE / AUDIO_BLOCK_SAMPLES); const uint16_t audio_block_time_us = 1000000 / (SAMPLE_RATE / AUDIO_BLOCK_SAMPLES);
config_t configuration = {0xffff, 0, VOLUME, 0.5f, DEFAULT_MIDI_CHANNEL};
bool eeprom_update_flag = false;
#ifdef SHOW_CPU_LOAD_MSEC #ifdef SHOW_CPU_LOAD_MSEC
elapsedMillis cpu_mem_millis; elapsedMillis cpu_mem_millis;
#endif #endif
enum MDA_EP_PARAM { DECAY, RELEASE, HARDNESS, TREBLE, PAN_TREM, LFO_RATE, VELOCITY_SENSE, STEREO, MAX_POLY, TUNE, DETUNE, OVERDRIVE }; enum MDA_EP_PARAM { DECAY, RELEASE, HARDNESS, TREBLE, PAN_TREM, LFO_RATE, VELOCITY_SENSE, STEREO, MAX_POLY, TUNE, DETUNE, OVERDRIVE };
LiquidLine welcome_line1(1, 0, "MicroMDAEPiano");
LiquidLine welcome_line2(0, 1, "(c)parasiTstudio");
LiquidScreen welcome_screen(welcome_line1, welcome_line2);
LiquidMenu menu(lcd);
//************************************************************************************************* //*************************************************************************************************
//* SETUP FUNCTION //* SETUP FUNCTION
//************************************************************************************************* //*************************************************************************************************
@ -121,17 +122,11 @@ LiquidMenu menu(lcd);
void setup() void setup()
{ {
//while (!Serial) ; // wait for Arduino Serial Monitor //while (!Serial) ; // wait for Arduino Serial Monitor
Serial.begin(SERIAL_SPEED);
delay(220);
// LCD display setup
lcd.init();
lcd.blink_off();
lcd.cursor_off();
lcd.backlight();
lcd.noAutoscroll();
menu.add_screen(welcome_screen); menu_init();
Serial.begin(SERIAL_SPEED);
delay(500);
// Encoder setup // Encoder setup
enc[0].write(INITIAL_ENC_L_VALUE); enc[0].write(INITIAL_ENC_L_VALUE);
@ -165,12 +160,34 @@ void setup()
#ifdef TEENSY_AUDIO_BOARD #ifdef TEENSY_AUDIO_BOARD
sgtl5000_1.enable(); sgtl5000_1.enable();
//sgtl5000_1.dacVolumeRamp(); sgtl5000_1.dacVolumeRamp();
sgtl5000_1.dacVolumeRampLinear(); sgtl5000_1.dacVolume(1.0);
//sgtl5000_1.dacVolumeRampLinear();
sgtl5000_1.unmuteHeadphone(); sgtl5000_1.unmuteHeadphone();
sgtl5000_1.unmuteLineout(); sgtl5000_1.unmuteLineout();
sgtl5000_1.autoVolumeDisable(); // turn off AGC sgtl5000_1.autoVolumeDisable(); // turn off AGC
sgtl5000_1.volume(1.0, 1.0); sgtl5000_1.unmuteHeadphone();
sgtl5000_1.volume(0.5, 0.5); // Headphone volume
sgtl5000_1.lineOutLevel(SGTL5000_LINEOUT_LEVEL);
sgtl5000_1.audioPostProcessorEnable();
sgtl5000_1.autoVolumeControl(1, 1, 1, 0.9, 0.01, 0.05);
sgtl5000_1.autoVolumeEnable();
sgtl5000_1.surroundSoundEnable();
sgtl5000_1.surroundSound(7, 3); // Configures virtual surround width from 0 (mono) to 7 (widest). select may be set to 1 (disable), 2 (mono input) or 3 (stereo input).
sgtl5000_1.enhanceBassEnable();
sgtl5000_1.enhanceBass(1.0, 0.2, 1, 2); // Configures the bass enhancement by setting the levels of the original stereo signal and the bass-enhanced mono level which will be mixed together. The high-pass filter may be enabled (0) or bypassed (1).
/* The cutoff frequency is specified as follows:
value frequency
0 80Hz
1 100Hz
2 125Hz
3 150Hz
4 175Hz
5 200Hz
6 225Hz
*/
//sgtl5000_1.eqBands(bass, mid_bass, midrange, mid_treble, treble);
Serial.println(F("Teensy-Audio-Board enabled."));
#elif defined(TGA_AUDIO_BOARD) #elif defined(TGA_AUDIO_BOARD)
wm8731_1.enable(); wm8731_1.enable();
wm8731_1.volume(1.0); wm8731_1.volume(1.0);
@ -213,10 +230,12 @@ void setup()
mixer_l.gain(1, 0.3); mixer_l.gain(1, 0.3);
AudioInterrupts(); AudioInterrupts();
menu.update();
Serial.println(F("<setup end>")); Serial.println(F("<setup end>"));
menu.next_screen();
menu.update();
#if defined (DEBUG) && defined (SHOW_CPU_LOAD_MSEC) #if defined (DEBUG) && defined (SHOW_CPU_LOAD_MSEC)
show_cpu_and_mem_usage(); show_cpu_and_mem_usage();
cpu_mem_millis = 0; cpu_mem_millis = 0;
@ -287,8 +306,18 @@ void loop()
} }
check_midi_devices(); check_midi_devices();
// CONTROL-RATE-EVENT-HANDLING
if (control_rate > CONTROL_RATE_MS)
{
control_rate = 0;
}
} }
//************************************************************************************************* //*************************************************************************************************
//* PROGRAM FUNCTIONS //* PROGRAM FUNCTIONS
//************************************************************************************************* //*************************************************************************************************
@ -419,106 +448,60 @@ bool checkMidiChannel(byte inChannel)
void set_volume(float v, float vr, float vl) void set_volume(float v, float vr, float vl)
{ {
vol = v; ;
vol_right = vr;
vol_left = vl;
EEPROM.update(EEPROM_OFFSET + EEPROM_MASTER_VOLUME_ADDR, uint8_t(vol * UCHAR_MAX));
EEPROM.update(EEPROM_OFFSET + EEPROM_VOLUME_RIGHT_ADDR, uint8_t(vol_right * UCHAR_MAX));
EEPROM.update(EEPROM_OFFSET + EEPROM_VOLUME_LEFT_ADDR, uint8_t(vol_left * UCHAR_MAX));
update_eeprom_checksum();
#ifdef DEBUG
uint8_t tmp;
Serial.print(F("Setting volume: VOL="));
Serial.print(v, DEC);
Serial.print(F("["));
tmp = EEPROM.read(EEPROM_OFFSET + EEPROM_MASTER_VOLUME_ADDR);
Serial.print(tmp, DEC);
Serial.print(F("/"));
Serial.print(float(tmp) / UCHAR_MAX, DEC);
Serial.print(F("] VOL_L="));
Serial.print(vl, DEC);
Serial.print(F("["));
tmp = EEPROM.read(EEPROM_OFFSET + EEPROM_VOLUME_LEFT_ADDR);
Serial.print(tmp, DEC);
Serial.print(F("/"));
Serial.print(float(tmp) / UCHAR_MAX, DEC);
Serial.print(F("] VOL_R="));
Serial.print(vr, DEC);
Serial.print(F("["));
tmp = EEPROM.read(EEPROM_OFFSET + EEPROM_VOLUME_RIGHT_ADDR);
Serial.print(tmp, DEC);
Serial.print(F("/"));
Serial.print(float(tmp) / UCHAR_MAX, DEC);
Serial.println(F("]"));
#endif
#ifdef TEENSY_AUDIO_BOARD
sgtl5000_1.dacVolume(vol * vol_left, vol * vol_right);
#elif TGA_AUDIO_BOARD
wm8731_1.volume(vol);
#else
volume_r.gain(vr);
volume_l.gain(vl);
#endif
} }
//************************************************************************************************* /******************************************************************************
//* EEPROM FUNCTIONS EEPROM HELPER
//************************************************************************************************* ******************************************************************************/
void initial_values_from_eeprom(void) void initial_values_from_eeprom(void)
{ {
uint32_t crc_eeprom = read_eeprom_checksum(); uint32_t checksum;
uint32_t crc = eeprom_crc32(EEPROM_OFFSET, EEPROM_DATA_LENGTH); config_t tmp_conf;
EEPROM_readAnything(EEPROM_START_ADDRESS, tmp_conf);
checksum = crc32((byte*)&tmp_conf + 4, sizeof(tmp_conf) - 4);
#ifdef DEBUG #ifdef DEBUG
Serial.print(F("EEPROM checksum: 0x")); Serial.print(F("EEPROM checksum: 0x"));
Serial.print(crc_eeprom, HEX); Serial.print(tmp_conf.checksum, HEX);
Serial.print(F(" / 0x")); Serial.print(F(" / 0x"));
Serial.print(crc, HEX); Serial.print(checksum, HEX);
#endif #endif
if (crc_eeprom != crc)
if (checksum != tmp_conf.checksum)
{ {
#ifdef DEBUG #ifdef DEBUG
Serial.print(F(" - mismatch -> initializing EEPROM!")); Serial.print(F(" - mismatch -> initializing EEPROM!"));
#endif #endif
EEPROM.update(EEPROM_OFFSET + EEPROM_MASTER_VOLUME_ADDR, uint8_t(vol * UCHAR_MAX)); eeprom_update();
EEPROM.update(EEPROM_OFFSET + EEPROM_VOLUME_RIGHT_ADDR, uint8_t(vol_right * UCHAR_MAX));
EEPROM.update(EEPROM_OFFSET + EEPROM_VOLUME_LEFT_ADDR, uint8_t(vol_left * UCHAR_MAX));
update_eeprom_checksum();
} }
else else
{ {
vol = float(EEPROM.read(EEPROM_OFFSET + EEPROM_MASTER_VOLUME_ADDR)) / UCHAR_MAX; EEPROM_readAnything(EEPROM_START_ADDRESS, configuration);
vol_right = float(EEPROM.read(EEPROM_OFFSET + EEPROM_VOLUME_RIGHT_ADDR)) / UCHAR_MAX; Serial.print(F(" - OK, loading!"));
vol_left = float(EEPROM.read(EEPROM_OFFSET + EEPROM_VOLUME_LEFT_ADDR)) / UCHAR_MAX;
} }
#ifdef DEBUG #ifdef DEBUG
Serial.println(); Serial.println();
#endif #endif
} }
uint32_t read_eeprom_checksum(void) void eeprom_write(void)
{
return (EEPROM.read(EEPROM_CRC32_ADDR) << 24 | EEPROM.read(EEPROM_CRC32_ADDR + 1) << 16 | EEPROM.read(EEPROM_CRC32_ADDR + 2) << 8 | EEPROM.read(EEPROM_CRC32_ADDR + 3));
}
void update_eeprom_checksum(void)
{ {
write_eeprom_checksum(eeprom_crc32(EEPROM_OFFSET, EEPROM_DATA_LENGTH)); // recalculate crc and write to eeprom autostore = 0;
eeprom_update_flag = true;
} }
void write_eeprom_checksum(uint32_t crc) void eeprom_update(void)
{ {
EEPROM.update(EEPROM_CRC32_ADDR, (crc & 0xff000000) >> 24); eeprom_update_flag = false;
EEPROM.update(EEPROM_CRC32_ADDR + 1, (crc & 0x00ff0000) >> 16); configuration.checksum = crc32((byte*)&configuration + 4, sizeof(configuration) - 4);
EEPROM.update(EEPROM_CRC32_ADDR + 2, (crc & 0x0000ff00) >> 8); EEPROM_writeAnything(EEPROM_START_ADDRESS, configuration);
EEPROM.update(EEPROM_CRC32_ADDR + 3, crc & 0x000000ff); Serial.println(F("Updating EEPROM with configuration data"));
} }
uint32_t eeprom_crc32(uint16_t calc_start, uint16_t calc_bytes) // base code from https://www.arduino.cc/en/Tutorial/EEPROMCrc uint32_t crc32(byte * calc_start, uint16_t calc_bytes) // base code from https://www.arduino.cc/en/Tutorial/EEPROMCrc
{ {
const uint32_t crc_table[16] = const uint32_t crc_table[16] =
{ {
@ -529,20 +512,16 @@ uint32_t eeprom_crc32(uint16_t calc_start, uint16_t calc_bytes) // base code fro
}; };
uint32_t crc = ~0L; uint32_t crc = ~0L;
if (calc_start + calc_bytes > EEPROM.length()) for (byte* index = calc_start ; index < (calc_start + calc_bytes) ; ++index)
calc_bytes = EEPROM.length() - calc_start;
for (uint16_t index = calc_start ; index < (calc_start + calc_bytes) ; ++index)
{ {
crc = crc_table[(crc ^ EEPROM[index]) & 0x0f] ^ (crc >> 4); crc = crc_table[(crc ^ *index) & 0x0f] ^ (crc >> 4);
crc = crc_table[(crc ^ (EEPROM[index] >> 4)) & 0x0f] ^ (crc >> 4); crc = crc_table[(crc ^ (*index >> 4)) & 0x0f] ^ (crc >> 4);
crc = ~crc; crc = ~crc;
} }
return (crc); return (crc);
} }
//************************************************************************************************* //*************************************************************************************************
//* DEBUG FUNCTIONS //* DEBUG FUNCTIONS
//************************************************************************************************* //*************************************************************************************************

@ -1,35 +0,0 @@
/*
MicroMDAEPiano
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
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include "UI.h"
/*
UI::UI()
{
LiquidCrystalPlus_I2C lcd(LCD_I2C_ADDRESS, LCD_CHARS, LCD_LINES);
enc[] = {Encoder4(ENC_L_PIN_A, ENC_L_PIN_B), Encoder4(ENC_R_PIN_A, ENC_R_PIN_B)};
enc_val[] = {INITIAL_ENC_L_VALUE, INITIAL_ENC_R_VALUE};
but[] = {Bounce(BUT_L_PIN, BUT_DEBOUNCE_MS), Bounce(BUT_R_PIN, BUT_DEBOUNCE_MS)};
}
*/

@ -0,0 +1,57 @@
/*
MicroMDAEPiano
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
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <LiquidCrystal_I2C.h>
#include <LiquidMenu.h>
#ifndef UI_HPP_INCLUDED
#define UI_HPP_INCLUDED
extern LiquidCrystal_I2C lcd;
LiquidMenu menu(lcd);
// Welcome screen
LiquidLine welcome_line1(1, 0, "MicroMDAEPiano");
LiquidLine welcome_line2(0, 1, "(c)parasiTstudio");
LiquidScreen welcome_screen(welcome_line1, welcome_line2);
// Welcome screen
LiquidLine main_line1(0, 0, "Volume:");
LiquidLine main_line2(0, 1, "Voice");
LiquidScreen main_screen(main_line1, main_line2);
void menu_init(void)
{
// LCD display setup
lcd.init();
lcd.blink_off();
lcd.cursor_off();
lcd.backlight();
lcd.noAutoscroll();
menu.add_screen(welcome_screen);
menu.add_screen(main_screen);
menu.update();
}
#endif

@ -25,6 +25,7 @@
#define CONFIG_H_INCLUDED #define CONFIG_H_INCLUDED
#include "midinotes.h" #include "midinotes.h"
#include <Arduino.h>
// ATTENTION! For better latency you have to redefine AUDIO_BLOCK_SAMPLES from // ATTENTION! For better latency you have to redefine AUDIO_BLOCK_SAMPLES from
// 128 to 64 in <ARDUINO-IDE-DIR>/cores/teensy3/AudioStream.h // 128 to 64 in <ARDUINO-IDE-DIR>/cores/teensy3/AudioStream.h
@ -102,19 +103,14 @@
#define LCD_LINES 2 #define LCD_LINES 2
// EEPROM address // EEPROM address
#define EEPROM_OFFSET 0 #define EEPROM_START_ADDRESS 0
#define EEPROM_DATA_LENGTH 5
#define EEPROM_CRC32_ADDR EEPROM.length()-sizeof(uint32_t)
#define EEPROM_BANK_ADDR 0
#define EEPROM_VOICE_ADDR 1
#define EEPROM_MASTER_VOLUME_ADDR 2
#define EEPROM_VOLUME_RIGHT_ADDR 3
#define EEPROM_VOLUME_LEFT_ADDR 4
//************************************************************************************************* //*************************************************************************************************
//* DO NO CHANGE ANYTHING BEYOND IF YOU DON'T KNOW WHAT YOU ARE DOING !!! //* DO NO CHANGE ANYTHING BEYOND IF YOU DON'T KNOW WHAT YOU ARE DOING !!!
//************************************************************************************************* //*************************************************************************************************
#define CONTROL_RATE_MS 100
// MIDI // MIDI
#ifdef MIDI_DEVICE_USB #ifdef MIDI_DEVICE_USB
#define USBCON 1 #define USBCON 1
@ -134,4 +130,13 @@
#define NVOICES 32 #define NVOICES 32
#endif #endif
// struct for holding the current configuration
struct config_t {
uint32_t checksum;
uint8_t voice;
float vol;
float pan;
uint8_t midi_channel;
};
#endif #endif

@ -112,6 +112,7 @@ mdaEPiano::mdaEPiano() // mdaEPiano::mdaEPiano(audioMasterCallback audioMaster)
guiUpdate = 0; guiUpdate = 0;
vol = VOLUME;
update(); update();
// suspend(); // suspend();
} }
@ -239,8 +240,8 @@ void mdaEPiano::process(int16_t* outputs_r, int16_t* outputs_l)
l = 1.0; l = 1.0;
else if (l < -1.0) else if (l < -1.0)
l = -1.0; l = -1.0;
outputs_l[frame] = static_cast<int16_t>(l * 0x7fff) >> REDUCE_LOUDNESS; outputs_l[frame] = static_cast<int16_t>(l * vol * 0x7fff) >> REDUCE_LOUDNESS;
outputs_r[frame] = static_cast<int16_t>(r * 0x7fff) >> REDUCE_LOUDNESS; outputs_r[frame] = static_cast<int16_t>(r * vol * 0x7fff) >> REDUCE_LOUDNESS;
} }
if (fabs(tl) < 1.0e-10) tl = 0.0f; //anti-denormal if (fabs(tl) < 1.0e-10) tl = 0.0f; //anti-denormal

@ -108,7 +108,7 @@ class mdaEPiano
float treb, tfrq, tl, tr; float treb, tfrq, tl, tr;
float tune, fine, random, stretch, overdrive; float tune, fine, random, stretch, overdrive;
float muff, muffvel, sizevel, velsens, volume, modwhl; float muff, muffvel, sizevel, velsens, volume, modwhl;
float vol;
uint8_t curProgram; uint8_t curProgram;
}; };

Loading…
Cancel
Save