-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathConfig.h
More file actions
80 lines (71 loc) · 3.66 KB
/
Config.h
File metadata and controls
80 lines (71 loc) · 3.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#pragma once
#include <Arduino.h>
// ---------------------------------------------------------------------------
// MiniLoopDeck - global configuration
// ---------------------------------------------------------------------------
// Lo-Fi sample looper for the M5Stack Core2.
//
// Important hardware constraint: on the Core2 the microphone (SPM1423 PDM)
// and the speaker amp share the same I2S peripheral, so they can NOT run at
// the same time. The deck therefore works in two phases:
// 1) record ONE track (speaker off)
// 2) loop ALL tracks mixed together (mic off)
// True live-overdub while the speaker plays is not possible on this board.
// ---------------------------------------------------------------------------
// Audio format -------------------------------------------------------------
static constexpr uint32_t SAMPLE_RATE = 16000; // 16 kHz, lo-fi but plenty
static constexpr uint8_t NUM_TRACKS = 4; // 2-4 recommended
static constexpr uint32_t MAX_SECONDS = 10; // max loop length per track
static constexpr uint32_t MAX_SAMPLES = SAMPLE_RATE * MAX_SECONDS; // per track
// Engine internals ---------------------------------------------------------
static constexpr size_t REC_CHUNK = 1024; // samples queued per service
static constexpr uint8_t MASTER_VOLUME = 200; // 0..255
// Mic/PDM + DC filter need to settle after begin(); discard this many samples
// before recording, otherwise every take starts with an audible click/pop.
static constexpr uint32_t MIC_WARMUP_SAMPLES = SAMPLE_RATE / 8; // ~125 ms
// Loop matching ------------------------------------------------------------
// Onset trim: drop leading silence so the loop starts on the first hit.
static constexpr int32_t ONSET_FLOOR = 200; // min threshold
static constexpr uint32_t ONSET_PREROLL = SAMPLE_RATE * 5 / 1000; // keep 5 ms attack
// Seam smoothing: tiny linear fade at both ends to kill the loop-point click.
static constexpr uint32_t FADE_SAMPLES = SAMPLE_RATE * 3 / 1000; // ~3 ms
// Remote (StickS3) takes: drop the tail so the KEY1-release transient that the
// mic picks up at the end of a take is removed before looping.
static constexpr uint32_t REMOTE_TAIL_TRIM = SAMPLE_RATE * 90 / 1000; // ~90 ms
// Auto-align: nudge a follower loop to best-match the master groove.
static constexpr uint32_t ALIGN_WINDOW = SAMPLE_RATE * 60 / 1000; // +/- 60 ms
static constexpr uint32_t ALIGN_DECIM = 8; // correlation stride
static constexpr uint32_t ALIGN_CMP_LEN = SAMPLE_RATE; // compare 1 s max
// Visual metronome subdivides the master loop into this many beats.
static constexpr uint8_t BEATS_PER_LOOP = 4;
static constexpr uint32_t BEAT_FLASH_MS = 90;
// Effects ------------------------------------------------------------------
enum Fx : uint8_t {
FX_NONE = 0,
FX_REVERSE,
FX_BITCRUSH,
FX_LOFI,
FX_DRIVE,
FX_ECHO,
FX_COUNT
};
static const char* const FX_NAMES[FX_COUNT] = {
"DRY", "REVERSE", "CRUSH", "LOFI", "DRIVE", "ECHO"
};
// Effect tuning
static constexpr uint32_t ECHO_DELAY = SAMPLE_RATE / 4; // 0.25 s slap-back
static constexpr uint8_t LOFI_DECIM = 4; // sample-and-hold factor
static constexpr int16_t CRUSH_MASK = (int16_t)0xF000; // keep top 4 bits
static constexpr int32_t DRIVE_GAIN = 4; // pre-clip gain
// Deck state machine -------------------------------------------------------
enum DeckState : uint8_t {
STATE_IDLE = 0,
STATE_RECORDING,
STATE_PLAYING
};
// Saturating 32 -> 16 bit conversion used all over the mixer.
static inline int16_t clip16(int32_t v) {
if (v > 32767) return 32767;
if (v < -32768) return -32768;
return (int16_t)v;
}