//********************************************************************
// 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];
// EXTMEM 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
// Setup -------------------------------------------------------
void setup()
{
// init Serial for debug
Serial.begin(9600);
// init Midi
MIDI.begin();
MIDI.setHandleNoteOn(myNoteOn);
MIDI.setHandleNoteOff(myNoteOff);
SPI.begin();
// init Display
tft.begin();
tft.setFrameBuffer(screenBuffer); // Initialize Frame Buffer
tft.useFrameBuffer(true); // Use Frame Buffer
// tft.waitUpdateAsyncComplete();
tft.updateChangedAreasOnly(true);
tft.invertDisplay(1);
tft.setRotation(3);
// init TouchScreen
ts.begin(10);
// 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();
if (tft.asyncUpdateActive() == false)
{
draw_Peak();
readEncoder();
readTouchscreen();
check_Symbols();
}
if (updateScreen_Timer >= 51) // 51ms
{
tft.updateScreenAsync(false);
updateScreen_Timer = 0;
}
}