I have also asked here: https://community.platformio.org/t/teensy-debug-builds-teensy-fails-to-start/31297
//********************************************************************
// Sammy Polyhonic DIY Sampler (Degnerator 2)
// (c) Rolf Degen 11.2024 Version 1.00-01
// Teensy 4.1 600MHz
//********************************************************************
#include <Arduino.h>
#include "Audio.h"
#include <MIDI.h>
#include <SD.h>
#include <Wire.h>
#include <avr/interrupt.h>
#include "SPI.h"
#include "TeensyVariablePlayback.h"
#include "flashloader.h"
#include "ILI9341_t3n.h"
// #include <ILI9341_t4.h>
#include "Font/font_DroidSans.h"
#include "Adafruit_FT6206.h"
#include "touch_button.h"
#include "config.h"
#include "screensaver.h"
#include "GUI.h"
#include "filemanager.h"
#include "audioPatching.h"
#include "ILI9341_t3_PrintScreen.h"
#include "Font/font_LiberationSans.h"
extern "C" uint8_t external_psram_size;
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);
const int Midi_channel = 1;
// Initialize tft display
DMAMEM uint16_t screenBuffer[320 * 240];
ILI9341_t3n tft(TFT_CS, TFT_DC, TFT_RST, TFT_MOSI, TFT_SCK, TFT_MISO);
// The FT6206 (touch pannel) uses hardware I2C (SCL/SDA)
Adafruit_FT6206 ts = Adafruit_FT6206();
// Rotary encoder
#define encoder1_addr 48
#define encoder2_addr 49
#define encoder3_addr 50
#define encoder4_addr 51
#define encoder5_addr 52
#define encoder6_addr 53
#define PIN_ENC_INT 25
// Menu pages
#define Program_Menu 0
#define Osc_Menu 1
#define Filter_Menu 2
#define Envelope_menu 3
int16_t value;
boolean pressed, lastpressed;
int encoder_addr = 48; // First encoder adrdress
boolean enc_action;
int encoder_last_value[6][6] = {
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0}};
int ampEnvValue[6] = {0, 0, 0, 0, 127, 40};
// Envelope Times
const uint32_t ENVTIMES[128] PROGMEM =
{0, 1, 2, 3, 4, 6, 10, 16, 33, 41, 49,
58, 67, 78, 89, 99, 111, 124, 136, 150, 164, 178, 192, 209, 224, 241,
258, 276, 295, 314, 333, 353, 374, 395, 418, 440, 464, 489, 513, 539,
565, 592, 621, 650, 680, 710, 742, 774, 808, 843, 878, 915, 952, 991,
1031, 1073, 1114, 1158, 1202, 1250, 1297, 1346, 1396, 1448, 1502, 1558,
1614, 1676, 1735, 1794, 1864, 1923, 1994, 2065, 2136, 2207, 2289, 2360,
2443, 2525, 2620, 2702, 2797, 2891, 2985, 3092, 3186, 3292, 3410, 3516,
3634, 3752, 3882, 4012, 4142, 4272, 4413, 4567, 4708, 4862, 5027, 5180,
5357, 5522, 5699, 5888, 6077, 6278, 6478, 6691, 6903, 7127, 7351, 7587,
7835, 8083, 8343, 8614, 8885, 9169, 9464, 9770, 10077, 10408, 10738,
11080, 11434, 11880};
// Linear Original
const float LINEAR[128] PROGMEM =
{0, 0.008, 0.016, 0.024, 0.031, 0.039,
0.047, 0.055, 0.063, 0.071, 0.079, 0.087, 0.094, 0.102, 0.11, 0.118,
0.126, 0.134, 0.142, 0.15, 0.157, 0.165, 0.173, 0.181, 0.189, 0.197,
0.205, 0.213, 0.22, 0.228, 0.236, 0.244, 0.252, 0.26, 0.268, 0.276,
0.283, 0.291, 0.299, 0.307, 0.315, 0.323, 0.331, 0.339, 0.346, 0.354,
0.362, 0.37, 0.378, 0.386, 0.394, 0.402, 0.409, 0.417, 0.425, 0.433,
0.441, 0.449, 0.457, 0.465, 0.472, 0.48, 0.488, 0.496, 0.504, 0.512,
0.52, 0.528, 0.535, 0.543, 0.551, 0.559, 0.567, 0.575, 0.583, 0.591,
0.598, 0.606, 0.614, 0.622, 0.63, 0.638, 0.646, 0.654, 0.661, 0.669,
0.677, 0.685, 0.693, 0.701, 0.709, 0.717, 0.724, 0.732, 0.74, 0.748,
0.756, 0.764, 0.772, 0.78, 0.787, 0.795, 0.803, 0.811, 0.819, 0.827,
0.835, 0.843, 0.85, 0.858, 0.866, 0.874, 0.882, 0.89, 0.898, 0.906,
0.913, 0.921, 0.929, 0.937, 0.945, 0.953, 0.961, 0.969, 0.976, 0.984,
0.992, 1.00};
unsigned long lastSamplePlayed = 0;
uint8_t channels = 2;
newdigate::audiosample *Sample;
boolean sample_busy_flag;
elapsedMillis screensaverTimer = 0;
elapsedMillis touchReadTimer = 0;
elapsedMillis screensaverResetTimer = 0;
elapsedMillis rotaryEncoder0_Timer = 0;
elapsedMillis rotaryEncoder1_Timer = 0;
elapsedMillis rotaryEncoder2_Timer = 0;
elapsedMillis rotaryEncoder3_Timer = 0;
elapsedMillis rotaryEncoder4_Timer = 0;
elapsedMillis rotaryEncoder5_Timer = 0;
elapsedMillis Task_Timer = 0;
elapsedMillis midiSymbolTimer = 0;
boolean screensaver_Active = false;
uint8_t touch_index = 0;
int pageNo = 0;
int old_pageNo = 0;
extern boolean TK_state_List_P1[6];
uint16_t loopCount = 0;
uint8_t midiSymbol_status = false;
uint8_t voiceMode = 0; // 0=poly mode 1= unsison
// Voice
struct VoiceAndNote
{
int note;
long timeOn;
int voiceOn;
};
struct VoiceAndNote voices[NO_OF_VOICES] = {{-1, 0, 0}, {-1, 0, 0}, {-1, 0, 0}, {-1, 0, 0}, {-1, 0, 0}, {-1, 0, 0}, {-1, 0, 0}, {-1, 0, 0}};
int voiceToReturn = -1;
long earliestTime = millis(); // For voice allocation - initialise to now
// Set encoder wheel parameters
void encoder_set(uint8_t encoder_addr, int16_t rmin, int16_t rmax, int16_t rstep, int16_t rval, uint8_t rloop)
{
Wire1.beginTransmission(encoder_addr);
Wire1.write((uint8_t)(rval & 0xff));
Wire1.write((uint8_t)(rval >> 8));
Wire1.write(0);
Wire1.write(rloop);
Wire1.write((uint8_t)(rmin & 0xff));
Wire1.write((uint8_t)(rmin >> 8));
Wire1.write((uint8_t)(rmax & 0xff));
Wire1.write((uint8_t)(rmax >> 8));
Wire1.write((uint8_t)(rstep & 0xff));
Wire1.write((uint8_t)(rstep >> 8));
Wire1.endTransmission();
}
// Set encoder wheel value
void encoder_setValue(uint8_t encoder_addr, int16_t rval)
{
Wire1.beginTransmission(encoder_addr);
Wire1.write((uint8_t)(rval & 0xff));
Wire1.write((uint8_t)(rval >> 8));
Wire1.endTransmission();
}
// Read encoder wheel value
int16_t encoder_getValue(int encoder_addr)
{
Wire1.requestFrom(encoder_addr, 2);
return ((uint16_t)Wire1.read() | ((uint16_t)Wire1.read() << 8));
}
void Encoders_Interrupt()
{
enc_action = true;
}
// update Audio ---------------------------------------------------------
void updateAmpEnvSustain(int value)
{
float decValue = LINEAR[value];
ampEnv[0].sustain(decValue);
ampEnv[1].sustain(decValue);
ampEnv[2].sustain(decValue);
ampEnv[3].sustain(decValue);
ampEnv[4].sustain(decValue);
ampEnv[5].sustain(decValue);
ampEnv[6].sustain(decValue);
ampEnv[7].sustain(decValue);
}
// Press virtuel key and play sample from psram -------------------------
void play_sample(int16_t note)
{
note += 48; // sample note C4 440Hz
Serial.print("virtual Note : ");
Serial.println(note);
float rate = ((float)pow(2, (note - 60) / 12.00));
float rate2 = ((float)pow(2, (note - 60) / 12.00));
sampleOsc[0].setPlaybackRate(rate);
sampleOsc[0].playRaw(Sample->sampledata, Sample->samplesize / 2, channels);
sampleOsc[1].setPlaybackRate(rate2);
sampleOsc[1].playRaw(Sample->sampledata, Sample->samplesize / 2, channels);
}
// draw bargraph ------------------------------------------------
void draw_bargraph(uint16_t xpos, uint8_t ypos, uint16_t bar_length, uint8_t bar_hight, uint16_t bar_color)
{
tft.fillRect(xpos, ypos, bar_length, bar_hight, ILI9341_BLACK);
tft.drawRect(xpos, ypos, bar_length, bar_hight, bar_color);
tft.fillRect(xpos + 53, ypos - 11, 30, 10, ILI9341_BLACK);
tft.setCursor(xpos + 54, ypos - 11);
tft.setTextSize(1);
tft.setFont(DroidSans_10);
tft.setTextColor(ILI9341_WHITE);
tft.print(0);
tft.print("%");
}
// draw fill_bargraph -------------------------------------------
void draw_fill_bargraph(uint16_t xpos, uint8_t ypos, uint16_t bar_length, uint8_t bar_hight, uint8_t percent, uint16_t bar_color)
{
xpos++;
ypos++;
bar_length -= 1;
bar_hight -= 2;
for (size_t i = 0; i < bar_hight; i++)
{
tft.drawFastHLine(xpos, ypos + i, bar_length, bar_color);
}
tft.fillRect(xpos + 52, ypos - 12, 20, 8, ILI9341_BLACK);
tft.setCursor(xpos + 52, ypos - 12);
tft.setTextSize(1);
tft.setTextColor(ILI9341_WHITE);
tft.print(percent);
tft.print("%");
}
// print file info ----------------------------------------------
void print_file_info(const char *str, uint16_t file_size)
{
tft.fillRect(180, 40, 100, 60, ILI9341_BLACK);
tft.setCursor(180, 40);
tft.setTextSize(1);
tft.setTextColor(ILI9341_WHITE);
tft.print(str);
tft.setCursor(180, 55);
tft.print(file_size);
tft.print(" KB");
}
// press patch list on page1 -----------------------------------
void press_patch_list_page1()
{
uint8_t new_index = 0;
static uint8_t old_index = 0;
static uint8_t old_key_index = 1;
new_index = touch_patch_list();
if (new_index != old_index)
{
old_index = new_index;
if (new_index >= 1 && new_index <= 6)
{
if (new_index != old_key_index)
{
draw_patch_list(new_index - 1, old_key_index - 1);
old_key_index = new_index;
}
}
else if (new_index == 0)
{
for (size_t i = 0; i < 6; i++)
{
TK_state_List_P1[i] = false; // clear touch state
}
}
}
if (new_index >= 1)
{
Reset_screensaver();
}
}
// Touchscreen query -------------------------------------------
void readTouchscreen()
{
if (touchReadTimer >= TouchRead_interval)
{
touchReadTimer = 0;
read_touch_buttons();
}
}
// Screensaver interval ----------------------------------------
void checkScreensaver()
{
if (screensaverTimer >= Screensaver_interval)
{
screensaverTimer = 0;
if (screensaver_Active == false)
{
if (screensaverResetTimer >= Screensaver_stay)
{
screensaverResetTimer = 0;
screensaver_Active = true;
tft.fillScreen(ILI9341_BLACK);
}
}
else
{
screensaver();
}
}
}
// read Midi ---------------------------------------------------
void readMidi()
{
MIDI.read(Midi_channel);
}
// get VoiceNo ------------------------------------------------
int getVoiceNo(int note)
{
voiceToReturn = -1; // Initialise
earliestTime = millis(); // Initialise to now
if (note == -1)
{
// NoteOn() - Get the oldest free voice (recent voices may be still on release stage)
for (int i = 0; i < NO_OF_VOICES; i++)
{
if (voices[i].voiceOn == 0)
{
if (voices[i].timeOn < earliestTime)
{
earliestTime = voices[i].timeOn;
voiceToReturn = i;
}
}
}
if (voiceToReturn == -1)
{
// No free voices, need to steal oldest sounding voice
earliestTime = millis(); // Reinitialise
for (int i = 0; i < NO_OF_VOICES; i++)
{
if (voices[i].timeOn < earliestTime)
{
earliestTime = voices[i].timeOn;
voiceToReturn = i;
}
}
}
return voiceToReturn + 1;
}
else
{
// NoteOff() - Get voice number from note
for (int i = 0; i < NO_OF_VOICES; i++)
{
if (voices[i].note == note && voices[i].voiceOn == 1)
{
return i + 1; // voice number
}
}
// Unison - Note on without previous note off?
return voiceToReturn;
}
// Shouldn't get here, return voice 1
return 1;
}
// Press midi key and play sample from psram -------------------
void playSample(int Voice, uint8_t note)
{
float rate = ((float)pow(2, (note - 72) / 12.00)); // sample note C4 440Hz
int channels = 2;
uint16_t envTime = ENVTIMES[ampEnvValue[0]];
ampEnv[Voice].delay(envTime);
envTime = ENVTIMES[ampEnvValue[1]];
ampEnv[Voice].attack(envTime);
ampEnv[Voice].hold(0);
envTime = ENVTIMES[ampEnvValue[3]];
ampEnv[Voice].decay(envTime);
float decValue = LINEAR[ampEnvValue[4]];
ampEnv[Voice].sustain(decValue);
envTime = ENVTIMES[ampEnvValue[5]];
ampEnv[Voice].release(envTime);
ampEnv[Voice].noteOn();
sampleOsc[Voice].setPlaybackRate(rate);
sampleOsc[Voice].playRaw(Sample->sampledata, Sample->samplesize / 2, channels);
}
// Press midi key and play sample from psram -------------------
void play_midi_sample(uint8_t note)
{
/*
// Drum[slot]->setPlaybackRate( (float)pow (2, (inNumber - 72) / 12.00) * drum_config[activesample].p_offset );
// const uint8_t offset = (note > 209) ? 210 : 18;
// note -= offset;
float rate = ((float)pow(2, (note - 72) / 12.00)); // sample note C4 440Hz
float rate2 = ((float)pow(2, (note - 67) / 12.00)); // sample note C4 440Hz
//Serial.print("Midi Note : ");
//Serial.println(note);
playSample1.setPlaybackRate(rate);
playSample2.setPlaybackRate(rate2);
channels = 2;
playSample1.playRaw(Sample->sampledata, Sample->samplesize / 2, channels);
playSample2.playRaw(Sample->sampledata, Sample->samplesize / 2, channels);
*/
}
// NoteOn from serial Midi -------------------------------------
void myNoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
{
Serial.print("note: ");
Serial.println(note);
int Voice = getVoiceNo(note);
if (Voice == -1)
{
Voice = (getVoiceNo(-1))-1; // Voice-No: 0 - 7
voices[Voice].note = note;
voices[Voice].timeOn = millis();
voices[Voice].voiceOn = 1;
}
playSample(Voice, note);
// play_midi_sample(note);
midiSymbol_status = 1;
Reset_screensaver();
}
// NoteOff from serial Midi ------------------------------------
void myNoteOff(uint8_t channel, uint8_t note, uint8_t velocity)
{
int Voice = getVoiceNo(note) - 1;
if (Voice < 0)
{
return;
}
voices[Voice].voiceOn = 0;
ampEnv[Voice].noteOff();
}
// check display symbols ---------------------------------------
void check_Symbols()
{
if (pageNo != 0)
{
return;
}
if (midiSymbol_status == 1)
{
uint16_t x = 230;
uint16_t y = 10;
draw_Midi_Symbol(x, y, ILI9341_YELLOW);
midiSymbol_status = 2;
midiSymbolTimer = 0;
// tft.waitUpdateAsyncComplete();
//tft.updateScreenAsync(false);
tft.updateScreen();
}
else if (midiSymbol_status == 2 && midiSymbolTimer >= 250)
{
uint16_t x = 230;
uint16_t y = 10;
draw_Midi_Symbol(x, y, ILI9341_DARKERGREY);
midiSymbol_status = 2;
midiSymbolTimer = 0;
midiSymbol_status = 0;
// tft.waitUpdateAsyncComplete();
//tft.updateScreenAsync(false);
tft.updateScreen();
}
}
// Encoder speed -----------------------------------------------
void encoderSpeed(uint8_t enc_addr, int last_value, uint32_t elapsedtime)
{
if (elapsedtime < 150)
{
encoder_set(enc_addr, 0, 127, 6, last_value, 0);
}
else if (elapsedtime >= 150 && elapsedtime < 200)
{
encoder_set(enc_addr, 0, 127, 4, last_value, 0);
}
else if (elapsedtime >= 200 && elapsedtime < 250)
{
encoder_set(enc_addr, 0, 127, 2, last_value, 0);
}
else if (elapsedtime >= 250)
{
encoder_set(enc_addr, 0, 127, 1, last_value, 0);
}
}
// int encoder speed -------------------------------------------
void init_Encoder()
{
// set encoder dynamic
/*
encoderSpeed(48, encoder_last_value[pageNo][0], 250);
encoderSpeed(49, encoder_last_value[pageNo][1], 250);
encoderSpeed(50, encoder_last_value[pageNo][2], 250);
encoderSpeed(51, encoder_last_value[pageNo][3], 250);
encoderSpeed(52, encoder_last_value[pageNo][4], 250);
encoderSpeed(53, encoder_last_value[pageNo][5], 250);
*/
encoderSpeed(48, ampEnvValue[0], 250);
encoderSpeed(49, ampEnvValue[1], 250);
encoderSpeed(50, ampEnvValue[3], 250);
encoderSpeed(51, ampEnvValue[4], 250);
encoderSpeed(52, ampEnvValue[5], 250);
encoderSpeed(53, encoder_last_value[pageNo][5], 250);
rotaryEncoder0_Timer = 250;
rotaryEncoder1_Timer = 250;
rotaryEncoder2_Timer = 250;
rotaryEncoder3_Timer = 250;
rotaryEncoder4_Timer = 250;
rotaryEncoder5_Timer = 250;
}
// Read Rotary encoder -----------------------------------------
void readEncoder(void)
{
if (enc_action == true) // change encoder value ?
{
enc_action = false;
uint8_t count = 6; // numbers of encoders
boolean break_flag = false;
int oldEnvValue[6];
oldEnvValue[0] = encoder_last_value[pageNo][0];
oldEnvValue[1] = encoder_last_value[pageNo][1];
oldEnvValue[2] = encoder_last_value[pageNo][2];
oldEnvValue[3] = encoder_last_value[pageNo][3];
oldEnvValue[4] = encoder_last_value[pageNo][4];
oldEnvValue[5] = encoder_last_value[pageNo][5];
for (uint8_t i = 0; i < count; i++)
{
value = encoder_getValue(encoder_addr + i);
if (value != encoder_last_value[pageNo][i])
{
encoder_last_value[pageNo][i] = value;
break_flag = true;
}
if (break_flag == true)
{
if (pageNo == Envelope_menu)
{
tft.setFont(LiberationSans_10);
tft.setTextColor(ILI9341_BLACK);
if (encoder_addr + i == encoder1_addr)
{
tft.fillRoundRect(11, 176, 58, 17, 2, ILI9341_DARKERGREY);
tft.setCursor(13, 180);
tft.print("Del: ");
tft.setCursor(42, 180);
tft.print(encoder_last_value[pageNo][i]);
ampEnvValue[0] = encoder_last_value[pageNo][i];
// Encoder speed
encoderSpeed(encoder1_addr, encoder_last_value[pageNo][0], rotaryEncoder0_Timer);
rotaryEncoder0_Timer = 0;
}
else if (encoder_addr + i == encoder2_addr)
{
tft.fillRoundRect(71, 176, 58, 17, 2, ILI9341_DARKERGREY);
tft.setCursor(73, 180);
tft.print("Atk: ");
tft.setCursor(102, 180);
tft.print(encoder_last_value[pageNo][i]);
ampEnvValue[1] = encoder_last_value[pageNo][i];
// Encoder speed
encoderSpeed(encoder2_addr, encoder_last_value[pageNo][1], rotaryEncoder1_Timer);
rotaryEncoder1_Timer = 0;
}
else if (encoder_addr + i == encoder3_addr)
{
tft.fillRoundRect(131, 176, 58, 17, 2, ILI9341_DARKERGREY);
tft.setCursor(133, 180);
tft.print("Dec: ");
tft.setCursor(162, 180);
tft.print(encoder_last_value[pageNo][i]);
ampEnvValue[3] = encoder_last_value[pageNo][i];
// Encoder speed
encoderSpeed(encoder3_addr, encoder_last_value[pageNo][2], rotaryEncoder2_Timer);
rotaryEncoder2_Timer = 0;
}
else if (encoder_addr + i == encoder4_addr)
{
tft.fillRoundRect(191, 176, 58, 17, 2, ILI9341_DARKERGREY);
tft.setCursor(193, 180);
tft.print("Sus: ");
tft.setCursor(222, 180);
tft.print(encoder_last_value[pageNo][i]);
ampEnvValue[4] = encoder_last_value[pageNo][i];
updateAmpEnvSustain(ampEnvValue[4]);
// Encoder speed
encoderSpeed(encoder4_addr, encoder_last_value[pageNo][3], rotaryEncoder3_Timer);
rotaryEncoder3_Timer = 0;
}
else if (encoder_addr + i == encoder5_addr)
{
tft.fillRoundRect(251, 176, 58, 17, 2, ILI9341_DARKERGREY);
tft.setCursor(253, 180);
tft.print("Rel: ");
tft.setCursor(282, 180);
tft.print(encoder_last_value[pageNo][i]);
ampEnvValue[5] = encoder_last_value[pageNo][i];
// Encoder speed
encoderSpeed(encoder5_addr, encoder_last_value[pageNo][4], rotaryEncoder4_Timer);
rotaryEncoder4_Timer = 0;
}
else if (encoder_addr + i == encoder6_addr)
{
// Encoder speed
encoderSpeed(encoder6_addr, encoder_last_value[pageNo][5], rotaryEncoder5_Timer);
rotaryEncoder5_Timer = 0;
}
// clear old envelope line
draw_envelope(oldEnvValue[0], oldEnvValue[1], oldEnvValue[2], oldEnvValue[3],
oldEnvValue[4], ILI9341_BLACK);
draw_env_grid();
// draw new envelope line
draw_envelope(encoder_last_value[pageNo][0], encoder_last_value[pageNo][1], encoder_last_value[pageNo][2],
encoder_last_value[pageNo][3], encoder_last_value[pageNo][4], ILI9341_DARKGREEN);
//tft.updateScreenAsync(false);
tft.updateScreen();
}
break;
}
}
}
}
// Display trade -----------------------------------------------
void DisplayThreade(void)
{
/*
if (Display_Timer >= 27)
{
Display_Timer = 0;
// tft.waitUpdateAsyncComplete();
// tft.updateScreenAsync(false);
// tft.updateChangedAreasOnly(true);
// tft.waitUpdateAsyncComplete();
// tft.updateScreen();
if (!tft.asyncUpdateActive())
{
// tft.updateScreenAsync();
tft.updateScreen();
}
}
*/
}
// Setup -------------------------------------------------------
void setup()
{
// init Serial for debug
Serial.begin(9600);
SPI.begin();
// init Display
tft.begin();
tft.setFrameBuffer(screenBuffer); // Initialize Frame Buffer
tft.useFrameBuffer(true); // Use Frame Buffer
tft.updateChangedAreasOnly(true);
tft.invertDisplay(1);
tft.setRotation(3);
// init TouchScreen
ts.begin(10);
// init Midi
MIDI.begin();
MIDI.setHandleNoteOn(myNoteOn);
MIDI.setHandleNoteOff(myNoteOff);
// init Wire1 for Encoders
Wire1.begin();
Wire1.setClock(400000UL); // I2C speed 400KHz
encoder_set(encoder_addr + 0, 0, 127, 1, 0, 0);
encoder_set(encoder_addr + 1, 0, 127, 1, 0, 0);
encoder_set(encoder_addr + 2, 0, 127, 1, 0, 0);
encoder_set(encoder_addr + 3, 0, 127, 1, 0, 0);
encoder_set(encoder_addr + 4, 0, 127, 1, 0, 0);
encoder_set(encoder_addr + 5, 0, 127, 1, 0, 0);
attachInterrupt(digitalPinToInterrupt(PIN_ENC_INT), Encoders_Interrupt, RISING);
// init SDCARD
Serial.print("Initializing SD card...");
while (!SD.begin(BUILTIN_SDCARD))
{
Serial.println("initialization failed!");
delay(1000);
}
Serial.println("SD card ok");
// init Audio
AudioMemory(128);
// Audio Patching
outMixer1.gain(0, 0.5);
outMixer1.gain(1, 0.5);
outMixer1.gain(2, 0.5);
outMixer1.gain(3, 0.5);
outMixer2.gain(0, 0.5);
outMixer2.gain(1, 0.5);
outMixer2.gain(2, 0.5);
outMixer2.gain(3, 0.5);
outMixer3.gain(0, 0.5);
outMixer3.gain(1, 0.5);
outMixer3.gain(2, 0.5);
outMixer3.gain(3, 0.5);
outMixer4.gain(0, 0.5);
outMixer4.gain(1, 0.5);
outMixer4.gain(2, 0.5);
outMixer4.gain(3, 0.5);
MainOutMixerL.gain(0, 0.5f);
MainOutMixerL.gain(1, 0.5f);
MainOutMixerR.gain(0, 0.5f);
MainOutMixerR.gain(1, 0.5f);
// init AmpEnvelope
const int8_t envelopeType = -4; // 0 linear, -8 fast exponential, -8 slow exponential
ampEnv[0].setEnvType(envelopeType);
ampEnv[1].setEnvType(envelopeType);
ampEnv[2].setEnvType(envelopeType);
ampEnv[3].setEnvType(envelopeType);
ampEnv[4].setEnvType(envelopeType);
ampEnv[5].setEnvType(envelopeType);
ampEnv[6].setEnvType(envelopeType);
ampEnv[7].setEnvType(envelopeType);
ampEnv[0].delay(ampEnvValue[0]);
ampEnv[1].delay(ampEnvValue[0]);
ampEnv[2].delay(ampEnvValue[0]);
ampEnv[3].delay(ampEnvValue[0]);
ampEnv[4].delay(ampEnvValue[0]);
ampEnv[5].delay(ampEnvValue[0]);
ampEnv[6].delay(ampEnvValue[0]);
ampEnv[7].delay(ampEnvValue[0]);
ampEnv[0].attack(ampEnvValue[1]);
ampEnv[1].attack(ampEnvValue[1]);
ampEnv[2].attack(ampEnvValue[1]);
ampEnv[3].attack(ampEnvValue[1]);
ampEnv[4].attack(ampEnvValue[1]);
ampEnv[5].attack(ampEnvValue[1]);
ampEnv[6].attack(ampEnvValue[1]);
ampEnv[7].attack(ampEnvValue[1]);
ampEnv[0].hold(ampEnvValue[2]);
ampEnv[1].hold(ampEnvValue[2]);
ampEnv[2].hold(ampEnvValue[2]);
ampEnv[3].hold(ampEnvValue[2]);
ampEnv[4].hold(ampEnvValue[2]);
ampEnv[5].hold(ampEnvValue[2]);
ampEnv[6].hold(ampEnvValue[2]);
ampEnv[7].hold(ampEnvValue[2]);
ampEnv[0].decay(ampEnvValue[3]);
ampEnv[1].decay(ampEnvValue[3]);
ampEnv[2].decay(ampEnvValue[3]);
ampEnv[3].decay(ampEnvValue[3]);
ampEnv[4].decay(ampEnvValue[3]);
ampEnv[5].decay(ampEnvValue[3]);
ampEnv[6].decay(ampEnvValue[3]);
ampEnv[7].decay(ampEnvValue[3]);
ampEnv[0].sustain(ampEnvValue[4]);
ampEnv[1].sustain(ampEnvValue[4]);
ampEnv[2].sustain(ampEnvValue[4]);
ampEnv[3].sustain(ampEnvValue[4]);
ampEnv[4].sustain(ampEnvValue[4]);
ampEnv[5].sustain(ampEnvValue[4]);
ampEnv[6].sustain(ampEnvValue[4]);
ampEnv[7].sustain(ampEnvValue[4]);
ampEnv[0].release(ampEnvValue[5]);
ampEnv[1].release(ampEnvValue[5]);
ampEnv[2].release(ampEnvValue[5]);
ampEnv[3].release(ampEnvValue[5]);
ampEnv[4].release(ampEnvValue[5]);
ampEnv[5].release(ampEnvValue[5]);
ampEnv[6].release(ampEnvValue[5]);
ampEnv[7].release(ampEnvValue[5]);
sampleOsc[0].enableInterpolation(true);
sampleOsc[1].enableInterpolation(true);
sampleOsc[2].enableInterpolation(true);
sampleOsc[3].enableInterpolation(true);
sampleOsc[4].enableInterpolation(true);
sampleOsc[5].enableInterpolation(true);
sampleOsc[6].enableInterpolation(true);
sampleOsc[7].enableInterpolation(true);
// Load Sample
newdigate::flashloader loader;
File root;
root = SD.open("/Samples");
const char *_filename = "/Samples/SAMPLE12.WAV"; // Sine 440Hz
Sample = loader.sampleOsc(_filename);
sample_busy_flag = true;
// draw Main page
pageNo = 0;
draw_menu_page(pageNo);
init_Encoder();
}
// Loop ---------------------------------------------------
void loop()
{
readMidi();
draw_Peak();
if (Task_Timer >= 15)
{
readEncoder();
readTouchscreen(); // call with interval timer
checkScreensaver(); // call with interval timer
check_Symbols();
//draw_real_envelope();
Task_Timer = 0;
}
}