ableton-js 2.1.8 → 2.3.0
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 +23 -0
- package/README.md +3 -4
- package/index.d.ts +2 -0
- package/index.js +10 -3
- package/midi-script/AbletonJS.py +8 -5
- package/midi-script/Application.py +26 -0
- package/midi-script/Clip.py +1 -0
- package/midi-script/Internal.py +1 -1
- package/midi-script/Socket.py +6 -2
- package/midi-script/Track.py +4 -0
- package/ns/application.d.ts +22 -0
- package/ns/application.js +70 -0
- package/ns/application.spec.d.ts +1 -0
- package/ns/application.spec.js +70 -0
- package/ns/clip.d.ts +2 -0
- package/ns/song.spec.js +1 -1
- package/ns/track.d.ts +4 -0
- package/ns/track.js +6 -2
- package/package.json +6 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,8 +4,31 @@ 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
|
+
#### [v2.3.0](https://github.com/leolabs/ableton.js/compare/v2.2.1-0...v2.3.0)
|
|
8
|
+
|
|
9
|
+
- :sparkles: Add the clip's name as an observable property [`78c9969`](https://github.com/leolabs/ableton.js/commit/78c99694e8e230ad4ecb022316ebed731994fc6f)
|
|
10
|
+
|
|
11
|
+
#### [v2.2.1-0](https://github.com/leolabs/ableton.js/compare/v2.2.0...v2.2.1-0)
|
|
12
|
+
|
|
13
|
+
> 26 March 2022
|
|
14
|
+
|
|
15
|
+
- :sparkles: Implement basic Application interface to fetch live version and dialog information [`5aba86f`](https://github.com/leolabs/ableton.js/commit/5aba86f811ff36d43a99a657a2789e3d9ac59cce)
|
|
16
|
+
- :white_check_mark: Add tests for the application namespace [`9954cdf`](https://github.com/leolabs/ableton.js/commit/9954cdf724a41d8705a62fa50ac5cb06b162e1f1)
|
|
17
|
+
- :sparkles: Add support for listing clips in arrangement view [`e7df690`](https://github.com/leolabs/ableton.js/commit/e7df69060ccc7e098b1b4f5d418a79a60d57c4ce)
|
|
18
|
+
|
|
19
|
+
#### [v2.2.0](https://github.com/leolabs/ableton.js/compare/v2.1.8...v2.2.0)
|
|
20
|
+
|
|
21
|
+
> 18 March 2022
|
|
22
|
+
|
|
23
|
+
- :memo: Fix details in readme [`#36`](https://github.com/leolabs/ableton.js/pull/36)
|
|
24
|
+
- :bug: Fix errors on quick disconnect/connect [`#42`](https://github.com/leolabs/ableton.js/pull/42)
|
|
25
|
+
- :bug: Fix connected status on load of Ableton class [`#40`](https://github.com/leolabs/ableton.js/pull/40)
|
|
26
|
+
- :wrench: Add GitHub repo to NPM page [`#39`](https://github.com/leolabs/ableton.js/pull/39)
|
|
27
|
+
|
|
7
28
|
#### [v2.1.8](https://github.com/leolabs/ableton.js/compare/v2.1.7...v2.1.8)
|
|
8
29
|
|
|
30
|
+
> 18 February 2022
|
|
31
|
+
|
|
9
32
|
- :sparkles: Add observable props for quantization [`ffd192d`](https://github.com/leolabs/ableton.js/commit/ffd192d1590f33cdd18c2e01dbf66a0bc67878e4)
|
|
10
33
|
|
|
11
34
|
#### [v2.1.7](https://github.com/leolabs/ableton.js/compare/v2.1.6...v2.1.7)
|
package/README.md
CHANGED
|
@@ -22,8 +22,7 @@ get an overview of the current of your set.
|
|
|
22
22
|
|
|
23
23
|
To use this library, you'll need to install and activate the MIDI Remote Script
|
|
24
24
|
in Ableton.js. To do that, copy the `midi-script` folder of this repo to
|
|
25
|
-
Ableton's Remote Scripts folder
|
|
26
|
-
like `AbletonJS` for better identification. The MIDI Remote Scripts folder is
|
|
25
|
+
Ableton's Remote Scripts folder and rename it to `AbletonJS`. The MIDI Remote Scripts folder is
|
|
27
26
|
usually located at:
|
|
28
27
|
|
|
29
28
|
- **Windows:** {path to Ableton}\Resources\MIDI\Remote Scripts
|
|
@@ -55,8 +54,8 @@ const test = async () => {
|
|
|
55
54
|
ableton.song.addListener("is_playing", (p) => console.log("Playing:", p));
|
|
56
55
|
ableton.song.addListener("tempo", (t) => console.log("Tempo:", t));
|
|
57
56
|
|
|
58
|
-
const
|
|
59
|
-
console.log(
|
|
57
|
+
const tempo = await ableton.song.get("tempo");
|
|
58
|
+
console.log(tempo);
|
|
60
59
|
};
|
|
61
60
|
|
|
62
61
|
test();
|
package/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { EventEmitter } from "events";
|
|
3
3
|
import { Song } from "./ns/song";
|
|
4
4
|
import { Internal } from "./ns/internal";
|
|
5
|
+
import { Application } from "./ns/application";
|
|
5
6
|
interface Command {
|
|
6
7
|
uuid: string;
|
|
7
8
|
ns: string;
|
|
@@ -42,6 +43,7 @@ export declare class Ableton extends EventEmitter implements ConnectionEventEmit
|
|
|
42
43
|
private buffer;
|
|
43
44
|
private latency;
|
|
44
45
|
song: Song;
|
|
46
|
+
application: Application;
|
|
45
47
|
internal: Internal;
|
|
46
48
|
constructor(host?: string, sendPort?: number, listenPort?: number, heartbeatInterval?: number);
|
|
47
49
|
close(): void;
|
package/index.js
CHANGED
|
@@ -67,6 +67,7 @@ var semver_1 = __importDefault(require("semver"));
|
|
|
67
67
|
var zlib_1 = require("zlib");
|
|
68
68
|
var song_1 = require("./ns/song");
|
|
69
69
|
var internal_1 = require("./ns/internal");
|
|
70
|
+
var application_1 = require("./ns/application");
|
|
70
71
|
var package_version_1 = require("./util/package-version");
|
|
71
72
|
var TimeoutError = /** @class */ (function (_super) {
|
|
72
73
|
__extends(TimeoutError, _super);
|
|
@@ -92,11 +93,12 @@ var Ableton = /** @class */ (function (_super) {
|
|
|
92
93
|
_this.listenPort = listenPort;
|
|
93
94
|
_this.msgMap = new Map();
|
|
94
95
|
_this.eventListeners = new Map();
|
|
95
|
-
_this._isConnected =
|
|
96
|
+
_this._isConnected = false;
|
|
96
97
|
_this.cancelConnectionEvent = false;
|
|
97
98
|
_this.buffer = [];
|
|
98
99
|
_this.latency = 0;
|
|
99
100
|
_this.song = new song_1.Song(_this);
|
|
101
|
+
_this.application = new application_1.Application(_this);
|
|
100
102
|
_this.internal = new internal_1.Internal(_this);
|
|
101
103
|
_this.client = dgram_1.default.createSocket({ type: "udp4", reuseAddr: true });
|
|
102
104
|
_this.client.bind(_this.listenPort, host);
|
|
@@ -123,6 +125,7 @@ var Ableton = /** @class */ (function (_super) {
|
|
|
123
125
|
if (this._isConnected && !this.cancelConnectionEvent) {
|
|
124
126
|
this._isConnected = false;
|
|
125
127
|
this.eventListeners.clear();
|
|
128
|
+
this.msgMap.forEach(function (msg) { return msg.clearTimeout(); });
|
|
126
129
|
this.msgMap.clear();
|
|
127
130
|
this.emit("disconnect", "heartbeat");
|
|
128
131
|
}
|
|
@@ -188,8 +191,9 @@ var Ableton = /** @class */ (function (_super) {
|
|
|
188
191
|
return functionCallback.rej(new Error(data.data));
|
|
189
192
|
}
|
|
190
193
|
if (data.event === "disconnect") {
|
|
191
|
-
this.msgMap.clear();
|
|
192
194
|
this.eventListeners.clear();
|
|
195
|
+
this.msgMap.forEach(function (msg) { return msg.clearTimeout(); });
|
|
196
|
+
this.msgMap.clear();
|
|
193
197
|
if (this._isConnected === true) {
|
|
194
198
|
this._isConnected = false;
|
|
195
199
|
this.cancelConnectionEvent = true;
|
|
@@ -236,7 +240,7 @@ var Ableton = /** @class */ (function (_super) {
|
|
|
236
240
|
rej(new TimeoutError([
|
|
237
241
|
"The command " + cls + "." + name + "(" + arg + ") timed out after " + timeout + " ms.",
|
|
238
242
|
"Please make sure that Ableton is running and that you have the latest",
|
|
239
|
-
"version of AbletonJS' midi script installed, listening on port",
|
|
243
|
+
"version of AbletonJS' midi script installed and renamed to \"AbletonJS\", listening on port",
|
|
240
244
|
_this.sendPort + " and sending on port " + _this.listenPort + ".",
|
|
241
245
|
].join(" "), payload));
|
|
242
246
|
}, timeout);
|
|
@@ -248,6 +252,9 @@ var Ableton = /** @class */ (function (_super) {
|
|
|
248
252
|
res(data);
|
|
249
253
|
},
|
|
250
254
|
rej: rej,
|
|
255
|
+
clearTimeout: function () {
|
|
256
|
+
clearTimeout(timeoutId);
|
|
257
|
+
},
|
|
251
258
|
});
|
|
252
259
|
_this.sendRaw(msg);
|
|
253
260
|
})];
|
package/midi-script/AbletonJS.py
CHANGED
|
@@ -3,6 +3,7 @@ import sys
|
|
|
3
3
|
|
|
4
4
|
from .Socket import Socket
|
|
5
5
|
from .Interface import Interface
|
|
6
|
+
from .Application import Application
|
|
6
7
|
from .CuePoint import CuePoint
|
|
7
8
|
from .Device import Device
|
|
8
9
|
from .DeviceParameter import DeviceParameter
|
|
@@ -14,6 +15,7 @@ from .Internal import Internal
|
|
|
14
15
|
from .ClipSlot import ClipSlot
|
|
15
16
|
from .Clip import Clip
|
|
16
17
|
from _Framework.ControlSurface import ControlSurface
|
|
18
|
+
from Live.Base import Timer
|
|
17
19
|
|
|
18
20
|
|
|
19
21
|
class AbletonJS(ControlSurface):
|
|
@@ -25,6 +27,7 @@ class AbletonJS(ControlSurface):
|
|
|
25
27
|
self.socket = Socket(self.command_handler)
|
|
26
28
|
|
|
27
29
|
self.handlers = {
|
|
30
|
+
"application": Application(c_instance, self.socket, self.application()),
|
|
28
31
|
"internal": Internal(c_instance, self.socket),
|
|
29
32
|
"cue-point": CuePoint(c_instance, self.socket),
|
|
30
33
|
"device": Device(c_instance, self.socket),
|
|
@@ -37,21 +40,21 @@ class AbletonJS(ControlSurface):
|
|
|
37
40
|
"clip": Clip(c_instance, self.socket)
|
|
38
41
|
}
|
|
39
42
|
|
|
40
|
-
self.
|
|
43
|
+
self.recv_loop = Timer(
|
|
44
|
+
callback=self.socket.process, interval=10, repeat=True)
|
|
45
|
+
|
|
46
|
+
self.recv_loop.start()
|
|
41
47
|
|
|
42
48
|
self.socket.send("connect")
|
|
43
49
|
|
|
44
50
|
def disconnect(self):
|
|
45
51
|
self.log_message("Disconnecting")
|
|
52
|
+
self.recv_loop.stop()
|
|
46
53
|
self.socket.send("disconnect")
|
|
47
54
|
self.socket.shutdown()
|
|
48
55
|
Interface.listeners.clear()
|
|
49
56
|
super(AbletonJS, self).disconnect()
|
|
50
57
|
|
|
51
|
-
def parse(self):
|
|
52
|
-
self.socket.process()
|
|
53
|
-
self.schedule_message(1, self.parse)
|
|
54
|
-
|
|
55
58
|
def command_handler(self, payload):
|
|
56
59
|
self.log_message("Received command: " + str(payload))
|
|
57
60
|
namespace = payload["ns"]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from __future__ import absolute_import
|
|
2
|
+
from .Interface import Interface
|
|
3
|
+
|
|
4
|
+
import Live
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Application(Interface):
|
|
8
|
+
def __init__(self, c_instance, socket, application):
|
|
9
|
+
super(Application, self).__init__(c_instance, socket)
|
|
10
|
+
self.application = application
|
|
11
|
+
self.log_message("Version: " + self.get_version(self.get_ns()))
|
|
12
|
+
|
|
13
|
+
def get_ns(self, nsid=None):
|
|
14
|
+
return self.application
|
|
15
|
+
|
|
16
|
+
def get_major_version(self, ns):
|
|
17
|
+
return ns.get_major_version()
|
|
18
|
+
|
|
19
|
+
def get_minor_version(self, ns):
|
|
20
|
+
return ns.get_minor_version()
|
|
21
|
+
|
|
22
|
+
def get_bugfix_version(self, ns):
|
|
23
|
+
return ns.get_bugfix_version()
|
|
24
|
+
|
|
25
|
+
def get_version(self, ns):
|
|
26
|
+
return str(ns.get_major_version()) + "." + str(ns.get_minor_version()) + "." + str(ns.get_bugfix_version())
|
package/midi-script/Clip.py
CHANGED
package/midi-script/Internal.py
CHANGED
package/midi-script/Socket.py
CHANGED
|
@@ -82,19 +82,23 @@ class Socket(object):
|
|
|
82
82
|
def process(self):
|
|
83
83
|
try:
|
|
84
84
|
buffer = bytes()
|
|
85
|
+
num_messages = 0
|
|
85
86
|
while 1:
|
|
86
|
-
data = self._socket.recv(
|
|
87
|
+
data = self._socket.recv(8192)
|
|
87
88
|
if len(data) and self.input_handler:
|
|
88
89
|
buffer += data[1:]
|
|
90
|
+
num_messages += 1
|
|
89
91
|
|
|
90
92
|
# \xFF for Live 10 (Python2) and 255 for Live 11 (Python3)
|
|
91
93
|
if(data[0] == b'\xFF' or data[0] == 255):
|
|
92
94
|
unzipped = zlib.decompress(buffer)
|
|
93
95
|
payload = json.loads(unzipped)
|
|
94
96
|
|
|
95
|
-
self.log_message(
|
|
97
|
+
self.log_message(
|
|
98
|
+
"Receiving from " + str(num_messages) + " messages, " + str(len(buffer)) + " bytes: " + str(payload))
|
|
96
99
|
self.input_handler(payload)
|
|
97
100
|
buffer = bytes()
|
|
101
|
+
num_messages = 0
|
|
98
102
|
except socket.error as e:
|
|
99
103
|
return
|
|
100
104
|
except Exception as e:
|
package/midi-script/Track.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import absolute_import
|
|
2
2
|
from .Interface import Interface
|
|
3
3
|
from .Device import Device
|
|
4
|
+
from .Clip import Clip
|
|
4
5
|
from .ClipSlot import ClipSlot
|
|
5
6
|
|
|
6
7
|
|
|
@@ -16,6 +17,9 @@ class Track(Interface):
|
|
|
16
17
|
def __init__(self, c_instance, socket):
|
|
17
18
|
super(Track, self).__init__(c_instance, socket)
|
|
18
19
|
|
|
20
|
+
def get_arrangement_clips(self, ns):
|
|
21
|
+
return list(map(Clip.serialize_clip, ns.arrangement_clips))
|
|
22
|
+
|
|
19
23
|
def get_devices(self, ns):
|
|
20
24
|
return list(map(Device.serialize_device, ns.devices))
|
|
21
25
|
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Ableton } from "..";
|
|
2
|
+
import { Namespace } from ".";
|
|
3
|
+
export interface GettableProperties {
|
|
4
|
+
bugfix_version: number;
|
|
5
|
+
major_version: number;
|
|
6
|
+
minor_version: number;
|
|
7
|
+
version: string;
|
|
8
|
+
current_dialog_button_count: number;
|
|
9
|
+
current_dialog_message: string;
|
|
10
|
+
open_dialog_count: number;
|
|
11
|
+
}
|
|
12
|
+
export interface TransformedProperties {
|
|
13
|
+
}
|
|
14
|
+
export interface SettableProperties {
|
|
15
|
+
}
|
|
16
|
+
export interface ObservableProperties {
|
|
17
|
+
open_dialog_count: number;
|
|
18
|
+
}
|
|
19
|
+
export declare class Application extends Namespace<GettableProperties, TransformedProperties, SettableProperties, ObservableProperties> {
|
|
20
|
+
constructor(ableton: Ableton);
|
|
21
|
+
pressCurrentDialogButton(index: number): Promise<any>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __extends = (this && this.__extends) || (function () {
|
|
3
|
+
var extendStatics = function (d, b) {
|
|
4
|
+
extendStatics = Object.setPrototypeOf ||
|
|
5
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
+
return extendStatics(d, b);
|
|
8
|
+
};
|
|
9
|
+
return function (d, b) {
|
|
10
|
+
if (typeof b !== "function" && b !== null)
|
|
11
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
+
extendStatics(d, b);
|
|
13
|
+
function __() { this.constructor = d; }
|
|
14
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
+
};
|
|
16
|
+
})();
|
|
17
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
18
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
19
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
20
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
21
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
22
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
23
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
27
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
28
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
29
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
30
|
+
function step(op) {
|
|
31
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
32
|
+
while (_) try {
|
|
33
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
34
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
35
|
+
switch (op[0]) {
|
|
36
|
+
case 0: case 1: t = op; break;
|
|
37
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
38
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
39
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
40
|
+
default:
|
|
41
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
42
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
43
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
44
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
45
|
+
if (t[2]) _.ops.pop();
|
|
46
|
+
_.trys.pop(); continue;
|
|
47
|
+
}
|
|
48
|
+
op = body.call(thisArg, _);
|
|
49
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
50
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
54
|
+
exports.Application = void 0;
|
|
55
|
+
var _1 = require(".");
|
|
56
|
+
var Application = /** @class */ (function (_super) {
|
|
57
|
+
__extends(Application, _super);
|
|
58
|
+
function Application(ableton) {
|
|
59
|
+
return _super.call(this, ableton, "application") || this;
|
|
60
|
+
}
|
|
61
|
+
Application.prototype.pressCurrentDialogButton = function (index) {
|
|
62
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
63
|
+
return __generator(this, function (_a) {
|
|
64
|
+
return [2 /*return*/, this.sendCommand("press_current_dialog_button", [index])];
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
return Application;
|
|
69
|
+
}(_1.Namespace));
|
|
70
|
+
exports.Application = Application;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "jest-extended";
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (_) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
var tests_1 = require("../util/tests");
|
|
40
|
+
require("jest-extended");
|
|
41
|
+
var gettableProps = [
|
|
42
|
+
"major_version",
|
|
43
|
+
"minor_version",
|
|
44
|
+
"bugfix_version",
|
|
45
|
+
"version",
|
|
46
|
+
"open_dialog_count",
|
|
47
|
+
"current_dialog_message",
|
|
48
|
+
"current_dialog_button_count",
|
|
49
|
+
];
|
|
50
|
+
describe("Application", function () {
|
|
51
|
+
it("should be able to read all properties without erroring", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
52
|
+
return __generator(this, function (_a) {
|
|
53
|
+
switch (_a.label) {
|
|
54
|
+
case 0: return [4 /*yield*/, tests_1.withAbleton(function (ab) { return __awaiter(void 0, void 0, void 0, function () {
|
|
55
|
+
return __generator(this, function (_a) {
|
|
56
|
+
switch (_a.label) {
|
|
57
|
+
case 0: return [4 /*yield*/, Promise.all(gettableProps.map(function (p) { return ab.application.get(p); }))];
|
|
58
|
+
case 1:
|
|
59
|
+
_a.sent();
|
|
60
|
+
return [2 /*return*/];
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}); })];
|
|
64
|
+
case 1:
|
|
65
|
+
_a.sent();
|
|
66
|
+
return [2 /*return*/];
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}); });
|
|
70
|
+
});
|
package/ns/clip.d.ts
CHANGED
|
@@ -115,6 +115,7 @@ export interface ObservableProperties {
|
|
|
115
115
|
is_recording: boolean;
|
|
116
116
|
loop_end: number;
|
|
117
117
|
loop_start: number;
|
|
118
|
+
name: string;
|
|
118
119
|
pitch_coarse: number;
|
|
119
120
|
pitch_fine: number;
|
|
120
121
|
playing_position: number;
|
|
@@ -127,6 +128,7 @@ export interface ObservableProperties {
|
|
|
127
128
|
}
|
|
128
129
|
export interface RawClip {
|
|
129
130
|
id: number;
|
|
131
|
+
name: string;
|
|
130
132
|
color: number;
|
|
131
133
|
is_audio_clip: boolean;
|
|
132
134
|
is_midi_clip: boolean;
|
package/ns/song.spec.js
CHANGED
|
@@ -143,7 +143,7 @@ describe("Song", function () {
|
|
|
143
143
|
switch (_a.label) {
|
|
144
144
|
case 0:
|
|
145
145
|
largeArray = [];
|
|
146
|
-
for (i = 0; i <
|
|
146
|
+
for (i = 0; i < 100000; i++) {
|
|
147
147
|
largeArray.push(i);
|
|
148
148
|
}
|
|
149
149
|
return [4 /*yield*/, ab.song.setData("abletonjs_test", largeArray)];
|
package/ns/track.d.ts
CHANGED
|
@@ -2,9 +2,11 @@ import { Ableton } from "..";
|
|
|
2
2
|
import { Namespace } from ".";
|
|
3
3
|
import { Device, RawDevice } from "./device";
|
|
4
4
|
import { ClipSlot, RawClipSlot } from "./clip-slot";
|
|
5
|
+
import { Clip, RawClip } from "./clip";
|
|
5
6
|
import { Color } from "../util/color";
|
|
6
7
|
export interface GettableProperties {
|
|
7
8
|
arm: boolean;
|
|
9
|
+
arrangement_clips: RawClip[];
|
|
8
10
|
can_be_armed: boolean;
|
|
9
11
|
can_be_frozen: boolean;
|
|
10
12
|
can_show_chains: boolean;
|
|
@@ -48,6 +50,7 @@ export interface TransformedProperties {
|
|
|
48
50
|
color: Color;
|
|
49
51
|
devices: Device[];
|
|
50
52
|
clip_slots: ClipSlot[];
|
|
53
|
+
arrangement_clips: Clip[];
|
|
51
54
|
}
|
|
52
55
|
export interface SettableProperties {
|
|
53
56
|
arm: boolean;
|
|
@@ -77,6 +80,7 @@ export interface SettableProperties {
|
|
|
77
80
|
}
|
|
78
81
|
export interface ObservableProperties {
|
|
79
82
|
arm: number;
|
|
83
|
+
arrangement_clips: RawClip[];
|
|
80
84
|
clip_slots: RawClipSlot[];
|
|
81
85
|
color_index: number;
|
|
82
86
|
color: number;
|
package/ns/track.js
CHANGED
|
@@ -19,6 +19,7 @@ exports.Track = void 0;
|
|
|
19
19
|
var _1 = require(".");
|
|
20
20
|
var device_1 = require("./device");
|
|
21
21
|
var clip_slot_1 = require("./clip-slot");
|
|
22
|
+
var clip_1 = require("./clip");
|
|
22
23
|
var color_1 = require("../util/color");
|
|
23
24
|
var Track = /** @class */ (function (_super) {
|
|
24
25
|
__extends(Track, _super);
|
|
@@ -26,10 +27,13 @@ var Track = /** @class */ (function (_super) {
|
|
|
26
27
|
var _this = _super.call(this, ableton, "track", raw.id) || this;
|
|
27
28
|
_this.raw = raw;
|
|
28
29
|
_this.transformers = {
|
|
30
|
+
arrangement_clips: function (clips) {
|
|
31
|
+
return clips.map(function (clip) { return new clip_1.Clip(ableton, clip); });
|
|
32
|
+
},
|
|
29
33
|
color: function (c) { return new color_1.Color(c); },
|
|
30
|
-
devices: function (devices) { return devices.map(function (d) { return new device_1.Device(
|
|
34
|
+
devices: function (devices) { return devices.map(function (d) { return new device_1.Device(ableton, d); }); },
|
|
31
35
|
clip_slots: function (clip_slots) {
|
|
32
|
-
return clip_slots.map(function (c) { return new clip_slot_1.ClipSlot(
|
|
36
|
+
return clip_slots.map(function (c) { return new clip_slot_1.ClipSlot(ableton, c); });
|
|
33
37
|
},
|
|
34
38
|
};
|
|
35
39
|
return _this;
|
package/package.json
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ableton-js",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Control Ableton Live from Node",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"author": "Leo Bernard <admin@leolabs.org>",
|
|
7
7
|
"license": "MIT",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/leolabs/ableton-js.git"
|
|
11
|
+
},
|
|
8
12
|
"files": [
|
|
9
13
|
"**/*.js",
|
|
10
14
|
"**/*.d.ts",
|
|
@@ -16,7 +20,7 @@
|
|
|
16
20
|
"ableton10:launch": "set -- /Applications/Ableton*10* && open \"$1\"",
|
|
17
21
|
"ableton11:copy-script": "set -- /Applications/Ableton*11*/Contents/App-Resources/MIDI\\ Remote\\ Scripts && rm -rf \"$1/AbletonJS\" && cp -r \"$(pwd)/midi-script\" \"$1/AbletonJS\" && rm -rf \"$1/AbletonJS/_Framework\"",
|
|
18
22
|
"ableton11:launch": "set -- /Applications/Ableton*11* && open \"$1\"",
|
|
19
|
-
"ableton:logs": "tail -f ~/Library/Preferences/Ableton/*/Log.txt | grep -i -e RemoteScriptError -e RemoteScriptMessage
|
|
23
|
+
"ableton:logs": "tail -f ~/Library/Preferences/Ableton/*/Log.txt | grep -i -e RemoteScriptError -e RemoteScriptMessage",
|
|
20
24
|
"ableton:kill": "pkill -KILL -f \"Ableton Live\"",
|
|
21
25
|
"ableton10:start": "yarn ableton:kill; yarn ableton:clean && yarn ableton10:copy-script && yarn ableton10:launch && yarn ableton:logs",
|
|
22
26
|
"ableton11:start": "yarn ableton:kill; yarn ableton:clean && yarn ableton11:copy-script && yarn ableton11:launch && yarn ableton:logs",
|