Deluge Firmware
1.3.0
Build date: 2026.08.29
Toggle main menu visibility
Loading...
Searching...
No Matches
encoders.h
1
/*
2
* Copyright © 2020-2023 Synthstrom Audible Limited
3
*
4
* This file is part of The Synthstrom Audible Deluge Firmware.
5
*
6
* The Synthstrom Audible Deluge Firmware is free software: you can redistribute it and/or modify it under the
7
* terms of the GNU General Public License as published by the Free Software Foundation,
8
* either version 3 of the License, or (at your option) any later version.
9
*
10
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
11
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
* See the GNU General Public License for more details.
13
*
14
* You should have received a copy of the GNU General Public License along with this program.
15
* If not, see <https://www.gnu.org/licenses/>.
16
*/
17
18
#pragma once
19
20
#include "OSLikeStuff/scheduler_api.h"
21
#include <atomic>
22
#include <cstddef>
23
#include <cstdint>
24
25
namespace
deluge::hid::encoders {
26
29
class
DetentedEncoder {
30
public
:
31
DetentedEncoder() =
default
;
32
DetentedEncoder(
const
DetentedEncoder&) =
delete
;
33
DetentedEncoder& operator=(
const
DetentedEncoder&) =
delete
;
34
35
void
applyEdges(int8_t edges);
36
38
bool
pending
()
const
{
return
pos
.load(std::memory_order_relaxed) != 0; }
39
41
int32_t
take
();
42
45
void
restore
(int32_t val) {
pos
.fetch_add(val, std::memory_order_relaxed); }
46
47
private
:
48
int32_t
edgeAccumulator
= 0;
49
std::atomic_int32_t
pos
= 0;
50
};
51
53
class
ContinuousEncoder {
54
public
:
55
ContinuousEncoder() =
default
;
56
ContinuousEncoder(
const
ContinuousEncoder&) =
delete
;
57
ContinuousEncoder& operator=(
const
ContinuousEncoder&) =
delete
;
58
59
void
applyEdges(int8_t edges) {
pos
.fetch_add(edges, std::memory_order_relaxed); }
60
62
bool
pending
()
const
{
return
pos
.load(std::memory_order_relaxed) != 0; }
63
65
int8_t
take
();
66
68
double
calcNextKnobSpeed
(int8_t offset);
69
70
private
:
71
std::atomic_int8_t
pos
= 0;
72
double
currentKnobSpeed{0.0};
// Used for encoder acceleration
73
};
74
75
// ── Named encoder globals ─────────────────────────────────────────────────
76
77
extern
DetentedEncoder scrollY;
78
extern
DetentedEncoder scrollX;
79
extern
DetentedEncoder tempo;
80
extern
DetentedEncoder select;
81
extern
ContinuousEncoder mod0;
82
extern
ContinuousEncoder mod1;
83
84
// ── Array-index access for iteration ─────────────────────────────────────
85
86
constexpr
size_t
kNumFunctionEncoders = 4;
87
constexpr
size_t
kNumModEncoders = 2;
88
89
DetentedEncoder& functionEncoderAt(
size_t
i);
90
ContinuousEncoder& modEncoderAt(
size_t
i);
91
92
// ── Shared timestamp ──────────────────────────────────────────────────────
93
96
extern
uint32_t timeModEncoderLastTurned[];
97
98
// ── Lifecycle ─────────────────────────────────────────────────────────────
99
100
void
init();
101
104
extern
TaskID EncoderTaskID;
105
106
}
// namespace deluge::hid::encoders
deluge::hid::encoders::ContinuousEncoder::pending
bool pending() const
True if any ticks are waiting to be consumed.
Definition
encoders.h:62
deluge::hid::encoders::ContinuousEncoder::take
int8_t take()
Returns the accumulated tick count and resets pos to 0.
Definition
encoders.cpp:47
deluge::hid::encoders::ContinuousEncoder::pos
std::atomic_int8_t pos
Written by the IRQ (applyEdges), drained by the encoder task.
Definition
encoders.h:71
deluge::hid::encoders::ContinuousEncoder::calcNextKnobSpeed
double calcNextKnobSpeed(int8_t offset)
Returns multiplier for encoder offset.
Definition
encoders.cpp:51
deluge::hid::encoders::DetentedEncoder::restore
void restore(int32_t val)
Definition
encoders.h:45
deluge::hid::encoders::DetentedEncoder::pending
bool pending() const
True if any detent steps are waiting to be consumed.
Definition
encoders.h:38
deluge::hid::encoders::DetentedEncoder::edgeAccumulator
int32_t edgeAccumulator
Accumulates A-pin edges until we have a full detent click. IRQ-only.
Definition
encoders.h:48
deluge::hid::encoders::DetentedEncoder::take
int32_t take()
Returns the accumulated signed detent count and resets pos to 0.
Definition
encoders.cpp:41
deluge::hid::encoders::DetentedEncoder::pos
std::atomic_int32_t pos
Written by the IRQ (applyEdges), drained by the encoder task.
Definition
encoders.h:49