mirror of
https://github.com/erik-toth/audio-synth.git
synced 2025-12-06 08:40: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
|
||||
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]
|
||||
Name=ProjectTitle
|
||||
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.
@@ -16,9 +16,7 @@
|
||||
#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
|
||||
{
|
||||
@@ -94,7 +92,7 @@ class CV
|
||||
class SequencerBlock
|
||||
{
|
||||
public:
|
||||
SequencerBlock(uint16_t maxDurationMS, uint16_t minStepDurationMS);
|
||||
SequencerBlock(uint16_t maxDurationMS, uint16_t maxStepCount);
|
||||
|
||||
// Aufnahme-Funktionen
|
||||
void startRecord();
|
||||
@@ -105,7 +103,7 @@ class SequencerBlock
|
||||
// Wiedergabe-Funktionen
|
||||
void startPlay();
|
||||
void stopPlay();
|
||||
void update(); // Muss regelmäßig aufgerufen werden
|
||||
void update();
|
||||
bool isPlaying();
|
||||
|
||||
// Sequenz-Verwaltung
|
||||
@@ -114,35 +112,44 @@ class SequencerBlock
|
||||
|
||||
// Status-Abfragen
|
||||
bool timeLimitReached();
|
||||
uint8_t getStepCount();
|
||||
bool stepLimitReached();
|
||||
uint16_t getStepCount();
|
||||
uint16_t getCurrentVoltageCh1();
|
||||
uint16_t getCurrentVoltageCh2();
|
||||
uint16_t getTotalDuration();
|
||||
|
||||
private:
|
||||
// Sequenz-Speicher
|
||||
DualVoltageDurationPair _sequence[N_MAX_SEQUENCE_STEPS];
|
||||
uint8_t _stepCount;
|
||||
uint8_t _currentStep;
|
||||
/*!
|
||||
* @brief Memory limiting
|
||||
* @return (uint16_t) 1024
|
||||
* @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 _minStepDurationMS;
|
||||
uint16_t _maxStepCount;
|
||||
unsigned long _recordStartTime;
|
||||
unsigned long _lastStepTime;
|
||||
unsigned long _playStartTime;
|
||||
unsigned long _stepStartTime;
|
||||
|
||||
// Status-Flags
|
||||
// Status flags
|
||||
bool _isRecording;
|
||||
bool _isPlaying;
|
||||
bool _loop;
|
||||
|
||||
// Letzte aufgenommene Spannungen
|
||||
// Last recorded Voltage: at n-th step minus one
|
||||
uint16_t _lastVoltageCh1;
|
||||
uint16_t _lastVoltageCh2;
|
||||
|
||||
// Hilfsfunktionen
|
||||
// helper functions
|
||||
void _finishCurrentStep();
|
||||
bool _canAddStep();
|
||||
};
|
||||
|
||||
@@ -11,11 +11,12 @@
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
// CONSTANTS DEFINITONS
|
||||
#define N_KEYBOARD_ROW 4
|
||||
#define N_KEYBOARD_COL 3
|
||||
#define N_KEYBOARD_ROW 4 // for PROD. change to 5
|
||||
#define N_KEYBOARD_COL 3 // for PROD. change to 5
|
||||
#define N_CV_GATES 2
|
||||
#define N_SB 2
|
||||
#define BAUDRATE 115200
|
||||
#define N_MAX_SEQ_STEPS 512
|
||||
// PIN DEFENTITIONS
|
||||
// I2C PINS
|
||||
#define PIN_SDA 15
|
||||
@@ -25,15 +26,22 @@
|
||||
#define PIN_K_R1 8
|
||||
#define PIN_K_R2 9
|
||||
#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_C1 2
|
||||
#define PIN_K_C2 4
|
||||
#define PIN_K_C3 // 5 NOT IN USE
|
||||
#define PIN_K_C4 // 6 NOT IN USE
|
||||
#define PIN_K_C3 5 // DEV. not in use
|
||||
#define PIN_K_C4 6 // DEV. not in use
|
||||
// SEQUENCER BUTTON PINS
|
||||
#define PIN_SB_1_REC 37 // 33 not available on dev board
|
||||
#define PIN_SB_1_PLAY 38 // 34 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 // for PROD. change to 34 / not available on dev board
|
||||
#define PIN_SB_2_REC 35
|
||||
#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
|
||||
@@ -235,12 +235,12 @@ uint8_t CV::_getKeyToVoltageIndex(Key k)
|
||||
|
||||
/*!
|
||||
* @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;
|
||||
_minStepDurationMS = minStepDurationMS;
|
||||
_maxStepCount = maxStepCount;
|
||||
_stepCount = 0;
|
||||
_currentStep = 0;
|
||||
_isRecording = false;
|
||||
@@ -386,7 +386,7 @@ void SequencerBlock::clear()
|
||||
_lastVoltageCh1 = 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_ch2 = 0;
|
||||
@@ -409,7 +409,12 @@ bool SequencerBlock::timeLimitReached()
|
||||
return (elapsed >= _maxDurationMS);
|
||||
}
|
||||
|
||||
uint8_t SequencerBlock::getStepCount()
|
||||
bool SequencerBlock::stepLimitReached()
|
||||
{
|
||||
return (_stepCount >= _maxStepCount);
|
||||
}
|
||||
|
||||
uint16_t SequencerBlock::getStepCount()
|
||||
{
|
||||
return _stepCount;
|
||||
}
|
||||
@@ -447,21 +452,13 @@ void SequencerBlock::_finishCurrentStep()
|
||||
unsigned long now = millis();
|
||||
uint16_t duration = now - _lastStepTime;
|
||||
|
||||
// Nur Steps mit ausreichender Dauer speichern
|
||||
if(duration >= _minStepDurationMS)
|
||||
{
|
||||
_sequence[_stepCount - 1].duration = duration;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Step war zu kurz, verwerfen
|
||||
_stepCount--;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
/*
|
||||
* 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.h"
|
||||
@@ -12,17 +15,17 @@ Keyboard keyboard(N_KEYBOARD_ROW, N_KEYBOARD_COL, pins_keyboard_row, pins_keyboa
|
||||
Adafruit_MCP4728 MCP4728;
|
||||
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 */
|
||||
1*83, 5*83, 9*83,
|
||||
2*83, 6*83, 10*83,
|
||||
3*83, 7*83, 11*83,
|
||||
4*83, 8*83, 12*83
|
||||
1*83, 5*83, 9*83, /* ROW 1: B D Fis */
|
||||
2*83, 6*83, 10*83, /* ROW 2: H Dis G */
|
||||
3*83, 7*83, 11*83, /* ROW 3: C E Gis */
|
||||
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);
|
||||
|
||||
// Sequencer mit 30s max, 50ms Mindest-Step-Dauer
|
||||
SequencerBlock sb1(30000, 50);
|
||||
SequencerBlock sb2(30000, 50);
|
||||
// Sequencer 30s max, 512 max Steps
|
||||
SequencerBlock sb1(30000, N_MAX_SEQ_STEPS);
|
||||
SequencerBlock sb2(30000, N_MAX_SEQ_STEPS);
|
||||
|
||||
// Button States
|
||||
struct ButtonState {
|
||||
|
||||
Reference in New Issue
Block a user