Files
audio-synth/dev/digital/Firmware_TEST/include/FIRMWARE.h
Erik Tóth b3d66fdfd8 Software Update 4: Sequencer Block
Sequencer Klasse eingebaut
  Überprüfung noch ausständig
2025-11-17 09:28:48 +01:00

147 lines
3.5 KiB
C++

/*
@file: FIRMARE.h
@author: Erik Tóth
@contact: etoth@tsn.at
@date: 2025-10-26
@brief: Header for FIRMWARE.cpp
*/
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_MCP4728.h>
#ifndef FIRMWARE_H
#define FIRMWARE_H
#define N_MAX_QUEUE 10
#define N_MAX_ROWS 8
#define N_MAX_COLS 8
#define MS_DEBOUNCE 20
#define N_MAX_DAC_CH 4
#define N_MAX_SEQUENCE_STEPS 128
struct Key
{
int row;
int col;
};
struct voltageDurationPair
{
uint16_t voltage;
uint16_t duration;
};
const Key NOT_A_KEY = {-1, -1};
bool isNotKey(Key k);
bool isEqualKey(Key k1, Key k2);
class Keyboard
{
public:
Keyboard(uint8_t nRows, uint8_t nCols, uint8_t *pinsRow, uint8_t *pinsCol);
void begin();
void update();
int getQueueLength();
Key getQueue(uint8_t index);
private:
uint8_t _nRows;
uint8_t _nCols;
uint8_t *_pinsRow;
uint8_t *_pinsCol;
bool _keyState[N_MAX_COLS][N_MAX_ROWS];
bool _keyStateLatest[N_MAX_COLS][N_MAX_ROWS];
unsigned long _lastChangeTime[N_MAX_COLS][N_MAX_ROWS];
Key _activeKeys[N_MAX_QUEUE];
uint8_t _nActiveKeys;
uint8_t _nSticky;
void _addActiveKey(uint8_t row, uint8_t col);
void _removeActiveKey(uint8_t row, uint8_t col);
bool _inQueue(uint8_t row, uint8_t col);
bool _inQueue(Key k);
bool _isNotKey(Key k);
bool _isEqualKey(Key k1, Key k2);
};
class CV
{
public:
CV(Adafruit_MCP4728 *dac, TwoWire *wire, uint8_t nCV, MCP4728_channel_t *cvChannelMap, uint16_t *keyToVoltage, uint8_t row, uint8_t col);
bool begin(uint8_t pinSDA, uint8_t pinSCL);
void setVoltage(uint8_t cvIndex, Key k);
void setVoltage(uint8_t cvIndex, uint16_t mV);
void clearAll();
private:
Adafruit_MCP4728 *_dac;
TwoWire *_wire;
uint8_t _nCV;
uint8_t _row;
uint8_t _col;
MCP4728_channel_t _cvChannelMap[N_MAX_DAC_CH];
uint16_t *_keyToVoltage;
uint8_t _getKeyToVoltageIndex(uint8_t row, uint8_t col);
uint8_t _getKeyToVoltageIndex(Key k);
};
class SequencerBlock
{
public:
SequencerBlock(uint16_t maxDurationMS, uint16_t timeoutMS);
// Aufnahme-Funktionen
void startRecord();
void stopRecord();
void addStep(uint16_t voltage);
bool isRecording();
// Wiedergabe-Funktionen
void startPlay();
void stopPlay();
void update(); // Muss regelmäßig aufgerufen werden
bool isPlaying();
// Sequenz-Verwaltung
void clear();
void setLoop(bool loop);
// Status-Abfragen
bool timeLimitReached();
uint8_t getStepCount();
uint16_t getCurrentVoltage();
uint16_t getTotalDuration();
private:
// Sequenz-Speicher
voltageDurationPair _sequence[N_MAX_SEQUENCE_STEPS];
uint8_t _stepCount;
uint8_t _currentStep;
// Zeitverwaltung
uint16_t _maxDurationMS;
uint16_t _timeoutMS;
unsigned long _recordStartTime;
unsigned long _lastStepTime;
unsigned long _playStartTime;
unsigned long _stepStartTime;
// Status-Flags
bool _isRecording;
bool _isPlaying;
bool _loop;
// Letzte aufgenommene Spannung
uint16_t _lastVoltage;
// Hilfsfunktionen
void _finishCurrentStep();
bool _canAddStep();
};
#endif