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.

262 lines
8.8KB

  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 either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. /** This value is incremented when the format of the API changes in a way which
  18. breaks compatibility.
  19. */
  20. static constexpr uint32 currentProtocolVersion = 1;
  21. using ProtocolVersion = IntegerWithBitSize<8>;
  22. //==============================================================================
  23. /** A timestamp for a packet, in milliseconds since device boot-up */
  24. using PacketTimestamp = IntegerWithBitSize<32>;
  25. /** This relative timestamp is for use inside a packet, and it represents a
  26. number of milliseconds that should be added to the packet's timestamp.
  27. */
  28. using PacketTimestampOffset = IntegerWithBitSize<5>;
  29. //==============================================================================
  30. /** Messages that a device may send to the host. */
  31. enum class MessageFromDevice
  32. {
  33. deviceTopology = 0x01,
  34. packetACK = 0x02,
  35. touchStart = 0x10,
  36. touchMove = 0x11,
  37. touchEnd = 0x12,
  38. touchStartWithVelocity = 0x13,
  39. touchMoveWithVelocity = 0x14,
  40. touchEndWithVelocity = 0x15,
  41. controlButtonDown = 0x20,
  42. controlButtonUp = 0x21
  43. };
  44. /** Messages that the host may send to a device. */
  45. enum class MessageFromHost
  46. {
  47. deviceCommandMessage = 0x01,
  48. sharedDataChange = 0x02,
  49. programEventMessage = 0x03
  50. };
  51. /** This is the first item in a BLOCKS message, identifying the message type. */
  52. using MessageType = IntegerWithBitSize<7>;
  53. //==============================================================================
  54. /** This is a type of index identifier used to refer to a block within a group.
  55. It refers to the index of a device in the list of devices that was most recently
  56. sent via a topology change message
  57. (It's not a global UID for a block unit).
  58. NB: to send a message to all devices, pass the getDeviceIndexForBroadcast() value.
  59. */
  60. using TopologyIndex = uint8;
  61. static constexpr int topologyIndexBits = 7;
  62. /** Use this value as the index if you want a message to be sent to all devices in
  63. the group.
  64. */
  65. static constexpr TopologyIndex topologyIndexForBroadcast = 63;
  66. using DeviceCount = IntegerWithBitSize<7>;
  67. using ConnectionCount = IntegerWithBitSize<8>;
  68. //==============================================================================
  69. /** Battery charge level. */
  70. using BatteryLevel = IntegerWithBitSize<5>;
  71. /** Battery charger connection flag. */
  72. using BatteryCharging = IntegerWithBitSize<1>;
  73. //==============================================================================
  74. /** ConnectorPort is an index, starting at 0 for the leftmost port on the
  75. top edge, and going clockwise.
  76. */
  77. using ConnectorPort = IntegerWithBitSize<5>;
  78. //==============================================================================
  79. struct BlockSerialNumber
  80. {
  81. uint8 serial[16];
  82. bool isValid() const noexcept
  83. {
  84. for (auto c : serial)
  85. if (c == 0)
  86. return false;
  87. return isAnyControlBlock() || isPadBlock();
  88. }
  89. bool isPadBlock() const noexcept { return hasPrefix ("LPB"); }
  90. bool isLiveBlock() const noexcept { return hasPrefix ("LIC"); }
  91. bool isLoopBlock() const noexcept { return hasPrefix ("LOC"); }
  92. bool isDevCtrlBlock() const noexcept { return hasPrefix ("DCB"); }
  93. bool isAnyControlBlock() const noexcept { return isLiveBlock() || isLoopBlock() || isDevCtrlBlock(); }
  94. bool hasPrefix (const char* prefix) const noexcept { return memcmp (serial, prefix, 3) == 0; }
  95. };
  96. struct DeviceStatus
  97. {
  98. BlockSerialNumber serialNumber;
  99. TopologyIndex index;
  100. BatteryLevel batteryLevel;
  101. BatteryCharging batteryCharging;
  102. };
  103. struct DeviceConnection
  104. {
  105. TopologyIndex device1, device2;
  106. ConnectorPort port1, port2;
  107. };
  108. //==============================================================================
  109. /** The coordinates of a touch. */
  110. struct TouchPosition
  111. {
  112. using Xcoord = IntegerWithBitSize<12>;
  113. using Ycoord = IntegerWithBitSize<12>;
  114. using Zcoord = IntegerWithBitSize<8>;
  115. Xcoord x;
  116. Ycoord y;
  117. Zcoord z;
  118. enum { bits = Xcoord::bits + Ycoord::bits + Zcoord::bits };
  119. };
  120. /** The velocities for each dimension of a touch. */
  121. struct TouchVelocity
  122. {
  123. using VXcoord = IntegerWithBitSize<8>;
  124. using VYcoord = IntegerWithBitSize<8>;
  125. using VZcoord = IntegerWithBitSize<8>;
  126. VXcoord vx;
  127. VYcoord vy;
  128. VZcoord vz;
  129. enum { bits = VXcoord::bits + VYcoord::bits + VZcoord::bits };
  130. };
  131. /** The index of a touch, i.e. finger number. */
  132. using TouchIndex = IntegerWithBitSize<5>;
  133. using PacketCounter = IntegerWithBitSize<10>;
  134. //==============================================================================
  135. enum DeviceCommands
  136. {
  137. beginAPIMode = 0x00,
  138. requestTopologyMessage = 0x01,
  139. endAPIMode = 0x02,
  140. ping = 0x03,
  141. debugMode = 0x04
  142. };
  143. using DeviceCommand = IntegerWithBitSize<9>;
  144. //==============================================================================
  145. /** An ID for a control-block button type */
  146. using ControlButtonID = IntegerWithBitSize<12>;
  147. //==============================================================================
  148. using RotaryDialIndex = IntegerWithBitSize<7>;
  149. using RotaryDialAngle = IntegerWithBitSize<14>;
  150. using RotaryDialDelta = IntegerWithBitSize<14>;
  151. //==============================================================================
  152. enum DataChangeCommands
  153. {
  154. endOfPacket = 0,
  155. endOfChanges = 1,
  156. skipBytesFew = 2,
  157. skipBytesMany = 3,
  158. setSequenceOfBytes = 4,
  159. setFewBytesWithValue = 5,
  160. setFewBytesWithLastValue = 6,
  161. setManyBytesWithValue = 7
  162. };
  163. using PacketIndex = IntegerWithBitSize<16>;
  164. using DataChangeCommand = IntegerWithBitSize<3>;
  165. using ByteCountFew = IntegerWithBitSize<4>;
  166. using ByteCountMany = IntegerWithBitSize<8>;
  167. using ByteValue = IntegerWithBitSize<8>;
  168. using ByteSequenceContinues = IntegerWithBitSize<1>;
  169. static constexpr uint32 numProgramMessageInts = 2;
  170. static constexpr uint32 apiModeHostPingTimeoutMs = 5000;
  171. static constexpr uint32 padBlockProgramAndHeapSize = 3200;
  172. static constexpr uint32 padBlockStackSize = 800;
  173. static constexpr uint32 controlBlockProgramAndHeapSize = 1500;
  174. static constexpr uint32 controlBlockStackSize = 500;
  175. //==============================================================================
  176. /** Contains the number of bits required to encode various items in the packets */
  177. enum BitSizes
  178. {
  179. topologyMessageHeader = MessageType::bits + ProtocolVersion::bits + DeviceCount::bits + ConnectionCount::bits,
  180. topologyDeviceInfo = sizeof (BlockSerialNumber) * 7 + BatteryLevel::bits + BatteryCharging::bits,
  181. topologyConnectionInfo = topologyIndexBits + ConnectorPort::bits + topologyIndexBits + ConnectorPort::bits,
  182. typeDeviceAndTime = MessageType::bits + PacketTimestampOffset::bits,
  183. touchMessage = typeDeviceAndTime + TouchIndex::bits + TouchPosition::bits,
  184. touchMessageWithVelocity = touchMessage + TouchVelocity::bits,
  185. programEventMessage = MessageType::bits + 32 * numProgramMessageInts,
  186. packetACK = MessageType::bits + PacketCounter::bits,
  187. controlButtonMessage = typeDeviceAndTime + ControlButtonID::bits,
  188. };
  189. //==============================================================================
  190. // These are the littlefoot functions provided for use in BLOCKS programs
  191. static constexpr const char* ledProgramLittleFootFunctions[] =
  192. {
  193. "makeARGB/iiiii",
  194. "blendARGB/iii",
  195. "setLED/viii",
  196. "blendLED/viii",
  197. "fillRect/viiiii",
  198. "enableDebug/viii",
  199. nullptr
  200. };