Deluge Firmware
1.3.0
Build date: 2026.08.29
Toggle main menu visibility
Loading...
Searching...
No Matches
cv_engine.h
1
/*
2
* Copyright © 2015-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 "model/drum/gate_drum.h"
21
#include <cstdint>
22
23
#define WHICH_GATE_OUTPUT_IS_RUN 2
24
#define WHICH_GATE_OUTPUT_IS_CLOCK 3
25
26
const
uint8_t gatePort[] = {2, 2, 2, 4};
27
const
uint8_t gatePin[] = {7, 8, 9, 0};
28
29
class
CVChannel {
30
public
:
31
CVChannel() {
32
noteCurrentlyPlaying = -32768;
33
voltsPerOctave = 100;
34
transpose = 0;
35
cents = 0;
36
pitchBend = 0;
37
}
38
int16_t noteCurrentlyPlaying;
39
uint8_t voltsPerOctave;
40
int8_t transpose;
41
int8_t cents;
42
int32_t
43
pitchBend;
// (1 << 23) represents one semitone. So full 32-bit range can be +-256 semitones. This is different
44
// to the equivalent calculation in Voice, which needs to get things into a number of octaves.
45
};
46
47
class
GateChannel {
48
public
:
49
GateChannel() { on =
false
; }
50
bool
on;
// Means either on now, or "awaiting" switch-on
51
GateType mode;
52
uint32_t timeLastSwitchedOff;
53
};
54
55
class
CVEngine {
56
public
:
57
CVEngine();
58
void
init();
59
void
sendNote(
bool
on, uint8_t channel, int16_t note = -32768);
60
void
setGateType(uint8_t whichGate, GateType value);
61
void
setCVVoltsPerOctave(uint8_t channel, uint8_t value);
62
void
setCVTranspose(uint8_t channel, int32_t semitones, int32_t cents);
63
void
setCVPitchBend(uint8_t channel, int32_t value,
bool
outputToo =
true
);
64
int32_t calculateVoltage(int32_t note, uint8_t channel);
65
void
physicallySwitchGate(int32_t channel);
66
// defer updating the gate while CV is pending and do it when it's done
67
void
cvOutUpdated();
68
69
void
analogOutTick();
70
void
playbackBegun();
71
void
playbackEnded();
73
void
updateClockOutput
();
74
void
updateRunOutput();
75
bool
isTriggerClockOutputEnabled();
77
void
updateGateOutputs
();
78
79
bool
isGatePending()
const
{
return
gateOutputPending
; }
80
bool
isRunPending()
const
{
return
asapGateOutputPending
; }
81
bool
isClockPending()
const
{
return
clockOutputPending
; }
82
bool
isAnythingButRunPending()
const
{
return
isGatePending() || isClockPending(); }
83
bool
isAnythingPending()
const
{
return
isGatePending() || isClockPending() || isRunPending(); }
84
GateChannel
gateChannels[NUM_GATE_CHANNELS];
85
86
CVChannel
cvChannels[NUM_PHYSICAL_CV_CHANNELS];
87
88
uint8_t minGateOffTime;
// in 100uS's
89
90
bool
clockState;
91
92
// When one or more note-on is pending, this is the latest time that one of them last switched off.
93
// But it seems I only use this very coarsely - more to see if we're still in the same audio frame than to measure
94
// time exactly. This could be improved.
95
uint32_t mostRecentSwitchOffTimeOfPendingNoteOn;
96
97
void
sendVoltageOut(uint8_t channel, uint16_t voltage);
98
99
inline
bool
isNoteOn(int32_t channel, int32_t note) {
100
return
(gateChannels[channel].on && cvChannels[channel].noteCurrentlyPlaying == note);
101
}
102
103
private
:
104
void
recalculateCVChannelVoltage(uint8_t channel);
105
void
switchGateOff(int32_t channel);
106
void
switchGateOn(int32_t channel, int32_t doInstantlyIfPossible =
false
);
108
bool
cvOutPending
{
false
};
110
bool
gateOutputPending
{
false
};
112
bool
asapGateOutputPending
;
114
bool
clockOutputPending
;
115
};
116
117
extern
CVEngine
cvEngine;
CVChannel
Definition
cv_engine.h:29
CVEngine
Definition
cv_engine.h:55
CVEngine::updateGateOutputs
void updateGateOutputs()
physically send all gate outs if any output pending
Definition
cv_engine.cpp:94
CVEngine::cvOutPending
bool cvOutPending
signifies there's a gate that can't go until the cv is output
Definition
cv_engine.h:108
CVEngine::clockOutputPending
bool clockOutputPending
gate 4 as a clock signal
Definition
cv_engine.h:114
CVEngine::gateOutputPending
bool gateOutputPending
gate 1-4 as synths or drums
Definition
cv_engine.h:110
CVEngine::updateClockOutput
void updateClockOutput()
toggles clock, does not physically update until updateGateOutputs called
Definition
cv_engine.cpp:321
CVEngine::asapGateOutputPending
bool asapGateOutputPending
gate 3 as a run signal
Definition
cv_engine.h:112
GateChannel
Definition
cv_engine.h:47