mirror of
https://github.com/erik-toth/audio-synth.git
synced 2025-12-06 10:00:02 +00:00
Firmware MCU: Update sequencer block to support dynamic step count and enhance documentation
This commit is contained in:
@@ -66,6 +66,23 @@ DItemRevisionGUID=
|
|||||||
GenerateClassCluster=0
|
GenerateClassCluster=0
|
||||||
DocumentUniqueId=QMXNWCKL
|
DocumentUniqueId=QMXNWCKL
|
||||||
|
|
||||||
|
[Document2]
|
||||||
|
DocumentPath=ESP32-S3.Harness
|
||||||
|
AnnotationEnabled=1
|
||||||
|
AnnotateStartValue=1
|
||||||
|
AnnotationIndexControlEnabled=0
|
||||||
|
AnnotateSuffix=
|
||||||
|
AnnotateScope=All
|
||||||
|
AnnotateOrder=-1
|
||||||
|
DoLibraryUpdate=1
|
||||||
|
DoDatabaseUpdate=1
|
||||||
|
ClassGenCCAutoEnabled=1
|
||||||
|
ClassGenCCAutoRoomEnabled=0
|
||||||
|
ClassGenNCAutoScope=None
|
||||||
|
DItemRevisionGUID=
|
||||||
|
GenerateClassCluster=0
|
||||||
|
DocumentUniqueId=
|
||||||
|
|
||||||
[Parameter1]
|
[Parameter1]
|
||||||
Name=ProjectTitle
|
Name=ProjectTitle
|
||||||
Value=ESP32-S3
|
Value=ESP32-S3
|
||||||
|
|||||||
BIN
dev/digital/ESP32-S3/History/ESP32-S3.~(3).PrjPcb.Zip
Normal file
BIN
dev/digital/ESP32-S3/History/ESP32-S3.~(3).PrjPcb.Zip
Normal file
Binary file not shown.
@@ -12,13 +12,11 @@
|
|||||||
#ifndef FIRMWARE_H
|
#ifndef FIRMWARE_H
|
||||||
#define FIRMWARE_H
|
#define FIRMWARE_H
|
||||||
|
|
||||||
#define N_MAX_QUEUE 10
|
#define N_MAX_QUEUE 10
|
||||||
#define N_MAX_ROWS 8
|
#define N_MAX_ROWS 8
|
||||||
#define N_MAX_COLS 8
|
#define N_MAX_COLS 8
|
||||||
#define MS_DEBOUNCE 20
|
#define MS_DEBOUNCE 20
|
||||||
|
#define N_MAX_DAC_CH 4
|
||||||
#define N_MAX_DAC_CH 4
|
|
||||||
#define N_MAX_SEQUENCE_STEPS 128
|
|
||||||
|
|
||||||
struct Key
|
struct Key
|
||||||
{
|
{
|
||||||
@@ -94,7 +92,7 @@ class CV
|
|||||||
class SequencerBlock
|
class SequencerBlock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SequencerBlock(uint16_t maxDurationMS, uint16_t minStepDurationMS);
|
SequencerBlock(uint16_t maxDurationMS, uint16_t maxStepCount);
|
||||||
|
|
||||||
// Aufnahme-Funktionen
|
// Aufnahme-Funktionen
|
||||||
void startRecord();
|
void startRecord();
|
||||||
@@ -105,7 +103,7 @@ class SequencerBlock
|
|||||||
// Wiedergabe-Funktionen
|
// Wiedergabe-Funktionen
|
||||||
void startPlay();
|
void startPlay();
|
||||||
void stopPlay();
|
void stopPlay();
|
||||||
void update(); // Muss regelmäßig aufgerufen werden
|
void update();
|
||||||
bool isPlaying();
|
bool isPlaying();
|
||||||
|
|
||||||
// Sequenz-Verwaltung
|
// Sequenz-Verwaltung
|
||||||
@@ -114,35 +112,44 @@ class SequencerBlock
|
|||||||
|
|
||||||
// Status-Abfragen
|
// Status-Abfragen
|
||||||
bool timeLimitReached();
|
bool timeLimitReached();
|
||||||
uint8_t getStepCount();
|
bool stepLimitReached();
|
||||||
|
uint16_t getStepCount();
|
||||||
uint16_t getCurrentVoltageCh1();
|
uint16_t getCurrentVoltageCh1();
|
||||||
uint16_t getCurrentVoltageCh2();
|
uint16_t getCurrentVoltageCh2();
|
||||||
uint16_t getTotalDuration();
|
uint16_t getTotalDuration();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Sequenz-Speicher
|
/*!
|
||||||
DualVoltageDurationPair _sequence[N_MAX_SEQUENCE_STEPS];
|
* @brief Memory limiting
|
||||||
uint8_t _stepCount;
|
* @return (uint16_t) 1024
|
||||||
uint8_t _currentStep;
|
* @attention Increasing the value might lead to an overflow
|
||||||
|
* @note sizeOf(DualVoltageDurationPair) = 6 Byte ==> 6 Byte * 1024 = 6144 Byte
|
||||||
|
*/
|
||||||
|
const static uint16_t _MAX_SEQUENCE_STEPS = 1024;
|
||||||
|
|
||||||
// Zeitverwaltung
|
// Sequenz memory
|
||||||
|
DualVoltageDurationPair _sequence[_MAX_SEQUENCE_STEPS];
|
||||||
|
uint16_t _stepCount;
|
||||||
|
uint16_t _currentStep;
|
||||||
|
|
||||||
|
// Time management
|
||||||
uint16_t _maxDurationMS;
|
uint16_t _maxDurationMS;
|
||||||
uint16_t _minStepDurationMS;
|
uint16_t _maxStepCount;
|
||||||
unsigned long _recordStartTime;
|
unsigned long _recordStartTime;
|
||||||
unsigned long _lastStepTime;
|
unsigned long _lastStepTime;
|
||||||
unsigned long _playStartTime;
|
unsigned long _playStartTime;
|
||||||
unsigned long _stepStartTime;
|
unsigned long _stepStartTime;
|
||||||
|
|
||||||
// Status-Flags
|
// Status flags
|
||||||
bool _isRecording;
|
bool _isRecording;
|
||||||
bool _isPlaying;
|
bool _isPlaying;
|
||||||
bool _loop;
|
bool _loop;
|
||||||
|
|
||||||
// Letzte aufgenommene Spannungen
|
// Last recorded Voltage: at n-th step minus one
|
||||||
uint16_t _lastVoltageCh1;
|
uint16_t _lastVoltageCh1;
|
||||||
uint16_t _lastVoltageCh2;
|
uint16_t _lastVoltageCh2;
|
||||||
|
|
||||||
// Hilfsfunktionen
|
// helper functions
|
||||||
void _finishCurrentStep();
|
void _finishCurrentStep();
|
||||||
bool _canAddStep();
|
bool _canAddStep();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,11 +11,12 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
// CONSTANTS DEFINITONS
|
// CONSTANTS DEFINITONS
|
||||||
#define N_KEYBOARD_ROW 4
|
#define N_KEYBOARD_ROW 4 // for PROD. change to 5
|
||||||
#define N_KEYBOARD_COL 3
|
#define N_KEYBOARD_COL 3 // for PROD. change to 5
|
||||||
#define N_CV_GATES 2
|
#define N_CV_GATES 2
|
||||||
#define N_SB 2
|
#define N_SB 2
|
||||||
#define BAUDRATE 115200
|
#define BAUDRATE 115200
|
||||||
|
#define N_MAX_SEQ_STEPS 512
|
||||||
// PIN DEFENTITIONS
|
// PIN DEFENTITIONS
|
||||||
// I2C PINS
|
// I2C PINS
|
||||||
#define PIN_SDA 15
|
#define PIN_SDA 15
|
||||||
@@ -25,15 +26,22 @@
|
|||||||
#define PIN_K_R1 8
|
#define PIN_K_R1 8
|
||||||
#define PIN_K_R2 9
|
#define PIN_K_R2 9
|
||||||
#define PIN_K_R3 10
|
#define PIN_K_R3 10
|
||||||
#define PIN_K_R4 // 11 NOT IN USE
|
#define PIN_K_R4 11 // DEV. not in use
|
||||||
#define PIN_K_C0 1
|
#define PIN_K_C0 1
|
||||||
#define PIN_K_C1 2
|
#define PIN_K_C1 2
|
||||||
#define PIN_K_C2 4
|
#define PIN_K_C2 4
|
||||||
#define PIN_K_C3 // 5 NOT IN USE
|
#define PIN_K_C3 5 // DEV. not in use
|
||||||
#define PIN_K_C4 // 6 NOT IN USE
|
#define PIN_K_C4 6 // DEV. not in use
|
||||||
// SEQUENCER BUTTON PINS
|
// SEQUENCER BUTTON PINS
|
||||||
#define PIN_SB_1_REC 37 // 33 not available on dev board
|
#define PIN_SB_1_REC 37 // for PROD. change to 33 / not available on dev board
|
||||||
#define PIN_SB_1_PLAY 38 // 34 not available on dev board
|
#define PIN_SB_1_PLAY 38 // for PROD. change to 34 / not available on dev board
|
||||||
#define PIN_SB_2_REC 35
|
#define PIN_SB_2_REC 35
|
||||||
#define PIN_SB_2_PLAY 36
|
#define PIN_SB_2_PLAY 36
|
||||||
|
// MISC/INFO PINS
|
||||||
|
#define PIN_ACTIVE -1 // TODO: if any key is played return HIGH
|
||||||
|
#define PIN_REC -1 // TODO: if any sb is recording return HIGH
|
||||||
|
#define PIN_BPM -1 // TODO: get bpm through potentiometer analog value
|
||||||
|
#define PIN_B_METRONOME -1 // TODO: button activates/deactivates bpm led output
|
||||||
|
#define PIN_L_METRONOME -1 // TODO: led blinks according to bpm value
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -235,12 +235,12 @@ uint8_t CV::_getKeyToVoltageIndex(Key k)
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @param maxDurationMS maximum loop duration of recording in milliseconds
|
* @param maxDurationMS maximum loop duration of recording in milliseconds
|
||||||
* @param minStepDurationMS minimum duration for a step to be recorded (prevents ultra-short steps)
|
* @param maxStepCount maximum number of steps that can be recorded
|
||||||
*/
|
*/
|
||||||
SequencerBlock::SequencerBlock(uint16_t maxDurationMS, uint16_t minStepDurationMS)
|
SequencerBlock::SequencerBlock(uint16_t maxDurationMS, uint16_t maxStepCount)
|
||||||
{
|
{
|
||||||
_maxDurationMS = maxDurationMS;
|
_maxDurationMS = maxDurationMS;
|
||||||
_minStepDurationMS = minStepDurationMS;
|
_maxStepCount = maxStepCount;
|
||||||
_stepCount = 0;
|
_stepCount = 0;
|
||||||
_currentStep = 0;
|
_currentStep = 0;
|
||||||
_isRecording = false;
|
_isRecording = false;
|
||||||
@@ -386,7 +386,7 @@ void SequencerBlock::clear()
|
|||||||
_lastVoltageCh1 = 0;
|
_lastVoltageCh1 = 0;
|
||||||
_lastVoltageCh2 = 0;
|
_lastVoltageCh2 = 0;
|
||||||
|
|
||||||
for(uint8_t i = 0; i < N_MAX_SEQUENCE_STEPS; i++)
|
for(uint8_t i = 0; i < _MAX_SEQUENCE_STEPS; i++)
|
||||||
{
|
{
|
||||||
_sequence[i].voltage_ch1 = 0;
|
_sequence[i].voltage_ch1 = 0;
|
||||||
_sequence[i].voltage_ch2 = 0;
|
_sequence[i].voltage_ch2 = 0;
|
||||||
@@ -409,7 +409,12 @@ bool SequencerBlock::timeLimitReached()
|
|||||||
return (elapsed >= _maxDurationMS);
|
return (elapsed >= _maxDurationMS);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t SequencerBlock::getStepCount()
|
bool SequencerBlock::stepLimitReached()
|
||||||
|
{
|
||||||
|
return (_stepCount >= _maxStepCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t SequencerBlock::getStepCount()
|
||||||
{
|
{
|
||||||
return _stepCount;
|
return _stepCount;
|
||||||
}
|
}
|
||||||
@@ -447,21 +452,13 @@ void SequencerBlock::_finishCurrentStep()
|
|||||||
unsigned long now = millis();
|
unsigned long now = millis();
|
||||||
uint16_t duration = now - _lastStepTime;
|
uint16_t duration = now - _lastStepTime;
|
||||||
|
|
||||||
// Nur Steps mit ausreichender Dauer speichern
|
_sequence[_stepCount - 1].duration = duration;
|
||||||
if(duration >= _minStepDurationMS)
|
|
||||||
{
|
|
||||||
_sequence[_stepCount - 1].duration = duration;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Step war zu kurz, verwerfen
|
|
||||||
_stepCount--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SequencerBlock::_canAddStep()
|
bool SequencerBlock::_canAddStep()
|
||||||
{
|
{
|
||||||
if(_stepCount >= N_MAX_SEQUENCE_STEPS) return false;
|
if(_stepCount >= _maxStepCount) return false;
|
||||||
|
if(_stepCount >= _MAX_SEQUENCE_STEPS) return false;
|
||||||
if(timeLimitReached()) return false;
|
if(timeLimitReached()) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* Example Code Three - Dual Channel Sequencer
|
* Example Code Three - Dual Channel Sequencer
|
||||||
|
* TODO:
|
||||||
|
- add predefined sequence of voltage (e.g. for usage as startup sound)
|
||||||
|
- implement INFO and MISC pins form file FIRMWARE_DEF.h
|
||||||
*/
|
*/
|
||||||
#include "FIRMWARE_DEF.h"
|
#include "FIRMWARE_DEF.h"
|
||||||
#include "FIRMWARE.h"
|
#include "FIRMWARE.h"
|
||||||
@@ -12,17 +15,17 @@ Keyboard keyboard(N_KEYBOARD_ROW, N_KEYBOARD_COL, pins_keyboard_row, pins_keyboa
|
|||||||
Adafruit_MCP4728 MCP4728;
|
Adafruit_MCP4728 MCP4728;
|
||||||
MCP4728_channel_t cvMap[N_CV_GATES] = {MCP4728_CHANNEL_A, MCP4728_CHANNEL_B};
|
MCP4728_channel_t cvMap[N_CV_GATES] = {MCP4728_CHANNEL_A, MCP4728_CHANNEL_B};
|
||||||
uint16_t keyToVoltage[N_KEYBOARD_ROW*N_KEYBOARD_COL] = { /* 83mV = 1/12V */
|
uint16_t keyToVoltage[N_KEYBOARD_ROW*N_KEYBOARD_COL] = { /* 83mV = 1/12V */
|
||||||
1*83, 5*83, 9*83,
|
1*83, 5*83, 9*83, /* ROW 1: B D Fis */
|
||||||
2*83, 6*83, 10*83,
|
2*83, 6*83, 10*83, /* ROW 2: H Dis G */
|
||||||
3*83, 7*83, 11*83,
|
3*83, 7*83, 11*83, /* ROW 3: C E Gis */
|
||||||
4*83, 8*83, 12*83
|
4*83, 8*83, 12*83 /* ROW 4: Cis F A' */
|
||||||
};
|
};
|
||||||
|
|
||||||
CV cv(&MCP4728, &Wire, N_CV_GATES, cvMap, keyToVoltage, N_KEYBOARD_ROW, N_KEYBOARD_COL);
|
CV cv(&MCP4728, &Wire, N_CV_GATES, cvMap, keyToVoltage, N_KEYBOARD_ROW, N_KEYBOARD_COL);
|
||||||
|
|
||||||
// Sequencer mit 30s max, 50ms Mindest-Step-Dauer
|
// Sequencer 30s max, 512 max Steps
|
||||||
SequencerBlock sb1(30000, 50);
|
SequencerBlock sb1(30000, N_MAX_SEQ_STEPS);
|
||||||
SequencerBlock sb2(30000, 50);
|
SequencerBlock sb2(30000, N_MAX_SEQ_STEPS);
|
||||||
|
|
||||||
// Button States
|
// Button States
|
||||||
struct ButtonState {
|
struct ButtonState {
|
||||||
|
|||||||
Reference in New Issue
Block a user