The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

276 lines
9.5KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2016 - ROLI Ltd.
  5. Permission is granted to use this software under the terms of the ISC license
  6. http://www.isc.org/downloads/software-support-policy/isc-license/
  7. Permission to use, copy, modify, and/or distribute this software for any
  8. purpose with or without fee is hereby granted, provided that the above
  9. copyright notice and this permission notice appear in all copies.
  10. THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
  11. TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  12. FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
  13. OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  14. USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  15. TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  16. OF THIS SOFTWARE.
  17. -----------------------------------------------------------------------------
  18. To release a closed-source product which uses other parts of JUCE not
  19. licensed under the ISC terms, commercial licenses are available: visit
  20. www.juce.com for more information.
  21. ==============================================================================
  22. */
  23. /** This value is incremented when the format of the API changes in a way which
  24. breaks compatibility.
  25. */
  26. static constexpr uint32 currentProtocolVersion = 1;
  27. using ProtocolVersion = IntegerWithBitSize<8>;
  28. //==============================================================================
  29. /** A timestamp for a packet, in milliseconds since device boot-up */
  30. using PacketTimestamp = IntegerWithBitSize<32>;
  31. /** This relative timestamp is for use inside a packet, and it represents a
  32. number of milliseconds that should be added to the packet's timestamp.
  33. */
  34. using PacketTimestampOffset = IntegerWithBitSize<5>;
  35. //==============================================================================
  36. /** Messages that a device may send to the host. */
  37. enum class MessageFromDevice
  38. {
  39. deviceTopology = 0x01,
  40. packetACK = 0x02,
  41. touchStart = 0x10,
  42. touchMove = 0x11,
  43. touchEnd = 0x12,
  44. touchStartWithVelocity = 0x13,
  45. touchMoveWithVelocity = 0x14,
  46. touchEndWithVelocity = 0x15,
  47. controlButtonDown = 0x20,
  48. controlButtonUp = 0x21
  49. };
  50. /** Messages that the host may send to a device. */
  51. enum class MessageFromHost
  52. {
  53. deviceCommandMessage = 0x01,
  54. sharedDataChange = 0x02,
  55. programEventMessage = 0x03
  56. };
  57. /** This is the first item in a BLOCKS message, identifying the message type. */
  58. using MessageType = IntegerWithBitSize<7>;
  59. //==============================================================================
  60. /** This is a type of index identifier used to refer to a block within a group.
  61. It refers to the index of a device in the list of devices that was most recently
  62. sent via a topology change message
  63. (It's not a global UID for a block unit).
  64. NB: to send a message to all devices, pass the getDeviceIndexForBroadcast() value.
  65. */
  66. using TopologyIndex = uint8;
  67. static constexpr int topologyIndexBits = 7;
  68. /** Use this value as the index if you want a message to be sent to all devices in
  69. the group.
  70. */
  71. static constexpr TopologyIndex topologyIndexForBroadcast = 63;
  72. using DeviceCount = IntegerWithBitSize<7>;
  73. using ConnectionCount = IntegerWithBitSize<8>;
  74. //==============================================================================
  75. /** Battery charge level. */
  76. using BatteryLevel = IntegerWithBitSize<5>;
  77. /** Battery charger connection flag. */
  78. using BatteryCharging = IntegerWithBitSize<1>;
  79. //==============================================================================
  80. /** ConnectorPort is an index, starting at 0 for the leftmost port on the
  81. top edge, and going clockwise.
  82. */
  83. using ConnectorPort = IntegerWithBitSize<5>;
  84. //==============================================================================
  85. struct BlockSerialNumber
  86. {
  87. uint8 serial[16];
  88. bool isValid() const noexcept
  89. {
  90. for (auto c : serial)
  91. if (c == 0)
  92. return false;
  93. return isAnyControlBlock() || isPadBlock();
  94. }
  95. bool isPadBlock() const noexcept { return hasPrefix ("LPB"); }
  96. bool isLiveBlock() const noexcept { return hasPrefix ("LIC"); }
  97. bool isLoopBlock() const noexcept { return hasPrefix ("LOC"); }
  98. bool isDevCtrlBlock() const noexcept { return hasPrefix ("DCB"); }
  99. bool isAnyControlBlock() const noexcept { return isLiveBlock() || isLoopBlock() || isDevCtrlBlock(); }
  100. bool hasPrefix (const char* prefix) const noexcept { return memcmp (serial, prefix, 3) == 0; }
  101. };
  102. struct DeviceStatus
  103. {
  104. BlockSerialNumber serialNumber;
  105. TopologyIndex index;
  106. BatteryLevel batteryLevel;
  107. BatteryCharging batteryCharging;
  108. };
  109. struct DeviceConnection
  110. {
  111. TopologyIndex device1, device2;
  112. ConnectorPort port1, port2;
  113. };
  114. //==============================================================================
  115. /** The coordinates of a touch. */
  116. struct TouchPosition
  117. {
  118. using Xcoord = IntegerWithBitSize<12>;
  119. using Ycoord = IntegerWithBitSize<12>;
  120. using Zcoord = IntegerWithBitSize<8>;
  121. Xcoord x;
  122. Ycoord y;
  123. Zcoord z;
  124. enum { bits = Xcoord::bits + Ycoord::bits + Zcoord::bits };
  125. };
  126. /** The velocities for each dimension of a touch. */
  127. struct TouchVelocity
  128. {
  129. using VXcoord = IntegerWithBitSize<8>;
  130. using VYcoord = IntegerWithBitSize<8>;
  131. using VZcoord = IntegerWithBitSize<8>;
  132. VXcoord vx;
  133. VYcoord vy;
  134. VZcoord vz;
  135. enum { bits = VXcoord::bits + VYcoord::bits + VZcoord::bits };
  136. };
  137. /** The index of a touch, i.e. finger number. */
  138. using TouchIndex = IntegerWithBitSize<5>;
  139. using PacketCounter = IntegerWithBitSize<10>;
  140. //==============================================================================
  141. enum DeviceCommands
  142. {
  143. beginAPIMode = 0x00,
  144. requestTopologyMessage = 0x01,
  145. endAPIMode = 0x02,
  146. ping = 0x03,
  147. debugMode = 0x04,
  148. saveProgramAsDefault = 0x05
  149. };
  150. using DeviceCommand = IntegerWithBitSize<9>;
  151. //==============================================================================
  152. /** An ID for a control-block button type */
  153. using ControlButtonID = IntegerWithBitSize<12>;
  154. //==============================================================================
  155. using RotaryDialIndex = IntegerWithBitSize<7>;
  156. using RotaryDialAngle = IntegerWithBitSize<14>;
  157. using RotaryDialDelta = IntegerWithBitSize<14>;
  158. //==============================================================================
  159. enum DataChangeCommands
  160. {
  161. endOfPacket = 0,
  162. endOfChanges = 1,
  163. skipBytesFew = 2,
  164. skipBytesMany = 3,
  165. setSequenceOfBytes = 4,
  166. setFewBytesWithValue = 5,
  167. setFewBytesWithLastValue = 6,
  168. setManyBytesWithValue = 7
  169. };
  170. using PacketIndex = IntegerWithBitSize<16>;
  171. using DataChangeCommand = IntegerWithBitSize<3>;
  172. using ByteCountFew = IntegerWithBitSize<4>;
  173. using ByteCountMany = IntegerWithBitSize<8>;
  174. using ByteValue = IntegerWithBitSize<8>;
  175. using ByteSequenceContinues = IntegerWithBitSize<1>;
  176. static constexpr uint32 numProgramMessageInts = 2;
  177. static constexpr uint32 apiModeHostPingTimeoutMs = 5000;
  178. static constexpr uint32 padBlockProgramAndHeapSize = 3200;
  179. static constexpr uint32 padBlockStackSize = 800;
  180. static constexpr uint32 controlBlockProgramAndHeapSize = 1500;
  181. static constexpr uint32 controlBlockStackSize = 500;
  182. //==============================================================================
  183. /** Contains the number of bits required to encode various items in the packets */
  184. enum BitSizes
  185. {
  186. topologyMessageHeader = MessageType::bits + ProtocolVersion::bits + DeviceCount::bits + ConnectionCount::bits,
  187. topologyDeviceInfo = sizeof (BlockSerialNumber) * 7 + BatteryLevel::bits + BatteryCharging::bits,
  188. topologyConnectionInfo = topologyIndexBits + ConnectorPort::bits + topologyIndexBits + ConnectorPort::bits,
  189. typeDeviceAndTime = MessageType::bits + PacketTimestampOffset::bits,
  190. touchMessage = typeDeviceAndTime + TouchIndex::bits + TouchPosition::bits,
  191. touchMessageWithVelocity = touchMessage + TouchVelocity::bits,
  192. programEventMessage = MessageType::bits + 32 * numProgramMessageInts,
  193. packetACK = MessageType::bits + PacketCounter::bits,
  194. controlButtonMessage = typeDeviceAndTime + ControlButtonID::bits,
  195. };
  196. //==============================================================================
  197. // These are the littlefoot functions provided for use in BLOCKS programs
  198. static constexpr const char* ledProgramLittleFootFunctions[] =
  199. {
  200. "makeARGB/iiiii",
  201. "blendARGB/iii",
  202. "setLED/viii",
  203. "blendLED/viii",
  204. "fillRect/viiiii",
  205. "blendRect/viiiii",
  206. "sendMIDI/vi",
  207. "sendMIDI/vii",
  208. "sendMIDI/viii",
  209. "addPressurePoint/vifff",
  210. "drawPressureMap/v",
  211. "fadePressureMap/v",
  212. "enableDebug/viii",
  213. nullptr
  214. };