Deluge Firmware 1.3.0
Build date: 2025.04.16
Loading...
Searching...
No Matches
cv_instrument.h
1/*
2 * Copyright © 2018-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/instrument/cv_instrument.h"
21#include "model/instrument/non_audio_instrument.h"
22
26enum class CVMode : uint8_t { off, pitch, mod, aftertouch, velocity };
27enum class GateMode : uint8_t { off, gate, trigger };
28enum CVInstrumentMode { one, two, both };
29constexpr int32_t kNumCVInstrumentChannels = both + 1;
30
31class CVInstrument final : public NonAudioInstrument {
32public:
33 CVInstrument();
34 void noteOnPostArp(int32_t noteCodePostArp, ArpNote* arpNote, int32_t noteIndex) override;
35 void noteOffPostArp(int32_t noteCode, int32_t oldMIDIChannel, int32_t velocity, int32_t noteIndex) override;
36 void polyphonicExpressionEventPostArpeggiator(int32_t newValue, int32_t noteCodeAfterArpeggiation,
37 int32_t expressionDmiension, ArpNote* arpNote,
38 int32_t noteIndex) override;
39 bool writeDataToFile(Serializer& writer, Clip* clipForSavingOutputOnly, Song* song) override;
40 bool readTagFromFile(Deserializer& reader, const char* tagName) override;
41 void monophonicExpressionEvent(int32_t newValue, int32_t expressionDmiension) override;
42 bool setActiveClip(ModelStackWithTimelineCounter* modelStack, PgmChangeSend maySendMIDIPGMs) override;
43 void setupWithoutActiveClip(ModelStack* modelStack) override;
44 static int32_t navigateChannels(int oldChannel, int offset) {
45 auto newChannel = (oldChannel + offset) % kNumCVInstrumentChannels;
46 if (newChannel == -1) {
47 newChannel = kNumCVInstrumentChannels - 1;
48 }
49 return newChannel;
50 }
51 bool matchesPreset(OutputType otherType, int32_t otherChannel, int32_t channelSuffix, char const* otherName,
52 char const* otherPath) override {
53 bool match{false};
54 if (type == otherType) {
55 auto ourChannel = getChannel();
56 match = ourChannel == otherChannel || ourChannel == both || otherChannel == both; // 3 means both
57 }
58 return match;
59 }
60
61 // It's much easier to store local copies of the most recent of these, so we never have to go doing complex quizzing
62 // of the arp, or MPE params, which we otherwise would have to do regularly.
63 int32_t monophonicPitchBendValue;
64 int32_t polyPitchBendValue;
65
66 char const* getXMLTag() override { return "cvChannel"; }
67 void setChannel(int channel) override {
68 if (channel <= both) {
69 NonAudioInstrument::setChannel(channel);
70 setMode(static_cast<CVInstrumentMode>(channel));
71 }
72 else {
73 NonAudioInstrument::setChannel(0);
74 setMode(static_cast<CVInstrumentMode>(0));
75 }
76 }
77 CVMode getCV2Mode() { return cvmode[1]; }
78
79 void setCV2Mode(CVMode mode);
80
81private:
82 void updatePitchBendOutput(bool outputToo = true);
83 // returns -1 if no pitch
84 int32_t getPitchChannel() {
85 auto c = getChannel();
86 if (c > 1) {
87 return 0;
88 }
89 return c;
90 }
91 void setMode(CVInstrumentMode channel) {
92 clearModes();
93 switch (channel) {
94 case CVInstrumentMode::one: {
95 gateMode[0] = GateMode::gate;
96 cvmode[0] = CVMode::pitch;
97 }
98 case CVInstrumentMode::two: {
99 gateMode[1] = GateMode::gate;
100 cvmode[1] = CVMode::pitch;
101 }
102 case CVInstrumentMode::both: {
103 gateMode[0] = GateMode::gate;
104 gateMode[1] = GateMode::trigger;
105 cvmode[0] = CVMode::pitch;
106 if (cvmode[1] == CVMode::off) {
107 cvmode[1] = CVMode::aftertouch;
108 }
109 }
110 }
111 }
112 void clearModes() {
113 gateMode[0] = GateMode::off;
114 gateMode[1] = GateMode::off;
115 cvmode[0] = CVMode::off;
116 cvmode[1] = CVMode::off;
117 }
118
119 GateMode gateMode[2]{GateMode::off, GateMode::off};
120 CVMode cvmode[2]{CVMode::off, CVMode::off};
121 void sendMonophonicExpressionEvent(int32_t dimension);
122};
Definition clip.h:46
Definition storage_manager.h:185
Definition model_stack.h:287
Definition model_stack.h:231
Definition model_stack.h:129
Definition model_stack.h:123
Definition param_manager.h:174
Definition storage_manager.h:119
Definition song.h:104
Definition arpeggiator.h:142