1 /*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2020 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21 */
22
23 namespace juce
24 {
25 namespace BlocksProtocol
26 {
27
28 #ifndef DOXYGEN
29
30 // This file isn't part of the public API, it's where we encode the knowledge base
31 // of all the different types of block we know about..
32 struct BlockDataSheet
33 {
BlockDataSheetBlockDataSheet34 BlockDataSheet (const BlocksProtocol::BlockSerialNumber& serial) : serialNumber (serial)
35 {
36 if (serialNumber.isPadBlock()) initialiseForPadBlock2x2();
37 if (serialNumber.isLiveBlock()) initialiseForControlBlockLive();
38 if (serialNumber.isLoopBlock()) initialiseForControlBlockLoop();
39 if (serialNumber.isDevCtrlBlock()) initialiseForControlBlockDeveloper();
40 if (serialNumber.isTouchBlock()) initialiseForControlBlockTouch();
41 if (serialNumber.isSeaboardBlock()) initialiseForSeaboardBlock();
42 if (serialNumber.isLumiKeysBlock()) initialiseForLumiKeysBlock();
43 }
44
convertPortIndexToConnectorPortBlockDataSheet45 Block::ConnectionPort convertPortIndexToConnectorPort (BlocksProtocol::ConnectorPort port) const noexcept
46 {
47 return ports[(int) port.get()];
48 }
49
50 const BlocksProtocol::BlockSerialNumber serialNumber;
51 Block::Type apiType = Block::Type::unknown;
52
53 const char* description = nullptr;
54
55 int widthUnits = 0, heightUnits = 0;
56
57 int lightGridWidth = 0, lightGridHeight = 0, lightGridStartIndex = 0;
58
59 bool hasTouchSurface = false;
60 int numKeywaves = 0;
61
62 int numLEDRowLEDs = 0;
63
64 uint32 programAndHeapSize = 0;
65
66 struct ButtonInfo
67 {
68 ControlButton::ButtonFunction type;
69 float x, y;
70 };
71
72 struct StatusLEDInfo
73 {
74 String name;
75 float x, y;
76 };
77
78 Array<ButtonInfo> buttons;
79 Array<StatusLEDInfo> statusLEDs;
80 Array<Block::ConnectionPort> ports;
81 Array<const char*> dials;
82 Array<BlockConfigManager::ConfigDescription> defaultConfig;
83
84 private:
85 //==============================================================================
initialiseForPadBlock2x2BlockDataSheet86 void initialiseForPadBlock2x2()
87 {
88 apiType = Block::Type::lightPadBlock;
89
90 description = "Pad BLOCK (2x2)";
91
92 widthUnits = 2;
93 heightUnits = 2;
94
95 lightGridWidth = 15;
96 lightGridHeight = 15;
97
98 addPorts (2, 2, 2, 2);
99
100 hasTouchSurface = true;
101 programAndHeapSize = BlocksProtocol::padBlockProgramAndHeapSize;
102
103 addModeButton();
104 }
105
initialiseForControlBlockLoopBlockDataSheet106 void initialiseForControlBlockLoop()
107 {
108 initialiseControlBlock ("Loop BLOCK", Block::Type::loopBlock,
109 ControlButton::ButtonFunction::mode,
110 ControlButton::ButtonFunction::volume,
111 ControlButton::ButtonFunction::click,
112 ControlButton::ButtonFunction::snap,
113 ControlButton::ButtonFunction::back,
114 ControlButton::ButtonFunction::playOrPause,
115 ControlButton::ButtonFunction::record,
116 ControlButton::ButtonFunction::learn,
117 ControlButton::ButtonFunction::down,
118 ControlButton::ButtonFunction::up);
119 }
120
initialiseForControlBlockLiveBlockDataSheet121 void initialiseForControlBlockLive()
122 {
123 initialiseControlBlock ("Live BLOCK", Block::Type::liveBlock,
124 ControlButton::ButtonFunction::mode,
125 ControlButton::ButtonFunction::volume,
126 ControlButton::ButtonFunction::scale,
127 ControlButton::ButtonFunction::chord,
128 ControlButton::ButtonFunction::arp,
129 ControlButton::ButtonFunction::sustain,
130 ControlButton::ButtonFunction::octave,
131 ControlButton::ButtonFunction::love,
132 ControlButton::ButtonFunction::down,
133 ControlButton::ButtonFunction::up);
134 }
135
initialiseForControlBlockDeveloperBlockDataSheet136 void initialiseForControlBlockDeveloper()
137 {
138 initialiseControlBlock ("Dev Ctrl BLOCK", Block::Type::developerControlBlock,
139 ControlButton::ButtonFunction::button0,
140 ControlButton::ButtonFunction::button1,
141 ControlButton::ButtonFunction::button2,
142 ControlButton::ButtonFunction::button3,
143 ControlButton::ButtonFunction::button4,
144 ControlButton::ButtonFunction::button5,
145 ControlButton::ButtonFunction::button6,
146 ControlButton::ButtonFunction::button7,
147 ControlButton::ButtonFunction::down,
148 ControlButton::ButtonFunction::up);
149 }
150
initialiseForControlBlockTouchBlockDataSheet151 void initialiseForControlBlockTouch()
152 {
153 initialiseControlBlock ("Touch BLOCK", Block::Type::touchBlock,
154 ControlButton::ButtonFunction::velocitySensitivity,
155 ControlButton::ButtonFunction::glideSensitivity,
156 ControlButton::ButtonFunction::slideSensitivity,
157 ControlButton::ButtonFunction::pressSensitivity,
158 ControlButton::ButtonFunction::liftSensitivity,
159 ControlButton::ButtonFunction::fixedVelocity,
160 ControlButton::ButtonFunction::glideLock,
161 ControlButton::ButtonFunction::pianoMode,
162 ControlButton::ButtonFunction::down,
163 ControlButton::ButtonFunction::up);
164 }
165
initialiseControlBlockBlockDataSheet166 void initialiseControlBlock (const char* name, Block::Type type,
167 ControlButton::ButtonFunction b1, ControlButton::ButtonFunction b2,
168 ControlButton::ButtonFunction b3, ControlButton::ButtonFunction b4,
169 ControlButton::ButtonFunction b5, ControlButton::ButtonFunction b6,
170 ControlButton::ButtonFunction b7, ControlButton::ButtonFunction b8,
171 ControlButton::ButtonFunction b9, ControlButton::ButtonFunction b10)
172 {
173 apiType = type;
174
175 description = name;
176
177 widthUnits = 2;
178 heightUnits = 1;
179
180 programAndHeapSize = BlocksProtocol::controlBlockProgramAndHeapSize;
181
182 addPorts (2, 1, 2, 1);
183
184 float x1 = 0.2f;
185 float x2 = 0.6f;
186 float x3 = 1.0f;
187 float x4 = 1.4f;
188 float x5 = 1.8f;
189 float y1 = 0.405f;
190 float y2 = 0.798f;
191
192 addButtons (b1, x1, y1,
193 b2, x2, y1,
194 b3, x3, y1,
195 b4, x4, y1,
196 b5, x5, y1,
197 b6, x1, y2,
198 b7, x2, y2,
199 b8, x3, y2,
200 b9, x4, y2,
201 b10, x5, y2);
202
203 numLEDRowLEDs = 15;
204 }
205
initialiseForSeaboardBlockBlockDataSheet206 void initialiseForSeaboardBlock()
207 {
208 apiType = Block::Type::seaboardBlock;
209
210 description = "Seaboard BLOCK (6x3)";
211
212 widthUnits = 6;
213 heightUnits = 3;
214
215 lightGridWidth = 0;
216 lightGridHeight = 0;
217 numKeywaves = 24;
218
219 addPortsSW (Block::ConnectionPort::DeviceEdge::west, 1);
220 addPortsNE (Block::ConnectionPort::DeviceEdge::north, 2);
221 addPortsNE (Block::ConnectionPort::DeviceEdge::east, 1);
222
223 hasTouchSurface = true;
224 programAndHeapSize = BlocksProtocol::padBlockProgramAndHeapSize;
225
226 addModeButton();
227 }
228
initialiseForLumiKeysBlockBlockDataSheet229 void initialiseForLumiKeysBlock()
230 {
231 apiType = Block::Type::lumiKeysBlock;
232
233 description = "LUMI Keys BLOCK (6x3)";
234
235 widthUnits = 6;
236 heightUnits = 3;
237
238 lightGridWidth = 0;
239 lightGridHeight = 0;
240 numKeywaves = 24;
241
242 addButtons (ControlButton::ButtonFunction::mode, 0.2f, 0.2f,
243 ControlButton::ButtonFunction::down, 0.6f, 0.2f,
244 ControlButton::ButtonFunction::up, 1.0f, 0.2f);
245
246 addPortsSW (Block::ConnectionPort::DeviceEdge::west, 2);
247 addPortsNE (Block::ConnectionPort::DeviceEdge::north, 4);
248 addPortsNE (Block::ConnectionPort::DeviceEdge::east, 2);
249
250 hasTouchSurface = true;
251 programAndHeapSize = BlocksProtocol::padBlockProgramAndHeapSize;
252
253 defaultConfig.add ({ mode, 0, 0, 3, false,
254 "Color Mode", ConfigType::options,
255 { "Multi-color Mode",
256 "Single Color Mode",
257 "Piano Mode",
258 "Night Mode"
259 },
260 BlockConfigManager::playGroup });
261
262 defaultConfig.add ({ zTrackingMode, 0, 0, 1, false,
263 "Pressure Tracking Mode", ConfigType::options,
264 { "Poly Aftertouch", "Channel Pressure" },
265 BlockConfigManager::playGroup });
266 }
267
268 //==============================================================================
addStatusLEDBlockDataSheet269 void addStatusLED (const char* name, float x, float y)
270 {
271 statusLEDs.add ({ name, x, y });
272 }
273
274 template <typename... Args>
addButtonsBlockDataSheet275 void addButtons (ControlButton::ButtonFunction fn, float x, float y, Args... others)
276 {
277 addButtons (fn, x, y);
278 addButtons (others...);
279 }
280
addButtonsBlockDataSheet281 void addButtons (ControlButton::ButtonFunction fn, float x, float y)
282 {
283 buttons.add ({ fn, x, y });
284 }
285
addModeButtonBlockDataSheet286 void addModeButton()
287 {
288 addButtons (ControlButton::ButtonFunction::mode, -1.0f, -1.0f);
289 }
290
addPortsBlockDataSheet291 void addPorts (int numNorth, int numEast, int numSouth, int numWest)
292 {
293 addPortsNE (Block::ConnectionPort::DeviceEdge::north, numNorth);
294 addPortsNE (Block::ConnectionPort::DeviceEdge::east, numEast);
295 addPortsSW (Block::ConnectionPort::DeviceEdge::south, numSouth);
296 addPortsSW (Block::ConnectionPort::DeviceEdge::west, numWest);
297 }
298
addPortsNEBlockDataSheet299 void addPortsNE (Block::ConnectionPort::DeviceEdge edge, int num)
300 {
301 for (int i = 0; i < num; ++i)
302 ports.add ({ edge, i});
303 }
304
addPortsSWBlockDataSheet305 void addPortsSW (Block::ConnectionPort::DeviceEdge edge, int num)
306 {
307 for (int i = 0; i < num; ++i)
308 ports.add ({ edge, num - i - 1});
309 }
310 };
311
312 //==============================================================================
getButtonNameForFunction(ControlButton::ButtonFunction fn)313 static const char* getButtonNameForFunction (ControlButton::ButtonFunction fn) noexcept
314 {
315 using BF = ControlButton::ButtonFunction;
316
317 switch (fn)
318 {
319 case BF::mode: return "Mode";
320
321 case BF::volume: return "Volume";
322 case BF::up: return "Up";
323 case BF::down: return "Down";
324
325 case BF::scale: return "Scale";
326 case BF::chord: return "Chord";
327 case BF::arp: return "Arp";
328 case BF::sustain: return "Sustain";
329 case BF::octave: return "Octave";
330 case BF::love: return "Love";
331
332 case BF::click: return "Click";
333 case BF::snap: return "Snap";
334 case BF::back: return "Back";
335 case BF::playOrPause: return "Play/Pause";
336 case BF::record: return "Record";
337 case BF::learn: return "Learn";
338
339 case BF::button0: return "0";
340 case BF::button1: return "1";
341 case BF::button2: return "2";
342 case BF::button3: return "3";
343 case BF::button4: return "4";
344 case BF::button5: return "5";
345 case BF::button6: return "6";
346 case BF::button7: return "7";
347
348 case BF::velocitySensitivity: return "Velocity Sensitivity";
349 case BF::glideSensitivity: return "Glide Sensitivity";
350 case BF::slideSensitivity: return "Slide Sensitivity";
351 case BF::pressSensitivity: return "Press Sensitivity";
352 case BF::liftSensitivity: return "Lift Sensitivity";
353 case BF::fixedVelocity: return "Fixed Velocity";
354 case BF::glideLock: return "Glide Lock";
355 case BF::pianoMode: return "Piano Mode";
356
357 default: break;
358 }
359
360 jassertfalse;
361 return nullptr;
362 }
363
364 #endif
365
366 } // namespace BlocksProtocol
367 } // namespace juce
368