Code:
#include "Display.h"
// XPT2046_Touchscreen ts(CS_PIN); // Instanziierung eines ts Objekts der Klasse XPT2046_Touchscreen
// ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);
#define TIRQ_PIN 2
#define CS_PIN 8
#define TFT_DC 9
#define TFT_CS 10
Display::Display() : ts(CS_PIN), tft(TFT_CS, TFT_DC)
{
}
// Original raw minimum and maximum values:
// X --> 340 bis 3900
// Y --> 200 bis 3850
boolean Display::isTouched()
{
return ts.touched();
}
TS_Point Display::getPoint()
{
int16_t xScaled{0};
int16_t yScaled{0};
TS_Point pUnscaled = ts.getPoint(); // point getter function
if (map(pUnscaled.x, 340, 3900, maximumX, minimumX) < minimumX)
{
xScaled = minimumX;
}
else if (map(pUnscaled.x, 340, 3900, maximumX, minimumX) > maximumX)
{
xScaled = maximumX;
}
else
{
xScaled = map(pUnscaled.x, 340, 3900, maximumX, minimumX);
}
if (map(pUnscaled.y, 200, 3850, maximumY, minimumY) < minimumY)
{
yScaled = minimumY;
}
else if (map(pUnscaled.y, 200, 3850, maximumY, minimumY) > maximumY)
{
yScaled = maximumY;
}
else
{
yScaled = map(pUnscaled.y, 200, 3850, maximumY, minimumY);
}
TS_Point pScaled{xScaled, yScaled, 0};
return pScaled;
}
int16_t *Display::getArray()
{
return wave1Values;
}
void Display::drawButtons()
{
for (int i{0}; i < 4; ++i)
{
tft.fillRoundRect(_gap + (_gap + _widthSquare) * i, 220, _widthSquare, _heightSquare, _radiusOfRoundCorner, CL(250, 0, 0));
tft.setCursor(26 + ((_gap + _widthSquare) * i), 227);
tft.print(buttonNames[i]);
}
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 Display::clear()
{
tft.fillScreen(ILI9341_BLACK);
drawButtons();
}
void Display::start()
{
Serial.begin(38600);
tft.begin();
tft.setRotation(1);
tft.fillScreen(ILI9341_BLACK);
ts.begin();
ts.setRotation(1);
while (!Serial && (millis() <= 1000))
; // weiß nicht was das ist
}
boolean Display::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 Display::touchButton()
{
if (pointInRect(_x, _y, _gap, (240 - _heightSquare), (_widthSquare), (_heightSquare)))
{
tft.fillRoundRect(_gap, (240 - _heightSquare), _widthSquare, _heightSquare, _radiusOfRoundCorner, CL(250, 100, 0));
clear();
// clearArray();
}
}
void Display::draw(TS_Point pTS)
{
wave1Values[pTS.x] = pTS.y;
// Serial.println(*getArray());
for (int i{0}; i < 257; ++i)
{
tft.fillCircle(map(i, 0, 256, 0, 320), map(wave1Values[i], -32767, 32767, 0, 240), pointRadius, CL(255, 0, 0));
}
}
/* float Display::mapper(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;
} */
void Display::linearInterpolation(TS_Point pTS)
{
if (X_old <= pTS.x)
{
for (int i = X_old; i < pTS.x; ++i)
{
wave1Values[i] = map(i, X_old, pTS.x, wave1Values[X_old], wave1Values[pTS.x]);
}
}
else
{
for (int i = pTS.x; i < X_old; ++i)
{
wave1Values[i] = map(i, X_old, pTS.x, wave1Values[X_old], wave1Values[pTS.x]);
}
}
X_old = pTS.x;
}
void Display::init()
{
start();
clear();
drawButtons();
}
void Display::update()
{
if (isTouched())
{
TS_Point pTS = getPoint();
if (previousIsTouched)
{
linearInterpolation(pTS);
}
touchButton();
clear();
draw(pTS);
}
previousIsTouched = isTouched();
}
Sequencer.h;
Code:
#ifndef Sequencer_h
#define Sequencer_h
#include <array>
#include <Audio.h>
#include <Wire.h>
#include "Display.h"
#include <MegunoLink.h>
#include <Filter.h>
#include "Encoder.h"
class Sequencer
{
public:
Sequencer();
void start();
void stop();
unsigned int counter(float interval);
void stepButtons();
void buttonsAbfragen(int zaehler, int digitalPin);
void stepLED();
void update();
float getBPMInterval();
void muxUpdate();
long encoder();
float mapper(float x, float in_min, float in_max, float out_min, float out_max);
int _deflectionRate;
int frequency1 = {160};
int frequency2 = {200};
int frequency3 = {140};
int frequency4 = (110);
ExponentialFilter<long> ADCFilter;
std::array<float, 4> attack;
std::array<float, 4> decay;
std::array<float, 4> sustain;
std::array<float, 4> release;
std::array<float, 4> amplitude;
std::array<int, 4> frequency{{frequency1, frequency2, frequency3, frequency4}};
std::array<int, 4> m_stepLEDPin{{3, 4, 5, 6}};
std::array<int, 4> m_stepButtonPin{{0, 1, 14, 15}};
std::array<boolean, 4> m_stepState{{true, true, true, true}};
std::array<boolean, 4> digitalReadValues;
int16_t *wave1Values;
float defaultAttackValue = {50};
float defaultDecayValue = {200};
float defaultSustainValue = {200};
float defaultReleaseValue = {200};
float defaultVolume = {0.3};
unsigned long m_lastMillis;
float m_interval = (60.0 / average_bpm) * 1000.0;
unsigned long m_stepStateInterval = 20;
unsigned int m_STEPNUM = 4;
int16_t AudioWaveformSineExample[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};
unsigned int m_step = 0;
const int numReadings = 5; // Anzahl der Readings
int readings[5]; // the readings from the analog input
int readIndex = 0; // the index of the current reading
int total = 0; // the running total
float average = 0; // the average
int inputPin = A3; // Analog input
int average_bpm = 120;
int average_bpm_alt = 120;
unsigned long m_BPMInterval = 400;
int m_AnalogThreshold = 3;
int ADCFilterBefore;
float interval;
float minBPM = 40.0;
float maxBPM = 800.0;
int pin_Out_S0 = 0;
int pin_Out_S1 = 1;
int pin_Out_S2 = 2;
int buttonState[48];
int bit1 = 0;
int bit2 = 0;
int bit3 = 0;
long positionEnc1 = -999;
Encoder Enc1;
AudioSynthWaveform *waveform = new AudioSynthWaveform[4];
AudioEffectEnvelope *envelope = new AudioEffectEnvelope[4];
AudioMixer4 mixer1;
AudioOutputI2S i2s1;
AudioConnection patchCord1;
AudioConnection patchCord2;
AudioConnection patchCord3;
AudioConnection patchCord4;
AudioConnection patchCord5;
AudioConnection patchCord6;
AudioConnection patchCord7;
AudioConnection patchCord8;
AudioConnection patchCord9;
AudioConnection patchCord10;
AudioControlSGTL5000 sgtl5000_1;
Display _display;
private:
};
#endif
Sequencer.cpp:
Code:
#include "Sequencer.h"
#include "Display.h"
Sequencer::Sequencer() : patchCord1(waveform[1], envelope[1]),
patchCord2(waveform[2], envelope[2]),
patchCord3(waveform[3], envelope[3]),
patchCord4(waveform[0], envelope[0]),
patchCord5(envelope[3], 0, mixer1, 3),
patchCord6(envelope[2], 0, mixer1, 2),
patchCord7(envelope[0], 0, mixer1, 0),
patchCord8(envelope[1], 0, mixer1, 1),
patchCord9(mixer1, 0, i2s1, 0),
patchCord10(mixer1, 0, i2s1, 1),
_display(),
ADCFilter(60, 0),
Enc1(21, 22)
{
for (int i{0}; i < 4; ++i)
{
envelope[i].attack(attack[i]);
envelope[i].decay(decay[i]);
envelope[i].sustain(sustain[i]);
envelope[i].release(release[i]);
}
AudioMemory(20);
sgtl5000_1.enable();
sgtl5000_1.volume(defaultVolume);
attack.fill(defaultDecayValue);
decay.fill(defaultDecayValue);
sustain.fill(defaultSustainValue);
release.fill(defaultSustainValue);
amplitude.fill(defaultVolume);
for (unsigned int i{0}; i < 4; ++i)
{
mixer1.gain(i, defaultVolume);
waveform[i].begin(WAVEFORM_SINE); // WAVEFORM_SINE expands to 0 WAVEFORM_ARBITRARY expands to 4
waveform[i].amplitude(amplitude[i]);
waveform[i].frequency(frequency[i]);
pinMode(m_stepLEDPin[i], OUTPUT);
pinMode(m_stepButtonPin[i], INPUT_PULLUP);
}
}
float Sequencer::getBPMInterval()
{
int RawValue = analogRead(A2);
ADCFilter.Filter(RawValue);
if ((millis() - m_lastMillis) > m_BPMInterval && ADCFilterBefore != ADCFilter.Current() && (ADCFilterBefore - ADCFilter.Current() > m_AnalogThreshold))
{
m_lastMillis = millis();
ADCFilterBefore = ADCFilter.Current();
}
// 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] = RawValue;
// 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 = mapper(average, 1.0, 1023.0, minBPM, maxBPM);
}
if (average_bpm != average_bpm_alt)
{
average_bpm_alt = average_bpm;
}
float m_interval = (60.0 / average_bpm) * 1000.0;
return m_interval;
}
unsigned int Sequencer::counter(float interval) // Returns the current position
{
if ((millis() - m_lastMillis) > getBPMInterval()) // m_interval = 1000 ---> 60 bpm , m_interval = 500 ---> 120bpm
{
m_lastMillis = millis();
m_step++;
if (m_step == m_STEPNUM)
{
m_step = 0;
}
}
return m_step;
}
void Sequencer::stepButtons()
{
std::array<boolean, 4> digitalReadValues = {digitalRead(0), digitalRead(1), digitalRead(14), digitalRead(15)};
for (unsigned int i{0}; i < digitalReadValues.size(); ++i)
{
if ((millis() - m_lastMillis) > m_stepStateInterval)
{
if (digitalReadValues[i] == LOW) // LOW = GEDRÜCKT
{
m_stepState[i] = !m_stepState[i];
}
}
}
}
void Sequencer::stepLED()
{
if (_display.isTouched())
{
wave1Values = _display.getArray();
}
waveform[0].arbitraryWaveform(wave1Values, 20000);
counter(getBPMInterval()); //No constructor needed because you already wrote Sequencer::stepLED()
for (unsigned int i{0}; i < m_stepLEDPin.size(); ++i)
{
if (counter(getBPMInterval()) == 0)
{
digitalWrite(m_stepLEDPin[0], m_stepState[0]);
digitalWrite(m_stepLEDPin[3], LOW);
envelope[0].noteOn();
waveform[0].amplitude(m_stepState[0]);
waveform[0].frequency(frequency[0]);
}
else if (counter(getBPMInterval()) == i)
{
digitalWrite(m_stepLEDPin[i], m_stepState[i]);
digitalWrite(m_stepLEDPin[i] - 1, LOW);
envelope[i].noteOn();
waveform[i].amplitude(m_stepState[i]);
waveform[i].frequency(frequency[i]);
}
}
}
float Sequencer::mapper(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;
}
void Sequencer::buttonsAbfragen(int zaehler, int digitalPin)
{
buttonState[zaehler] = digitalRead(digitalPin);
// delayMicroseconds(50);
// Serial.print(buttonState[zaehler]);
// Serial.print(",");
}
long Sequencer::encoder()
{
long newEnc1;
newEnc1 = Enc1.read();
Serial.println(newEnc1);
if (newEnc1 != positionEnc1)
{
positionEnc1 = newEnc1;
}
return newEnc1;
}
void Sequencer::muxUpdate()
{
for (int i = 0; i <= 7; i++)
{
bit1 = bitRead(i, 0);
bit2 = bitRead(i, 1);
bit3 = bitRead(i, 2);
digitalWrite(pin_Out_S0, bit1);
digitalWrite(pin_Out_S1, bit2);
digitalWrite(pin_Out_S2, bit3);
buttonsAbfragen(i, 14); // Mux 1
buttonsAbfragen(i + 8, 15); // Mux 2
buttonsAbfragen(i + 16, 16); // Mux 3
buttonsAbfragen(i + 24, 17); // Mux 4
buttonsAbfragen(i + 32, 18); // Mux 5
buttonsAbfragen(i + 40, 19); // Mux 6
}
}
void Sequencer::update()
{
encoder();
stepButtons();
stepLED();
muxUpdate();
}