Hello guys!
Currently, I am working on a step sequencer with a wavetable synthesizer. I want to draw the individual waves on a TFT ILI9341 Display and put them anywhere I want along 16 steps. I already managed to draw the waves and get an output with my Audio Shield, but now I am facing a weird problem. As soon as I try to implement my wave-synthesizer code into the step sequencer, it gets very quiet. As soon as I try to draw anything on the screen, the volume becomes high again and it begins to stutter. The LEDs which indicate the steps don't stop though. I am not sure whether it's a hard- or a software problem.. I apologize for my messy code, without any classes or sophisticated solutions, I began 1-2 months ago.. I would be very thankful about any kind of help from you! Thanks!
Be careful, it gets pretty loud as soon as I begin to draw!
ADSR:
Currently, I am working on a step sequencer with a wavetable synthesizer. I want to draw the individual waves on a TFT ILI9341 Display and put them anywhere I want along 16 steps. I already managed to draw the waves and get an output with my Audio Shield, but now I am facing a weird problem. As soon as I try to implement my wave-synthesizer code into the step sequencer, it gets very quiet. As soon as I try to draw anything on the screen, the volume becomes high again and it begins to stutter. The LEDs which indicate the steps don't stop though. I am not sure whether it's a hard- or a software problem.. I apologize for my messy code, without any classes or sophisticated solutions, I began 1-2 months ago.. I would be very thankful about any kind of help from you! Thanks!
Be careful, it gets pretty loud as soon as I begin to draw!
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <ILI9341_t3.h>
#include <font_Arial.h> // from ILI9341_t3
#include <XPT2046_Touchscreen.h>
#define CS_PIN 8
#define TFT_DC 9
#define TFT_CS 10
// MOSI=11, MISO=12, SCK=13
XPT2046_Touchscreen ts(CS_PIN);
#define TIRQ_PIN 2
ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);
namespace modulo4 {
float map(float x, float in_min, float in_max, float out_min, float out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
} //Funktionen innerhalb der Klammern nur aufrufbar, wenn modulo4:: davor steht
int width = 2;
constexpr int arrayLength = 257; // const kannst du während des programms initialisieren --> constexp liegt schon von Anfang an fest
int16_t anArray_X[arrayLength] = {0};
float anArray1[arrayLength] = {0};
int X, Y;
int Y_old;
int X_old;
boolean previous_is_touched;
typedef struct {
int x;
int y;
} points_t;
// int16_t anArray_Y[257] = {0};
// GUItool: begin automatically generated code
AudioSynthWaveform waveform2; //xy=161,336
AudioSynthWaveform waveform3; //xy=161,367
AudioSynthWaveform waveform4; //xy=161,398
AudioSynthWaveform waveform1; //xy=162,304
AudioEffectEnvelope envelope4; //xy=297,396
AudioEffectEnvelope envelope3; //xy=299,366
AudioEffectEnvelope envelope1; //xy=301,303
AudioEffectEnvelope envelope2; //xy=301,334
AudioMixer4 mixer1; //xy=439,347
AudioOutputI2S i2s1; //xy=633,351
AudioConnection patchCord1(waveform2, envelope2);
AudioConnection patchCord2(waveform3, envelope3);
AudioConnection patchCord3(waveform4, envelope4);
AudioConnection patchCord4(waveform1, envelope1);
AudioConnection patchCord5(envelope4, 0, mixer1, 3);
AudioConnection patchCord6(envelope3, 0, mixer1, 2);
AudioConnection patchCord7(envelope1, 0, mixer1, 0);
AudioConnection patchCord8(envelope2, 0, mixer1, 1);
AudioConnection patchCord9(mixer1, 0, i2s1, 0);
AudioConnection patchCord10(mixer1, 0, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1; //xy=289,51
// GUItool: end automatically generated code
int b1 = 0;
int b2 = 0;
int b3 = 0;
int b4 = 0;
float att1 = 50;
float dec1 = 200;
float sus1 = 200;
float rel1 = 200;
float att2 = 50;
float dec2 = 200;
float sus2 = 200;
float rel2 = 200;
float att3 = 50;
float dec3 = 200;
float sus3 = 200;
float rel3 = 200;
float att4 = 50;
float dec4 = 200;
float sus4 = 200;
float rel4 = 200;
float att = 200;
float dec = 200;
float sus = 200;
float rel = 200;
int led3 = 3;
int led4 = 4;
int led5 = 5;
int led6 = 6;
int amp1 = 1;
int amp2 = 1;
int amp3 = 1;
int amp4 = 1;
int freq1 = 500;
int freq2 = 700;
int freq3 = 900;
int freq4 = 1100;
//-------- MILLIS STEP --------//
int m_step = 0;
unsigned long m_interval = 200;
int m_STEPNUM = 4; // Amount of steps
unsigned long m_lastMillis;
float fourth = 1.0 / 4.0;
float one_sixth = 1.0 / 6.0;
int bpm = 120;
int modulo = 1000 * (60.0 / bpm); // in milli
// int fourth_modulo = fourth * modulo;
int previousA2 = 0; // previously sent poti values, to detect changes
int minBPM = 30;
int maxBPM = 220;
const int numReadings = 5; // Anzahl der Readings
int readings[numReadings]; // the readings from the analog input
int readIndex = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average
int inputPin = A1; // Analog input
int average_bpm = 0;
int average_bpm_alt = 0;
int16_t AudioWaveformSineyes[257] = {
0, 804, 1608, 2410, 3212, 4011, 4808, 5602, 6393, 7179,
7962, 8739, 9512, 10278, 11039, 11793, 12539, 13279, 14010, 14732,
15446, 16151, 16846, 17530, 18204, 18868, 19519, 20159, 20787, 21403,
22005, 22594, 23170, 23731, 24279, 24811, 25329, 25832, 26319, 26790,
27245, 27683, 28105, 28510, 28898, 29268, 29621, 29956, 30273, 30571,
30852, 31113, 31356, 31580, 31785, 31971, 32137, 32285, 32412, 32521,
32609, 32678, 32728, 32757, 32767, 32757, 32728, 32678, 32609, 32521,
32412, 32285, 32137, 31971, 31785, 31580, 31356, 31113, 30852, 30571,
30273, 29956, 29621, 29268, 28898, 28510, 28105, 27683, 27245, 26790,
26319, 25832, 25329, 24811, 24279, 23731, 23170, 22594, 22005, 21403,
20787, 20159, 19519, 18868, 18204, 17530, 16846, 16151, 15446, 14732,
14010, 13279, 12539, 11793, 11039, 10278, 9512, 8739, 7962, 7179,
6393, 5602, 4808, 4011, 3212, 2410, 1608, 804, 0, -804,
-1608, -2410, -3212, -4011, -4808, -5602, -6393, -7179, -7962, -8739,
-9512, -10278, -11039, -11793, -12539, -13279, -14010, -14732, -15446, -16151,
-16846, -17530, -18204, -18868, -19519, -20159, -20787, -21403, -22005, -22594,
-23170, -23731, -24279, -24811, -25329, -25832, -26319, -26790, -27245, -27683,
-28105, -28510, -28898, -29268, -29621, -29956, -30273, -30571, -30852, -31113,
-31356, -31580, -31785, -31971, -32137, -32285, -32412, -32521, -32609, -32678,
-32728, -32757, -32767, -32757, -32728, -32678, -32609, -32521, -32412, -32285,
-32137, -31971, -31785, -31580, -31356, -31113, -30852, -30571, -30273, -29956,
-29621, -29268, -28898, -28510, -28105, -27683, -27245, -26790, -26319, -25832,
-25329, -24811, -24279, -23731, -23170, -22594, -22005, -21403, -20787, -20159,
-19519, -18868, -18204, -17530, -16846, -16151, -15446, -14732, -14010, -13279,
-12539, -11793, -11039, -10278, -9512, -8739, -7962, -7179, -6393, -5602,
-4808, -4011, -3212, -2410, -1608, -804, 0
};
int16_t anArray_Y[arrayLength] = {0};
boolean wastouched = true;
void redrawButtons() {
/* tft.fillRoundRect(xStartingPointBefore, yStartingPointBefore, LengthOfSquare, WidthOfSquare, RadiusOfRoundCorner, colorOfSquare);
xStartingPointAfter = map(xStartingPointBefore, 0, 3482, 0, (arrayLength - 1));
yStartingPointAfter = map(yStartingPointBefore, */
tft.fillRoundRect(0, 224, 76, 14, 3, CL(0, 0, 0));
tft.fillRoundRect(0, 224, 76, 14, 3, CL(250, 100, 0));
tft.setCursor(0 + 23, 227);
tft.print("Clear");
}
void clearDisplay() {
tft.fillScreen(ILI9341_BLACK);
redrawButtons();
tft.drawLine(0, 120, 320, 120, CL(255, 255, 255));
tft.drawLine(0, 121, 320, 121, CL(255, 255, 255));
tft.drawLine(0, 119, 320, 119, CL(255, 255, 255));
}
void clearArray() {
for (X = 0; X < arrayLength; X++) {
anArray1[X] = 0;
}
}
boolean pointInRect(int x, float y, float rectX, float rectY, float rectW, float rectH) {
boolean ret = false;
if ((x >= rectX) && (x <= (rectX + rectW)) && (y >= rectY) && (y <= (rectY + rectH))) {
ret = true;
}
return ret;
}
void setup() {
Serial.begin(38600); // 38600 symbols per second
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
pinMode(led5, OUTPUT);
pinMode(led6, OUTPUT);
pinMode(1, INPUT_PULLUP); // b1
pinMode(2, INPUT_PULLUP); // b2
pinMode(3, INPUT_PULLUP); // b3
pinMode(4, INPUT_PULLUP); // b4
AudioMemory(20);
sgtl5000_1.enable();
sgtl5000_1.volume(0);
mixer1.gain(0, 0.5);
mixer1.gain(1, 0.5);
mixer1.gain(2, 0.5);
mixer1.gain(3, 0.5);
waveform1.begin(WAVEFORM_ARBITRARY); // WAVE 1
waveform1.amplitude(amp1);
waveform1.frequency(freq1);
waveform2.begin(WAVEFORM_SINE); // WAVE 2
waveform2.amplitude(amp2);
waveform2.frequency(freq2);
waveform3.begin(WAVEFORM_SINE); // WAVE 3
waveform3.amplitude(amp3);
waveform3.frequency(freq3);
waveform4.begin(WAVEFORM_SINE); // WAVE 4
waveform4.amplitude(amp4);
waveform4.frequency(freq4);
//------Touch---------//
tft.begin();
tft.setRotation(1);
tft.fillScreen(ILI9341_BLACK);
tft.drawLine(0, 120, 320, 120, CL(255, 255, 255));
tft.drawLine(0, 121, 320, 121, CL(255, 255, 255));
tft.drawLine(0, 119, 320, 119, CL(255, 255, 255));
ts.begin();
ts.setRotation(1);
while (!Serial && (millis() <= 1000)); // weiß nicht was das ist
clearDisplay();
redrawButtons();
}
void loop() {
int att = analogRead(A2);
int dec = analogRead(A0);
int rel = analogRead(A4);
int sus = analogRead(A3);
ADSR(att, dec, rel, sus);
// ----------------- SMOOTHING TEMPLATE -----------------
static float bpm = {120}; // wird wegen static nur einmal initialisiert
// int modulo = 1000 * (60.0 / average_bpm); // in milli
// int fourth_modulo = fourth * modulo;
int n1 = analogRead(A1);
// int current_time = millis();
// int modulo_time = current_time % modulo;
// subtract the last reading:
total = total - readings[readIndex] ; // Alle Analoge inputwerte zusammenaddiert, wobei der Wert der neuen Loop abgezogen wird (zieht den nullten Wert ab)
// read from the sensor:
readings[readIndex] = analogRead(inputPin);
// add the reading to the total:
total = total + readings[readIndex];
// advance to the next position in the array:
readIndex = readIndex + 1;
if (readIndex >= numReadings) {
// ...wrap around to the beginning:
readIndex = 0;
// calculate the average:
average = total / numReadings;
average_bpm = map(average, 0, 1023, 50, 280);
if (average_bpm != average_bpm_alt) {
// Serial.println(average_bpm);
}
average_bpm_alt = average_bpm;
// Serial.println(average_bpm);
// -------- ARBITRARY WAVE --------
boolean istouched = ts.touched();
int X;
float Y;
if (istouched) {
TS_Point p = ts.getPoint(); // point getter function
// X = map(p.x - 320, 3482, 0, 0, 320);
X = map(p.x - 320, 3482, 0, 0, arrayLength - 1);
if (X < 0) {
X = 0;
}
Y = modulo4::map(p.y - 240.0, 3465.0, 0.0, 1.0, -1.0); //davor 240
anArray1[X] = Y;
/* if (previous_is_touched) {
for ( int i {X_old}; i < X; (X_old <= X) ? (++i) : (--i) ) { // conditional operator
anArray1[i] = modulo4::map(i, X_old, X, anArray1[X_old], anArray1[X]);
}
}
X_old = X; */
if (previous_is_touched) {
for ( int i = X_old ; i < X;) {
if (X_old <= X) {
i++;
}
else {
i--;
}
anArray1[i] = modulo4::map(i, X_old, X, anArray1[X_old], anArray1[X]);
}
}
X_old = X;
if (pointInRect(X, Y, 0.0, -1.0, 76.0, 0.1)) {
clearDisplay();
clearArray();
}
clearDisplay();
for (int i {0}; i < arrayLength; ++i) {
tft.fillCircle(map(i, 0, 256, 0, 320), modulo4::map(anArray1[i], 1.0, -1.0, 0.0, 240.0), width, CL(255, 0, 0));
anArray_Y[i] = modulo4::map(anArray1[i], 1.0, -1.0, -32767, 32767);
}
waveform1.arbitraryWaveform(anArray_Y, 20000);
if ( X > arrayLength ) {
X = 256;
}
Serial.print("X: ");
Serial.print(X);
Serial.println();
Serial.print("Y: ");
Serial.print(anArray_Y[X]);
Serial.println();
Serial.println();
}
previous_is_touched = istouched;
// ----------------- MILLIS BASED SEQUENCER -----------------//
if ((millis() - m_lastMillis) > m_interval)
{
if (m_step == m_STEPNUM)
{
m_step = 0;
}
m_step++;
/* Serial.print("Millis:");
Serial.print(millis());
Serial.println();
Serial.print("Last Millis:");
Serial.print(m_lastMillis);
Serial.println();
Serial.println(); */
Serial.println(m_step);
m_lastMillis = millis();
}
if (m_step == 1) {
digitalWrite(led3, HIGH);
digitalWrite(led6, LOW);
envelope4.noteOff();
envelope1.noteOn();
waveform1.amplitude(amp1);
waveform1.frequency(freq1);
}
else if (m_step == 2) {
digitalWrite(led3, LOW);
digitalWrite(led4, HIGH);
envelope1.noteOff();
envelope2.noteOn();
waveform2.amplitude(amp2);
waveform2.frequency(freq2);
}
else if (m_step == 3) {
digitalWrite(led4, LOW);
digitalWrite(led5, HIGH);
envelope2.noteOff();
envelope3.noteOn();
waveform3.amplitude(amp3);
waveform3.frequency(freq3);
}
else if (m_step == 4) {
digitalWrite(led5, LOW);
digitalWrite(led6, HIGH);
envelope3.noteOff();
envelope4.noteOn();
waveform4.amplitude(amp4);
waveform4.frequency(freq4);
}
}
}
ADSR:
Code:
void ADSR(float att, float dec, float sus, float rel) { //HIGH and LOW are not boolean values.. they are integers, where HIGH = 1 and LOW = 0.
b1 = digitalRead(1);
b2 = digitalRead(2);
b3 = digitalRead(3);
b4 = digitalRead(4);
if (b1 == 0) {
att = att1;
dec = dec1;
sus = sus1;
rel = rel1;
}
else if (b2 == 0) {
att = att2;
dec = dec2;
sus = sus2;
rel = rel2;
}
else if (b3 == 0) {
att = att3;
dec = dec3;
sus = sus3;
rel = rel3;
}
else if (b4 == 0) {
att = att4;
dec = dec4;
sus = sus4;
rel = rel4;
}
envelope1.attack(att1); // ADSR 1
envelope1.decay(dec1);
envelope1.sustain(sus1);
envelope1.release(rel1);
envelope2.attack(att2); // ADSR 2
envelope2.decay(dec2);
envelope2.sustain(sus2);
envelope2.release(rel2);
envelope3.attack(att3); // ADSR 3
envelope3.decay(dec3);
envelope3.sustain(sus3);
envelope3.release(rel3);
envelope4.attack(att4); // ADSR 4
envelope4.decay(dec4);
envelope4.sustain(sus4);
envelope4.release(rel4);
}