tracktion-engine 3.0-10-g034fdde4aa5
Tracktion Engine — High level data model for audio applications

« « « Anklang Documentation
Loading...
Searching...
No Matches
tracktion_MidiPatchBay.cpp
Go to the documentation of this file.
1 /*
2 ,--. ,--. ,--. ,--.
3 ,-' '-.,--.--.,--,--.,---.| |,-.,-' '-.`--' ,---. ,--,--, Copyright 2024
4 '-. .-'| .--' ,-. | .--'| /'-. .-',--.| .-. || \ Tracktion Software
5 | | | | \ '-' \ `--.| \ \ | | | |' '-' '| || | Corporation
6 `---' `--' `--`--'`---'`--'`--' `---' `--' `---' `--''--' www.tracktion.com
7
8 Tracktion Engine uses a GPL/commercial licence - see LICENCE.md for details.
9*/
10
11namespace tracktion { inline namespace engine
12{
13
14MidiPatchBayPlugin::MidiPatchBayPlugin (PluginCreationInfo info) : Plugin (info)
15{
16 if (! state.hasProperty (IDs::mappings))
17 resetMappings();
18
19 sanityCheckMappings();
20 currentMappings = getMappings();
21}
22
23MidiPatchBayPlugin::~MidiPatchBayPlugin()
24{
25 notifyListenersOfDeletion();
26}
27
28juce::ValueTree MidiPatchBayPlugin::create()
29{
30 return createValueTree (IDs::PLUGIN,
31 IDs::type, xmlTypeName);
32}
33
34const char* MidiPatchBayPlugin::xmlTypeName = "midipatchbay";
35
36void MidiPatchBayPlugin::initialise (const PluginInitialisationInfo&) {}
37void MidiPatchBayPlugin::deinitialise() {}
38
39void MidiPatchBayPlugin::applyToBuffer (const PluginRenderContext& fc)
40{
41 if (fc.bufferForMidiMessages != nullptr)
42 {
43 SCOPED_REALTIME_CHECK
44
45 if (auto* mma = fc.bufferForMidiMessages)
46 {
47 const juce::ScopedLock sl (mappingsLock);
48
49 for (int i = mma->size(); --i >= 0;)
50 {
51 auto& m = (*mma)[i];
52
53 auto newChan = juce::jlimit (0, 16, (int) currentMappings.map[m.getChannel()]);
54
55 if (newChan == blockChannel)
56 mma->remove (i);
57 else
58 m.setChannel (newChan);
59 }
60 }
61 }
62}
63
64//==============================================================================
65void MidiPatchBayPlugin::makeConnection (int srcChannel, int dstChannel)
66{
67 Mappings mappings (getMappings());
68
71
72 if (juce::isPositiveAndNotGreaterThan (srcChannel, 16)
73 && juce::isPositiveAndNotGreaterThan (dstChannel, 16))
74 mappings.map[srcChannel] = (char) dstChannel;
75
76 setMappings (mappings);
77}
78
79void MidiPatchBayPlugin::valueTreeChanged()
80{
81 Plugin::valueTreeChanged();
82
83 Mappings newMappings (getMappings());
84
85 {
86 const juce::ScopedLock sl (mappingsLock);
87 currentMappings = newMappings;
88 }
89
90 changed();
91}
92
93MidiPatchBayPlugin::Mappings MidiPatchBayPlugin::getMappings() const
94{
95 Mappings m;
96 auto saved = juce::StringArray::fromTokens (state[IDs::mappings].toString(), false);
97
98 for (int i = 0; i < saved.size(); ++i)
99 m.map[i + 1] = (char) saved[i].getIntValue();
100
101 return m;
102}
103
104void MidiPatchBayPlugin::setMappings (const Mappings& newMappings)
105{
106 juce::String m;
107 m.preallocateBytes (64);
108
109 for (int i = 1; i < juce::numElementsInArray (newMappings.map); ++i)
110 m << (int) newMappings.map[i] << ' ';
111
112 state.setProperty (IDs::mappings, m.trimEnd(), getUndoManager());
113}
114
115void MidiPatchBayPlugin::resetMappings()
116{
117 Mappings m;
118
119 for (int i = juce::numElementsInArray (m.map); --i >= 0;)
120 m.map[i] = (char) i;
121
122 setMappings (m);
123}
124
125void MidiPatchBayPlugin::blockAllMappings()
126{
127 Mappings m;
128
129 for (int i = juce::numElementsInArray (m.map); --i >= 0;)
130 m.map[i] = (char) blockChannel;
131
132 setMappings (m);
133}
134
135void MidiPatchBayPlugin::sanityCheckMappings()
136{
137 Mappings m (getMappings());
138
139 for (int i = juce::numElementsInArray (m.map); --i >= 1;)
140 {
141 int dst = m.map[i];
143
144 if (! juce::isPositiveAndNotGreaterThan (dst, 16))
145 dst = 0;
146
147 m.map[i] = (char) dst;
148 }
149
150 setMappings (m);
151}
152
153std::pair<int, int> MidiPatchBayPlugin::getFirstMapping()
154{
155 int i = 0;
156
157 for (auto m : getMappings().map)
158 {
159 if (m > 0 && m <= 16)
160 return std::pair<int, int> (i, (int) m);
161
162 ++i;
163 }
164
165 return std::pair<int, int> (-1, -1);
166}
167
168}} // namespace tracktion { inline namespace engine
static StringArray fromTokens(StringRef stringToTokenise, bool preserveQuotedStrings)
T is_pointer_v
#define jassert(expression)
typedef char
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
bool isPositiveAndNotGreaterThan(Type1 valueToTest, Type2 upperLimit) noexcept
constexpr int numElementsInArray(Type(&)[N]) noexcept
Passed into Plugins when they are being initialised, to give them useful contextual information that ...
The context passed to plugin render methods to provide it with buffers to fill.
MidiMessageArray * bufferForMidiMessages
A buffer of MIDI events to process.