Code cleanup and added xfade utility and data.

chorus
Holger Wirtz 6 years ago
parent 42f309ea0e
commit 0167c9acc7
  1. 278
      MicroMDAEPiano.ino
  2. 4
      config.h
  3. 42
      mdaEPiano.cpp
  4. 22
      mdaEPiano.h
  5. 2
      mdaEPianoData.h
  6. 21125
      mdaEPianoDataXfade.h
  7. 9
      utility/gen_xfade.sh
  8. 100
      utility/xfade_generator.c

@ -26,12 +26,12 @@
#include <Audio.h> #include <Audio.h>
#include <Wire.h> #include <Wire.h>
#include <SPI.h> #include <SPI.h>
#include <SD.h>
#include <MIDI.h> #include <MIDI.h>
#include <EEPROM.h> #include <EEPROM.h>
#include <limits.h> #include <limits.h>
#include "mdaEPiano.h" #include "mdaEPiano.h"
#include "mdaEPianoData.h" //#include "mdaEPianoData.h"
#include "mdaEPianoDataXfade.h"
#if defined(USBCON) #if defined(USBCON)
#include <midi_UsbTransport.h> #include <midi_UsbTransport.h>
#endif #endif
@ -44,7 +44,6 @@
#include "LiquidCrystalPlus_I2C.h" #include "LiquidCrystalPlus_I2C.h"
#endif #endif
#ifndef MASTER_KEY_MIDI
// [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
#define LCD_CHARS 16 #define LCD_CHARS 16
@ -52,52 +51,44 @@
LiquidCrystalPlus_I2C lcd(LCD_I2C_ADDRESS, LCD_CHARS, LCD_LINES); LiquidCrystalPlus_I2C lcd(LCD_I2C_ADDRESS, LCD_CHARS, LCD_LINES);
Encoder enc1(ENC1_PIN_A, ENC1_PIN_B); 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
#endif
// GUItool: begin automatically generated code // GUItool: begin automatically generated code
AudioPlayQueue queue_r; //xy=494,404 AudioPlayQueue queue_r; //xy=494,404
AudioPlayQueue queue_l; //xy=494,404 AudioPlayQueue queue_l; //xy=494,404
AudioAnalyzePeak peak_r; //xy=695,491 AudioAnalyzePeak peak_r; //xy=695,491
AudioAnalyzePeak peak_l; //xy=695,491 AudioAnalyzePeak peak_l; //xy=695,491
AudioConnection patchCord0(queue_l, peak_l);
AudioConnection patchCord1(queue_r, peak_r);
#ifdef TEENSY_AUDIO_BOARD #ifdef TEENSY_AUDIO_BOARD
AudioOutputI2S i2s1; //xy=1072,364 AudioOutputI2S i2s1; //xy=1072,364
AudioConnection patchCord1(queue_r, peak_r); AudioConnection patchCord2(queue_l, 0, i2s1, 0);
AudioConnection patchCord2(queue_l, peak_l); AudioConnection patchCord3(queue_r, 0, i2s1, 1);
AudioConnection patchCord3(queue_r, 0, i2s1, 0);
AudioConnection patchCord4(queue_l, 0, i2s1, 1);
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
AudioConnection patchCord1(queue_r, volume_r); AudioConnection patchCord2(queue_l, volume_r);
AudioConnection patchCord2(queue_l, volume_l); AudioConnection patchCord3(queue_r, volume_l);
AudioConnection patchCord3(volume_r, peak_r); AudioConnection patchCord4(volume_r, peak_r);
AudioConnection patchCord4(volume_l, peak_l); AudioConnection patchCord5(volume_l, peak_l);
AudioConnection patchCord5(volume_r, 0, pt8211_1, 1); AudioConnection patchCord6(volume_r, 0, pt8211_1, 1);
AudioConnection patchCord6(volume_l, 0, pt8211_1, 0); AudioConnection patchCord7(volume_l, 0, pt8211_1, 0);
#endif #endif
// GUItool: end automatically generated code // GUItool: end automatically generated code
mdaEPiano* ep; mdaEPiano* ep;
bool sd_card_available = false;
uint8_t midi_channel = DEFAULT_MIDI_CHANNEL; 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;
uint16_t render_time_max = 0; uint16_t render_time_max = 0;
uint8_t bank = 0;
uint8_t voice = 0;
float vol = VOLUME; 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;
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);
#ifdef MASTER_KEY_MIDI
bool master_key_enabled = false;
#endif
#ifdef SHOW_CPU_LOAD_MSEC #ifdef SHOW_CPU_LOAD_MSEC
elapsedMillis cpu_mem_millis; elapsedMillis cpu_mem_millis;
#endif #endif
@ -129,7 +120,6 @@ void setup()
//while (!Serial) ; // wait for Arduino Serial Monitor //while (!Serial) ; // wait for Arduino Serial Monitor
Serial.begin(SERIAL_SPEED); Serial.begin(SERIAL_SPEED);
delay(220); delay(220);
#ifndef MASTER_KEY_MIDI
lcd.init(); lcd.init();
lcd.blink_off(); lcd.blink_off();
lcd.cursor_off(); lcd.cursor_off();
@ -140,13 +130,12 @@ void setup()
lcd.show(0, 0, 20, " MicroMDAEPiano"); lcd.show(0, 0, 20, " MicroMDAEPiano");
lcd.show(1, 0, 16, "(c)parasiTstudio"); lcd.show(1, 0, 16, "(c)parasiTstudio");
enc1.write(INITIAL_ENC1_VALUE); enc1.write(INITIAL_ENC1_VALUE);
#endif
Serial.println(F("MicroMDAEPiano based on https://sourceforge.net/projects/mda-vst")); Serial.println(F("MicroMDAEPiano based on https://sourceforge.net/projects/mda-vst"));
Serial.println(F("(c)2018 H. Wirtz <wirtz@parasitstudio.de>")); Serial.println(F("(c)2018 H. Wirtz <wirtz@parasitstudio.de>"));
Serial.println(F("https://about.teahub.io/dcoredump/MicroMDAEpiano")); Serial.println(F("https://about.teahub.io/dcoredump/MicroMDAEpiano"));
Serial.print(F("Data in PROGMEM: ")); Serial.print(F("Data in PROGMEM: "));
Serial.print(sizeof(epianoData), DEC); Serial.print(sizeof(epianoDataXfade), DEC);
Serial.println(F(" bytes")); Serial.println(F(" bytes"));
Serial.println(); Serial.println();
Serial.println(F("<setup start>")); Serial.println(F("<setup start>"));
@ -175,6 +164,7 @@ void setup()
// start audio card // start audio card
AudioMemory(AUDIO_MEM); AudioMemory(AUDIO_MEM);
#ifdef TEENSY_AUDIO_BOARD #ifdef TEENSY_AUDIO_BOARD
sgtl5000_1.enable(); sgtl5000_1.enable();
//sgtl5000_1.dacVolumeRamp(); //sgtl5000_1.dacVolumeRamp();
@ -187,19 +177,6 @@ void setup()
set_volume(vol, vol_left, vol_right); set_volume(vol, vol_left, vol_right);
// start SD card
SPI.setMOSI(SDCARD_MOSI_PIN);
SPI.setSCK(SDCARD_SCK_PIN);
if (!SD.begin(SDCARD_CS_PIN))
{
Serial.println(F("SD card not accessable"));
}
else
{
Serial.println(F("SD card found."));
sd_card_available = true;
}
#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
AudioProcessorUsageMaxReset(); AudioProcessorUsageMaxReset();
@ -238,8 +215,8 @@ void setup()
void loop() void loop()
{ {
int16_t* audio_buffer_r; // pointer to AUDIO_BLOCK_SAMPLES * int16_t int16_t* audio_buffer_r; // pointer to AUDIO_BLOCK_SAMPLES * sizeof(int16_t)
int16_t* audio_buffer_l; // pointer to AUDIO_BLOCK_SAMPLES * int16_t int16_t* audio_buffer_l; // pointer to AUDIO_BLOCK_SAMPLES * sizeof(int16_t)
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
@ -333,14 +310,12 @@ void handle_input(void)
} }
#endif #endif
#ifndef MASTER_KEY_MIDI
int enc1_val = enc1.read(); int enc1_val = enc1.read();
if (but1.update()) if (but1.update())
; ;
// place handling of encoder and showing values on lcd here // place handling of encoder and showing values on lcd here
#endif
} }
#ifdef DEBUG #ifdef DEBUG
@ -364,69 +339,6 @@ void print_midi_event(uint8_t type, uint8_t data1, uint8_t data2)
#endif #endif
#endif #endif
#ifdef MASTER_KEY_MIDI
bool handle_master_key(uint8_t data)
{
int8_t num = num_key_base_c(data);
#ifdef DEBUG
Serial.print(F("Master-Key: "));
Serial.println(num, DEC);
#endif
if (num > 0)
{
// a white key!
if (num <= 32)
{
if (load_sysex(bank, num))
{
#ifdef DEBUG
Serial.print(F("Loading voice number "));
Serial.println(num, DEC);
#endif
EEPROM.update(EEPROM_OFFSET + EEPROM_VOICE_ADDR, num);
update_eeprom_checksum();
}
#ifdef DEBUG
else
{
Serial.print(F("E: cannot load voice number "));
Serial.println(num, DEC);
}
#endif
}
return (true);
}
else
{
// a black key!
num = abs(num);
if (num <= 10)
{
set_volume(float(num * 0.1), vol_left, vol_right);
}
else if (num > 10 && num <= 20)
{
bank = num - 10;
EEPROM.update(EEPROM_OFFSET + EEPROM_BANK_ADDR, bank);
update_eeprom_checksum();
#ifdef DEBUG
Serial.print(F("Bank switch to: "));
Serial.println(bank, DEC);
#endif
return (true);
}
}
return (false);
}
#endif
bool load_sysex(uint8_t bank, uint8_t num)
{
return (true);
}
bool queue_midi_event(uint8_t type, uint8_t data1, uint8_t data2) bool queue_midi_event(uint8_t type, uint8_t data1, uint8_t data2)
{ {
bool ret = false; bool ret = false;
@ -455,94 +367,11 @@ bool queue_midi_event(uint8_t type, uint8_t data1, uint8_t data2)
// now throw away the MIDI channel information // now throw away the MIDI channel information
type &= 0xf0; type &= 0xf0;
#ifdef MASTER_KEY_MIDI ret = ep->processMidiMessage(type, data1, data2);
if (type == 0x80 && data1 == MASTER_KEY_MIDI) // Master key released
{
master_key_enabled = false;
#ifdef DEBUG
Serial.println(F("Master key disabled"));
#endif
}
else if (type == 0x90 && data1 == MASTER_KEY_MIDI) // Master key pressed
{
master_key_enabled = true;
#ifdef DEBUG
Serial.println(F("Master key enabled"));
#endif
}
else
{
if (master_key_enabled)
{
if (type == 0x80) // handle when note is released
{
//dexed->notesOff();
handle_master_key(data1);
}
}
else
#endif
ret = ep->processMidiMessage(type, data1, data2);
#ifdef MASTER_KEY_MIDI
}
#endif
return (ret); return (ret);
} }
#ifdef MASTER_KEY_MIDI
int8_t num_key_base_c(uint8_t midi_note)
{
int8_t num = 0;
switch (midi_note % 12)
{
// positive numbers are white keys, negative black ones
case 0:
num = 1;
break;
case 1:
num = -1;
break;
case 2:
num = 2;
break;
case 3:
num = -2;
break;
case 4:
num = 3;
break;
case 5:
num = 4;
break;
case 6:
num = -3;
break;
case 7:
num = 5;
break;
case 8:
num = -4;
break;
case 9:
num = 6;
break;
case 10:
num = -5;
break;
case 11:
num = 7;
break;
}
if (num > 0)
return (num + (((midi_note - MASTER_NUM1) / 12) * 7));
else
return (num + ((((midi_note - MASTER_NUM1) / 12) * 5) * -1));
}
#endif
void set_volume(float v, float vr, float vl) void set_volume(float v, float vr, float vl)
{ {
vol = v; vol = v;
@ -588,73 +417,6 @@ void set_volume(float v, float vr, float vl)
#endif #endif
} }
/*
void handle_sysex_parameter(const uint8_t* sysex, uint8_t len)
{
if (sysex[1] != 0x43) // check for Yamaha sysex
{
#ifdef DEBUG
Serial.println(F("E: SysEx vendor not Yamaha."));
#endif
return;
}
// parse parameter change
if (len == 7)
{
if ((sysex[3] & 0x7c) != 0 || (sysex[3] & 0x7c) != 2)
{
#ifdef DEBUG
Serial.println(F("E: Not a SysEx parameter or function parameter change."));
#endif
return;
}
if (sysex[6] != 0xf7)
{
#ifdef DEBUG
Serial.println(F("E: SysEx end status byte not detected."));
#endif
return;
}
if ((sysex[3] & 0x7c) == 0)
{
dexed->data[sysex[4]] = sysex[5]; // set parameter
dexed->doRefreshVoice();
}
else
{
dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET - 63 + sysex[4]] = sysex[5]; // set function parameter
dexed->controllers.values_[kControllerPitchRange] = dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_PITCHBEND_RANGE];
dexed->controllers.values_[kControllerPitchStep] = dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_PITCHBEND_STEP];
dexed->controllers.wheel.setRange(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_MODWHEEL_RANGE]);
dexed->controllers.wheel.setTarget(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_MODWHEEL_ASSIGN]);
dexed->controllers.foot.setRange(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_FOOTCTRL_RANGE]);
dexed->controllers.foot.setTarget(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_FOOTCTRL_ASSIGN]);
dexed->controllers.breath.setRange(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_BREATHCTRL_RANGE]);
dexed->controllers.breath.setTarget(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_BREATHCTRL_ASSIGN]);
dexed->controllers.at.setRange(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_AT_RANGE]);
dexed->controllers.at.setTarget(dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_AT_ASSIGN]);
dexed->controllers.masterTune = (dexed->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_MASTER_TUNE] * 0x4000 << 11) * (1.0 / 12);
dexed->controllers.refresh();
}
#ifdef DEBUG
Serial.print(F("SysEx"));
if ((sysex[3] & 0x7c) == 0)
Serial.print(F(" function"));
Serial.print(F(" parameter "));
Serial.print(sysex[4], DEC);
Serial.print(F(" = "));
Serial.println(sysex[5], DEC);
#endif
}
#ifdef DEBUG
else
Serial.println(F("E: SysEx parameter length wrong."));
#endif
}
*/
void initial_values_from_eeprom(void) void initial_values_from_eeprom(void)
{ {
uint32_t crc_eeprom = read_eeprom_checksum(); uint32_t crc_eeprom = read_eeprom_checksum();
@ -671,8 +433,6 @@ void initial_values_from_eeprom(void)
#ifdef DEBUG #ifdef DEBUG
Serial.print(F(" - mismatch -> initializing EEPROM!")); Serial.print(F(" - mismatch -> initializing EEPROM!"));
#endif #endif
EEPROM.update(EEPROM_OFFSET + EEPROM_BANK_ADDR, bank);
EEPROM.update(EEPROM_OFFSET + EEPROM_VOICE_ADDR, voice);
EEPROM.update(EEPROM_OFFSET + EEPROM_MASTER_VOLUME_ADDR, uint8_t(vol * UCHAR_MAX)); 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_RIGHT_ADDR, uint8_t(vol_right * UCHAR_MAX));
EEPROM.update(EEPROM_OFFSET + EEPROM_VOLUME_LEFT_ADDR, uint8_t(vol_left * UCHAR_MAX)); EEPROM.update(EEPROM_OFFSET + EEPROM_VOLUME_LEFT_ADDR, uint8_t(vol_left * UCHAR_MAX));
@ -680,8 +440,6 @@ void initial_values_from_eeprom(void)
} }
else else
{ {
bank = EEPROM.read(EEPROM_OFFSET + EEPROM_BANK_ADDR);
voice = EEPROM.read(EEPROM_OFFSET + EEPROM_VOICE_ADDR);
vol = float(EEPROM.read(EEPROM_OFFSET + EEPROM_MASTER_VOLUME_ADDR)) / UCHAR_MAX; vol = float(EEPROM.read(EEPROM_OFFSET + EEPROM_MASTER_VOLUME_ADDR)) / UCHAR_MAX;
vol_right = float(EEPROM.read(EEPROM_OFFSET + EEPROM_VOLUME_RIGHT_ADDR)) / UCHAR_MAX; vol_right = float(EEPROM.read(EEPROM_OFFSET + EEPROM_VOLUME_RIGHT_ADDR)) / UCHAR_MAX;
vol_left = float(EEPROM.read(EEPROM_OFFSET + EEPROM_VOLUME_LEFT_ADDR)) / UCHAR_MAX; vol_left = float(EEPROM.read(EEPROM_OFFSET + EEPROM_VOLUME_LEFT_ADDR)) / UCHAR_MAX;

@ -47,10 +47,6 @@
#define USBCON 1 // enabling onboard MIDI via programing connector #define USBCON 1 // enabling onboard MIDI via programing connector
#define MIDI_MERGE_THRU 1 #define MIDI_MERGE_THRU 1
// Master key handling (comment for disabling)
//#define MASTER_KEY_MIDI MIDI_C7
#define MASTER_NUM1 MIDI_C2
// Debug output // Debug output
#define SERIAL_SPEED 38400 #define SERIAL_SPEED 38400
#define DEBUG 1 #define DEBUG 1

@ -1,4 +1,4 @@
#include "mdaEPianoData.h" #include "mdaEPianoDataXfade.h"
#include "mdaEPiano.h" #include "mdaEPiano.h"
#include <stdio.h> #include <stdio.h>
@ -6,11 +6,6 @@
#include "config.h" #include "config.h"
// AudioEffect *createEffectInstance(audioMasterCallback audioMaster)
//{
// return new mdaEPiano(audioMaster);
//}
mdaEPiano::mdaEPiano() // mdaEPiano::mdaEPiano(audioMasterCallback audioMaster) : AudioEffectX(audioMaster, NPROGS, NPARAMS) mdaEPiano::mdaEPiano() // mdaEPiano::mdaEPiano(audioMasterCallback audioMaster) : AudioEffectX(audioMaster, NPROGS, NPARAMS)
{ {
Fs = SAMPLE_RATE; iFs = 1.0f / Fs; //just in case... Fs = SAMPLE_RATE; iFs = 1.0f / Fs; //just in case...
@ -30,18 +25,8 @@ 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;
if(audioMaster)
{
setNumInputs(0);
setNumOutputs(NOUTS);
canProcessReplacing();
isSynth();
setUniqueID('MDAe'); ///
}
*/
waves = (short*)epianoData;
//Waveform data and keymapping //Waveform data and keymapping
kgrp[ 0].root = 36; kgrp[ 0].high = 39; //C1 kgrp[ 0].root = 36; kgrp[ 0].high = 39; //C1
@ -90,27 +75,6 @@ mdaEPiano::mdaEPiano() // mdaEPiano::mdaEPiano(audioMasterCallback audioMaster)
kgrp[31].pos = 406046; kgrp[31].end = 414486; kgrp[31].loop = 2306; //ghost kgrp[31].pos = 406046; kgrp[31].end = 414486; kgrp[31].loop = 2306; //ghost
kgrp[32].pos = 414487; kgrp[32].end = 422408; kgrp[32].loop = 2169; kgrp[32].pos = 414487; kgrp[32].end = 422408; kgrp[32].loop = 2169;
/*
//extra xfade looping...
for (int32_t k = 0; k < 28; k++)
{
int32_t p0 = kgrp[k].end;
int32_t p1 = kgrp[k].end - kgrp[k].loop;
float xf = 1.0f;
float dxf = -0.02f;
while (xf > 0.0f)
{
waves[p0] = (short)((1.0f - xf) * (float)waves[p0] + xf * (float)waves[p1]);
p0--;
p1--;
xf += dxf;
}
}
*/
//initialise... //initialise...
for (int32_t v = 0; v < NVOICES; v++) for (int32_t v = 0; v < NVOICES; v++)
{ {

@ -24,7 +24,6 @@ private:
char name[24]; char name[24];
}; };
struct VOICE //voice state struct VOICE //voice state
{ {
int32_t delta; //sample playback int32_t delta; //sample playback
@ -58,33 +57,16 @@ 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(int16_t *outputs_r, int16_t *outputs_l); virtual void process(int16_t *outputs_r, int16_t *outputs_l);
virtual bool processMidiMessage(uint8_t type, uint8_t data1, uint8_t data2); virtual bool processMidiMessage(uint8_t type, uint8_t data1, uint8_t data2);
virtual void setProgram(int32_t program); virtual void setProgram(int32_t program);
//virtual void setProgramName(char *name);
//virtual void getProgramName(char *name);
virtual void setParameter(int32_t index, float value); virtual void setParameter(int32_t index, float value);
virtual float getParameter(int32_t index); virtual float getParameter(int32_t index);
//virtual void getParameterLabel(int32_t index, char *label);
//virtual void getParameterDisplay(int32_t index, char *text);
//virtual void getParameterName(int32_t index, char *text);
//virtual void setBlockSize(int32_t blockSize);
virtual void resume(); virtual void resume();
//virtual bool getOutputProperties (int32_t index); // virtual bool getOutputProperties (int32_t index, VstPinProperties* properties);
//virtual bool getProgramNameIndexed (int32_t category, int32_t index, char* text);
//virtual bool copyProgram (int32_t destination);
//virtual bool getEffectName (char* name);
//virtual bool getVendorString (char* text);
//virtual bool getProductString (char* text);
//virtual int32_t getVendorVersion () {return 1;}
//virtual int32_t canDo (char* text);
virtual int32_t getNumMidiInputChannels () { return 1; }
int32_t guiUpdate; int32_t guiUpdate;
void guiGetDisplay(int32_t index, char *label); void guiGetDisplay(int32_t index, char *label);

@ -21121,5 +21121,5 @@ const int16_t epianoData[] PROGMEM = {
-2448,-435,1671,3543,4870,5423,5075,3868,1992,-214,-2355,-4061,-5043,-5162,-4423,-2962,-1026,1085,3051,4551, -2448,-435,1671,3543,4870,5423,5075,3868,1992,-214,-2355,-4061,-5043,-5162,-4423,-2962,-1026,1085,3051,4551,
5334,5232,4234,2513,358,-1851,-3703,-4896,-5255,-4741,-3460,-1633,459,2486,4148,5150,5289,4538,2992,920, 5334,5232,4234,2513,358,-1851,-3703,-4896,-5255,-4741,-3460,-1633,459,2486,4148,5150,5289,4538,2992,920,
-1302,-3296,-4700,-5297,-5021,-3939,-2233,-189,1899,3696,4890,5299,4788,3436,1466,-757,-2846,-4450,-5294,-5248, -1302,-3296,-4700,-5297,-5021,-3939,-2233,-189,1899,3696,4890,5299,4788,3436,1466,-757,-2846,-4450,-5294,-5248,
-4377,-2810,-829,1280,3190,4588,5216,4960,3821,0,1,1,0,-1,0,0,0,0, -4377,-2810,-829,1280,3190,4588,5216,4960,3821,0,1,1,0,-1,0,0,0,0
}; };

File diff suppressed because it is too large Load Diff

@ -0,0 +1,9 @@
#!/bin/bash
sed -e 's/^.\+Arduino\.h.\+$/#include <stdint.h>/' ../mdaEPianoData.h >mdaEPianoData.h
sed -i 's/PROGMEM//' mdaEPianoData.h
sed -i 's/const//' mdaEPianoData.h
gcc -o xfade_generator xfade_generator.c
rm mdaEPianoData.h
./xfade_generator >../mdaEPianoData_xfade.h
rm xfade_generator

@ -0,0 +1,100 @@
#include "mdaEPianoData.h"
#include <stdio.h>
#include <math.h>
#include <stdint.h>
struct KGRP //keygroup
{
int32_t root; //MIDI root note
int32_t high; //highest note
int32_t pos;
int32_t end;
int32_t loop;
};
void main(void)
{
struct KGRP kgrp[34];
int16_t *waves = (int16_t*)epianoData;
//Waveform data and keymapping
kgrp[ 0].root = 36; kgrp[ 0].high = 39; //C1
kgrp[ 3].root = 43; kgrp[ 3].high = 45; //G1
kgrp[ 6].root = 48; kgrp[ 6].high = 51; //C2
kgrp[ 9].root = 55; kgrp[ 9].high = 57; //G2
kgrp[12].root = 60; kgrp[12].high = 63; //C3
kgrp[15].root = 67; kgrp[15].high = 69; //G3
kgrp[18].root = 72; kgrp[18].high = 75; //C4
kgrp[21].root = 79; kgrp[21].high = 81; //G4
kgrp[24].root = 84; kgrp[24].high = 87; //C5
kgrp[27].root = 91; kgrp[27].high = 93; //G5
kgrp[30].root = 96; kgrp[30].high = 999; //C6
kgrp[0].pos = 0; kgrp[0].end = 8476; kgrp[0].loop = 4400;
kgrp[1].pos = 8477; kgrp[1].end = 16248; kgrp[1].loop = 4903;
kgrp[2].pos = 16249; kgrp[2].end = 34565; kgrp[2].loop = 6398;
kgrp[3].pos = 34566; kgrp[3].end = 41384; kgrp[3].loop = 3938;
kgrp[4].pos = 41385; kgrp[4].end = 45760; kgrp[4].loop = 1633; //was 1636;
kgrp[5].pos = 45761; kgrp[5].end = 65211; kgrp[5].loop = 5245;
kgrp[6].pos = 65212; kgrp[6].end = 72897; kgrp[6].loop = 2937;
kgrp[7].pos = 72898; kgrp[7].end = 78626; kgrp[7].loop = 2203; //was 2204;
kgrp[8].pos = 78627; kgrp[8].end = 100387; kgrp[8].loop = 6368;
kgrp[9].pos = 100388; kgrp[9].end = 116297; kgrp[9].loop = 10452;
kgrp[10].pos = 116298; kgrp[10].end = 127661; kgrp[10].loop = 5217; //was 5220;
kgrp[11].pos = 127662; kgrp[11].end = 144113; kgrp[11].loop = 3099;
kgrp[12].pos = 144114; kgrp[12].end = 152863; kgrp[12].loop = 4284;
kgrp[13].pos = 152864; kgrp[13].end = 173107; kgrp[13].loop = 3916;
kgrp[14].pos = 173108; kgrp[14].end = 192734; kgrp[14].loop = 2937;
kgrp[15].pos = 192735; kgrp[15].end = 204598; kgrp[15].loop = 4732;
kgrp[16].pos = 204599; kgrp[16].end = 218995; kgrp[16].loop = 4733;
kgrp[17].pos = 218996; kgrp[17].end = 233801; kgrp[17].loop = 2285;
kgrp[18].pos = 233802; kgrp[18].end = 248011; kgrp[18].loop = 4098;
kgrp[19].pos = 248012; kgrp[19].end = 265287; kgrp[19].loop = 4099;
kgrp[20].pos = 265288; kgrp[20].end = 282255; kgrp[20].loop = 3609;
kgrp[21].pos = 282256; kgrp[21].end = 293776; kgrp[21].loop = 2446;
kgrp[22].pos = 293777; kgrp[22].end = 312566; kgrp[22].loop = 6278;
kgrp[23].pos = 312567; kgrp[23].end = 330200; kgrp[23].loop = 2283;
kgrp[24].pos = 330201; kgrp[24].end = 348889; kgrp[24].loop = 2689;
kgrp[25].pos = 348890; kgrp[25].end = 365675; kgrp[25].loop = 4370;
kgrp[26].pos = 365676; kgrp[26].end = 383661; kgrp[26].loop = 5225;
kgrp[27].pos = 383662; kgrp[27].end = 393372; kgrp[27].loop = 2811;
kgrp[28].pos = 383662; kgrp[28].end = 393372; kgrp[28].loop = 2811; //ghost
kgrp[29].pos = 393373; kgrp[29].end = 406045; kgrp[29].loop = 4522;
kgrp[30].pos = 406046; kgrp[30].end = 414486; kgrp[30].loop = 2306;
kgrp[31].pos = 406046; kgrp[31].end = 414486; kgrp[31].loop = 2306; //ghost
kgrp[32].pos = 414487; kgrp[32].end = 422408; kgrp[32].loop = 2169;
//extra xfade looping...
for (int32_t k = 0; k < 28; k++)
{
int32_t p0 = kgrp[k].end;
int32_t p1 = kgrp[k].end - kgrp[k].loop;
float xf = 1.0f;
float dxf = -0.02f;
while (xf > 0.0f)
{
waves[p0] = (int16_t)((1.0f - xf) * (float)waves[p0] + xf * (float)waves[p1]);
p0--;
p1--;
xf += dxf;
}
}
// output
printf("#include <Arduino.h>\n\n");
printf("const int16_t epianoDataXfade[] PROGMEM = {\n");
for(uint32_t z=0; z<(844836/sizeof(int16_t)); z=z+20)
{
for(uint32_t i=0;i<20;i++)
{
if(z+i>=(uint32_t)(844836/sizeof(int16_t)))
break;
printf("%d,",waves[z+i]);
if(i>=19)
printf("\n");
}
}
printf("\n};\n");
}
Loading…
Cancel
Save