mirror of
https://github.com/erik-toth/audio-synth.git
synced 2025-12-06 11:20:02 +00:00
161 lines
4.3 KiB
C++
161 lines
4.3 KiB
C++
/*
|
|
@file: FIRMARE.h
|
|
@author: Erik Tóth
|
|
@contact: etoth@tsn.at
|
|
@date: 2025-10-26
|
|
@updated: 2025-12-06
|
|
@brief: Header for FIRMWARE.cpp (FIXED VERSION)
|
|
*/
|
|
#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
|
|
|
|
struct Key
|
|
{
|
|
int row;
|
|
int col;
|
|
};
|
|
|
|
struct DualVoltageDurationPair
|
|
{
|
|
uint16_t voltage_ch1;
|
|
uint16_t voltage_ch2;
|
|
uint16_t duration;
|
|
bool active; // NEU: true wenn Step aktive Noten hat, false für Pausen
|
|
};
|
|
|
|
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 maxStepCount);
|
|
|
|
// Aufnahme-Funktionen
|
|
void startRecord();
|
|
void stopRecord();
|
|
void addStep(uint16_t voltage_ch1, uint16_t voltage_ch2);
|
|
bool isRecording();
|
|
|
|
// Wiedergabe-Funktionen
|
|
void startPlay();
|
|
void stopPlay();
|
|
void update();
|
|
bool isPlaying();
|
|
|
|
// Sequenz-Verwaltung
|
|
void clear();
|
|
void setLoop(bool loop);
|
|
|
|
// Status-Abfragen
|
|
bool timeLimitReached();
|
|
bool stepLimitReached();
|
|
uint16_t getStepCount();
|
|
uint16_t getCurrentVoltageCh1();
|
|
uint16_t getCurrentVoltageCh2();
|
|
bool isCurrentStepActive(); // NEU: Prüft ob aktueller Step aktive Noten hat
|
|
uint16_t getTotalDuration();
|
|
|
|
private:
|
|
/*!
|
|
* @brief Memory limiting
|
|
* @return (uint16_t) 1024
|
|
* @attention Increasing the value might lead to an overflow
|
|
* @note sizeOf(DualVoltageDurationPair) = 8 Byte ==> 8 Byte * 1024 = 8192 Byte
|
|
*/
|
|
const static uint16_t _MAX_SEQUENCE_STEPS = 1024;
|
|
|
|
// Sequenz memory
|
|
DualVoltageDurationPair _sequence[_MAX_SEQUENCE_STEPS];
|
|
uint16_t _stepCount;
|
|
uint16_t _currentStep;
|
|
|
|
// Time management
|
|
uint16_t _maxDurationMS;
|
|
uint16_t _maxStepCount;
|
|
unsigned long _recordStartTime;
|
|
unsigned long _lastStepTime;
|
|
unsigned long _playStartTime;
|
|
unsigned long _stepStartTime;
|
|
unsigned long _lastAddStepTime; // NEU: Rate-Limiting
|
|
|
|
// Status flags
|
|
bool _isRecording;
|
|
bool _isPlaying;
|
|
bool _loop;
|
|
|
|
// Last recorded Voltage: at n-th step minus one
|
|
uint16_t _lastVoltageCh1;
|
|
uint16_t _lastVoltageCh2;
|
|
|
|
// helper functions
|
|
void _finishCurrentStep();
|
|
bool _canAddStep();
|
|
};
|
|
|
|
#endif |