ableton-js 3.2.9 → 3.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,8 +4,22 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
+ #### [v3.2.11](https://github.com/leolabs/ableton.js/compare/v3.2.10...v3.2.11)
8
+
9
+ - :loud_sound: Warn when the UDP tick is lagging or when processing UDP takes too long to finish [`c419afc`](https://github.com/leolabs/ableton.js/commit/c419afc96de5b5834ae2807baf8fc4b3fb9c21ba)
10
+ - :sparkles: Use larger buffer sizes if possible for sending responses from Live [`ae480cb`](https://github.com/leolabs/ableton.js/commit/ae480cb6e86fcbbb4e0417b0869a5a78d43511c6)
11
+ - :memo: Update docs to reflect that chunks now have a dynamic size [`83afbb6`](https://github.com/leolabs/ableton.js/commit/83afbb6431a28883fdc459e31081b94bd9c6b54a)
12
+
13
+ #### [v3.2.10](https://github.com/leolabs/ableton.js/compare/v3.2.9...v3.2.10)
14
+
15
+ > 15 July 2023
16
+
17
+ - :sparkles: Remove the socket after closing it to avoid dangling event listeners trying to send messages after the plugin has been shut down [`54278f2`](https://github.com/leolabs/ableton.js/commit/54278f2b4ccb6efe34592fc108cd10c35e404e58)
18
+
7
19
  #### [v3.2.9](https://github.com/leolabs/ableton.js/compare/v3.2.8...v3.2.9)
8
20
 
21
+ > 14 July 2023
22
+
9
23
  - :sparkles: Only send the client port to Live once [`29e9443`](https://github.com/leolabs/ableton.js/commit/29e9443194294f5b55805df909d234b67e52eca2)
10
24
  - :sparkles: Send the current client port to Live every time the server port changes [`eb42ce3`](https://github.com/leolabs/ableton.js/commit/eb42ce32f4fa91bd57e4c026a7d29d961afa0a04)
11
25
 
package/README.md CHANGED
@@ -103,11 +103,11 @@ port in a local file so the other side knows which port to send messages to.
103
103
  ### Compression and Chunking
104
104
 
105
105
  To allow sending large JSON payloads, requests to and responses from the MIDI
106
- Script are compressed using gzip and chunked every 7500 bytes. The first byte of
107
- every message contains the chunk index (0x00-0xFF) followed by the gzipped
108
- chunk. The last chunk always has the index 0xFF. This indicates to the JS
109
- library that the previous received messages should be stiched together,
110
- unzipped, and processed.
106
+ Script are compressed using gzip and chunked to fit into the maximum allowed
107
+ package size. The first byte of every message chunk contains the chunk index
108
+ (0x00-0xFF) followed by the gzipped chunk. The last chunk always has the index
109
+ 0xFF. This indicates to the JS library that the previous received messages
110
+ should be stiched together, unzipped, and processed.
111
111
 
112
112
  ### Caching
113
113
 
package/index.js CHANGED
@@ -434,9 +434,7 @@ class Ableton extends events_1.EventEmitter {
434
434
  throw new Error("The client hasn't been started yet. Please call start() first.");
435
435
  }
436
436
  const buffer = (0, zlib_1.deflateSync)(Buffer.from(msg));
437
- // Based on this thread, 7500 bytes seems like a safe value
438
- // https://stackoverflow.com/questions/22819214/udp-message-too-long
439
- const byteLimit = 7500;
437
+ const byteLimit = this.client.getSendBufferSize() - 1;
440
438
  const chunks = Math.ceil(buffer.byteLength / byteLimit);
441
439
  // Split the message into chunks if it becomes too large
442
440
  for (let i = 0; i < chunks; i++) {
@@ -1,4 +1,5 @@
1
1
  from __future__ import absolute_import
2
+ import time
2
3
 
3
4
  from .version import version
4
5
  from .Config import DEBUG, FAST_POLLING
@@ -51,6 +52,7 @@ class AbletonJS(ControlSurface):
51
52
  "clip": Clip(c_instance, self.socket),
52
53
  }
53
54
 
55
+ self._last_tick = time.time() * 1000
54
56
  self.tick()
55
57
 
56
58
  if FAST_POLLING:
@@ -60,7 +62,21 @@ class AbletonJS(ControlSurface):
60
62
  self.recv_loop.start()
61
63
 
62
64
  def tick(self):
65
+ tick_time = time.time() * 1000
66
+
67
+ if tick_time - self._last_tick > 200:
68
+ self.log_message("UDP tick is lagging, delta: " +
69
+ str(round(tick_time - self._last_tick)) + "ms")
70
+
71
+ self._last_tick = tick_time
63
72
  self.socket.process()
73
+
74
+ process_time = time.time() * 1000
75
+
76
+ if process_time - tick_time > 100:
77
+ self.log_message("UDP processing is taking long, delta: " +
78
+ str(round(tick_time - process_time)) + "ms")
79
+
64
80
  self.schedule_message(1, self.tick)
65
81
 
66
82
  def build_midi_map(self, midi_map_handle):
@@ -93,6 +93,7 @@ class Socket(object):
93
93
  def shutdown(self):
94
94
  self.log_message("Shutting down...")
95
95
  self._socket.close()
96
+ self._socket = None
96
97
 
97
98
  def init_socket(self, try_stored=False):
98
99
  self.log_message(
@@ -113,6 +114,12 @@ class Socket(object):
113
114
  self._socket.bind(self._server_addr)
114
115
  port = self._socket.getsockname()[1]
115
116
 
117
+ # Get the chunk limit of the socket, minus 1 for the ordering byte
118
+ self._chunk_limit = self._socket.getsockopt(
119
+ socket.SOL_SOCKET, socket.SO_SNDBUF) - 1
120
+
121
+ self.log_message("Chunk limit: " + str(self._chunk_limit))
122
+
116
123
  # Write the chosen port to a file
117
124
  try:
118
125
  if stored_port != port:
@@ -146,14 +153,14 @@ class Socket(object):
146
153
  def _sendto(self, msg):
147
154
  '''Send a raw message to the client, compressed and chunked, if necessary'''
148
155
  compressed = zlib.compress(msg.encode("utf8")) + b'\n'
149
- # Based on this thread, 7500 bytes seems like a safe value
150
- # https://stackoverflow.com/questions/22819214/udp-message-too-long
151
- limit = 7500
152
156
 
153
- if len(compressed) < limit:
157
+ if self._socket == None:
158
+ return
159
+
160
+ if len(compressed) < self._chunk_limit:
154
161
  self._socket.sendto(b'\xFF' + compressed, self._client_addr)
155
162
  else:
156
- chunks = list(split_by_n(compressed, limit))
163
+ chunks = list(split_by_n(compressed, self._chunk_limit))
157
164
  count = len(chunks)
158
165
  for i, chunk in enumerate(chunks):
159
166
  count_byte = struct.pack("B", i if i + 1 < count else 255)
@@ -184,7 +191,7 @@ class Socket(object):
184
191
  buffer = bytes()
185
192
  num_messages = 0
186
193
  while 1:
187
- data = self._socket.recv(8192)
194
+ data = self._socket.recv(65536)
188
195
  if len(data) and self.input_handler:
189
196
  buffer += data[1:]
190
197
  num_messages += 1
@@ -1 +1 @@
1
- version = "3.2.9"
1
+ version = "3.2.11"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ableton-js",
3
- "version": "3.2.9",
3
+ "version": "3.2.11",
4
4
  "description": "Control Ableton Live from Node",
5
5
  "main": "index.js",
6
6
  "author": "Leo Bernard <admin@leolabs.org>",
@@ -19,7 +19,7 @@
19
19
  "ableton:copy-script": "set -- ~/Music/Ableton/User\\ Library/Remote\\ Scripts && mkdir -p \"$1\" && rm -rf \"$1/AbletonJS\" && cp -r \"$(pwd)/midi-script\" \"$1/AbletonJS\" && rm -rf \"$1/AbletonJS/_Framework\"",
20
20
  "ableton10:launch": "set -- /Applications/Ableton*10* && open \"$1\"",
21
21
  "ableton11:launch": "set -- /Applications/Ableton*11* && open \"$1\"",
22
- "ableton:logs": "tail -n 50 -f ~/Library/Preferences/Ableton/*/Log.txt | grep -i -e RemoteScriptError -e RemoteScriptMessage",
22
+ "ableton:logs": "tail -n 50 -f ~/Library/Preferences/Ableton/*/Log.txt | grep --line-buffered -i -e RemoteScriptError -e RemoteScriptMessage | sed 's/info: RemoteScriptMessage: (AbletonJS) //'",
23
23
  "ableton:kill": "pkill -KILL -f \"Ableton Live\"",
24
24
  "ableton10:start": "yarn ableton:kill; yarn ableton:clean && yarn ableton:copy-script && yarn ableton10:launch && yarn ableton:logs",
25
25
  "ableton11:start": "yarn ableton:kill; yarn ableton:clean && yarn ableton:copy-script && yarn ableton11:launch && yarn ableton:logs",