ableton-js 2.7.4 → 2.9.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 CHANGED
@@ -4,8 +4,27 @@ 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.9.0](https://github.com/leolabs/ableton.js/compare/v2.8.0...v2.9.0)
8
+
9
+ - Fix outdated ID types [`#81`](https://github.com/leolabs/ableton.js/pull/81)
10
+ - :sparkles: Add support for the application view [`50adde2`](https://github.com/leolabs/ableton.js/commit/50adde2ee7b59b602b7c0e0d3ec1d0817cbf5468)
11
+ - :art: Automatically convert iterable fields to lists [`56b2191`](https://github.com/leolabs/ableton.js/commit/56b21917a772e5cdef6c3568a3cd4458fab26c28)
12
+
13
+ #### [v2.8.0](https://github.com/leolabs/ableton.js/compare/v2.7.4...v2.8.0)
14
+
15
+ > 12 January 2023
16
+
17
+ - :sparkles: Add support for the `mixer_device` property [`#80`](https://github.com/leolabs/ableton.js/pull/80)
18
+ - :bug: duplicateClipToArrangement raw id should be a string instead of a number [`#75`](https://github.com/leolabs/ableton.js/pull/75)
19
+ - :bug: duplicateClipToArrangement raw id should be a string instead of a number (#75) [`#74`](https://github.com/leolabs/ableton-js/issues/74)
20
+ - :sparkles: Expose all MixerDevice parameters as DeviceParameter objects [`ac70a1e`](https://github.com/leolabs/ableton.js/commit/ac70a1e268dc038ac881604180b964b56983a402)
21
+ - :art: Fix typo in DeviceParameter serialization function [`eac46ec`](https://github.com/leolabs/ableton.js/commit/eac46ec1fae01689b135d28cdf93a1ea10df3f88)
22
+ - :label: Require all transformed properties to exist on the transformers object [`13156c3`](https://github.com/leolabs/ableton.js/commit/13156c3a5102b3e1e485658aed110b03e3b0ad66)
23
+
7
24
  #### [v2.7.4](https://github.com/leolabs/ableton.js/compare/v2.7.3...v2.7.4)
8
25
 
26
+ > 26 December 2022
27
+
9
28
  - :sparkles: Add a fire() function to scenes [`96e603d`](https://github.com/leolabs/ableton.js/commit/96e603df99df6a0d3b57ed2b4ccc674f2f14695f)
10
29
 
11
30
  #### [v2.7.3](https://github.com/leolabs/ableton.js/compare/v2.7.2...v2.7.3)
@@ -1,12 +1,13 @@
1
1
  from __future__ import absolute_import
2
- import sys
3
2
 
4
3
  from .Socket import Socket
5
4
  from .Interface import Interface
6
5
  from .Application import Application
6
+ from .ApplicationView import ApplicationView
7
7
  from .CuePoint import CuePoint
8
8
  from .Device import Device
9
9
  from .DeviceParameter import DeviceParameter
10
+ from .MixerDevice import MixerDevice
10
11
  from .Scene import Scene
11
12
  from .Song import Song
12
13
  from .SongView import SongView
@@ -15,6 +16,7 @@ from .Internal import Internal
15
16
  from .ClipSlot import ClipSlot
16
17
  from .Clip import Clip
17
18
  from .Midi import Midi
19
+
18
20
  from _Framework.ControlSurface import ControlSurface
19
21
  import Live
20
22
 
@@ -30,17 +32,19 @@ class AbletonJS(ControlSurface):
30
32
 
31
33
  self.handlers = {
32
34
  "application": Application(c_instance, self.socket, self.application()),
33
- "internal": Internal(c_instance, self.socket),
35
+ "application-view": ApplicationView(c_instance, self.socket, self.application()),
34
36
  "cue-point": CuePoint(c_instance, self.socket),
35
37
  "device": Device(c_instance, self.socket),
36
38
  "device-parameter": DeviceParameter(c_instance, self.socket),
39
+ "internal": Internal(c_instance, self.socket),
40
+ "midi": Midi(c_instance, self.socket, self.tracked_midi, self.request_rebuild_midi_map),
41
+ "mixer-device": MixerDevice(c_instance, self.socket),
37
42
  "scene": Scene(c_instance, self.socket),
38
43
  "song": Song(c_instance, self.socket),
39
44
  "song-view": SongView(c_instance, self.socket),
40
45
  "track": Track(c_instance, self.socket),
41
46
  "clip_slot": ClipSlot(c_instance, self.socket),
42
47
  "clip": Clip(c_instance, self.socket),
43
- "midi": Midi(c_instance, self.socket, self.tracked_midi, self.request_rebuild_midi_map)
44
48
  }
45
49
 
46
50
  self.recv_loop = Live.Base.Timer(
@@ -1,8 +1,6 @@
1
1
  from __future__ import absolute_import
2
2
  from .Interface import Interface
3
3
 
4
- import Live
5
-
6
4
 
7
5
  class Application(Interface):
8
6
  def __init__(self, c_instance, socket, application):
@@ -0,0 +1,11 @@
1
+ from __future__ import absolute_import
2
+ from .Interface import Interface
3
+
4
+
5
+ class ApplicationView(Interface):
6
+ def __init__(self, c_instance, socket, application):
7
+ super(ApplicationView, self).__init__(c_instance, socket)
8
+ self.application = application
9
+
10
+ def get_ns(self, nsid=None):
11
+ return self.application.view
@@ -23,9 +23,6 @@ class Clip(Interface):
23
23
  def __init__(self, c_instance, socket):
24
24
  super(Clip, self).__init__(c_instance, socket)
25
25
 
26
- def get_available_warp_modes(self, ns):
27
- return list(ns.available_warp_modes)
28
-
29
26
  def get_notes(self, ns, from_time=0, from_pitch=0, time_span=99999999999999, pitch_span=128):
30
27
  return ns.get_notes(from_time, from_pitch, time_span, pitch_span)
31
28
 
@@ -21,7 +21,7 @@ class Device(Interface):
21
21
  super(Device, self).__init__(c_instance, socket)
22
22
 
23
23
  def get_parameters(self, ns):
24
- return list(list(map(DeviceParameter.serialize_device_paramater, ns.parameters)))
24
+ return map(DeviceParameter.serialize_device_parameter, ns.parameters)
25
25
 
26
26
  def get_type(self, ns):
27
27
  return str(ns.type)
@@ -4,13 +4,13 @@ from .Interface import Interface
4
4
 
5
5
  class DeviceParameter(Interface):
6
6
  @staticmethod
7
- def serialize_device_paramater(param):
7
+ def serialize_device_parameter(param):
8
8
  if param is None:
9
9
  return None
10
10
 
11
- device_paramater_id = Interface.save_obj(param)
11
+ device_parameter_id = Interface.save_obj(param)
12
12
  return {
13
- "id": device_paramater_id,
13
+ "id": device_parameter_id,
14
14
  "name": param.name,
15
15
  "value": param.value,
16
16
  "is_quantized": param.is_quantized
@@ -18,6 +18,3 @@ class DeviceParameter(Interface):
18
18
 
19
19
  def __init__(self, c_instance, socket):
20
20
  super(DeviceParameter, self).__init__(c_instance, socket)
21
-
22
- def get_value_items(self, ns):
23
- return list(ns.value_items)
@@ -10,4 +10,4 @@ class Internal(Interface):
10
10
  return self
11
11
 
12
12
  def get_version(self, ns):
13
- return "2.7.4"
13
+ return "2.9.0"
@@ -0,0 +1,44 @@
1
+ from __future__ import absolute_import
2
+
3
+ from .DeviceParameter import DeviceParameter
4
+ from .Interface import Interface
5
+
6
+
7
+ class MixerDevice(Interface):
8
+ @staticmethod
9
+ def serialize_mixer_device(mixer_device):
10
+ if mixer_device is None:
11
+ return None
12
+
13
+ device_id = Interface.save_obj(mixer_device)
14
+ return {"id": device_id, "volume": mixer_device.volume}
15
+
16
+ def __init__(self, c_instance, socket):
17
+ super(MixerDevice, self).__init__(c_instance, socket)
18
+
19
+ def get_crossfader(self, ns):
20
+ return DeviceParameter.serialize_device_parameter(ns.crossfader)
21
+
22
+ def get_cue_volume(self, ns):
23
+ return DeviceParameter.serialize_device_parameter(ns.cue_volume)
24
+
25
+ def get_left_split_stereo(self, ns):
26
+ return DeviceParameter.serialize_device_parameter(ns.left_split_stereo)
27
+
28
+ def get_panning(self, ns):
29
+ return DeviceParameter.serialize_device_parameter(ns.panning)
30
+
31
+ def get_right_split_stereo(self, ns):
32
+ return DeviceParameter.serialize_device_parameter(ns.right_split_stereo)
33
+
34
+ def get_sends(self, ns):
35
+ return map(DeviceParameter.serialize_device_parameter, ns.sends)
36
+
37
+ def get_song_tempo(self, ns):
38
+ return DeviceParameter.serialize_device_parameter(ns.song_tempo)
39
+
40
+ def get_track_activator(self, ns):
41
+ return DeviceParameter.serialize_device_parameter(ns.track_activator)
42
+
43
+ def get_volume(self, ns):
44
+ return DeviceParameter.serialize_device_parameter(ns.volume)
@@ -16,4 +16,4 @@ class Scene(Interface):
16
16
  super(Scene, self).__init__(c_instance, socket)
17
17
 
18
18
  def get_clip_slots(self, ns):
19
- return list(list(map(ClipSlot.serialize_clip_slot, ns.clip_slots)))
19
+ return map(ClipSlot.serialize_clip_slot, ns.clip_slots)
@@ -5,6 +5,8 @@ import zlib
5
5
  import hashlib
6
6
  from threading import Timer
7
7
 
8
+ import Live
9
+
8
10
 
9
11
  def split_by_n(seq, n):
10
12
  '''A generator to divide a sequence into chunks of n units.'''
@@ -70,6 +72,8 @@ class Socket(object):
70
72
 
71
73
  def send(self, name, obj=None, uuid=None):
72
74
  def jsonReplace(o):
75
+ if isinstance(o, (map, Live.Base.FloatVector, Live.Base.IntVector, Live.Base.ObjectVector, Live.Base.StringVector, Live.Base.Vector)):
76
+ return list(o)
73
77
  return str(o)
74
78
 
75
79
  try:
@@ -27,7 +27,7 @@ class Song(Interface):
27
27
 
28
28
  def get_cue_points(self, ns):
29
29
  sorted_points = sorted(ns.cue_points, key=lambda cue: cue.time)
30
- return list(map(CuePoint.serialize_cue_point, sorted_points))
30
+ return map(CuePoint.serialize_cue_point, sorted_points)
31
31
 
32
32
  def get_master_track(self, ns):
33
33
  return Track.serialize_track(ns.master_track)
@@ -36,16 +36,16 @@ class Song(Interface):
36
36
  return str(ns.midi_recording_quantization)
37
37
 
38
38
  def get_return_tracks(self, ns):
39
- return list(map(Track.serialize_track, ns.return_tracks))
39
+ return map(Track.serialize_track, ns.return_tracks)
40
40
 
41
41
  def get_scenes(self, ns):
42
- return list(map(Scene.serialize_scene, ns.scenes))
42
+ return map(Scene.serialize_scene, ns.scenes)
43
43
 
44
44
  def get_tracks(self, ns):
45
- return list(map(Track.serialize_track, ns.tracks))
45
+ return map(Track.serialize_track, ns.tracks)
46
46
 
47
47
  def get_visible_tracks(self, ns):
48
- return list(map(Track.serialize_track, ns.visible_tracks))
48
+ return map(Track.serialize_track, ns.visible_tracks)
49
49
 
50
50
  def get_data(self, ns, key):
51
51
  return ns.get_data(key, None)
@@ -17,7 +17,7 @@ class SongView(Interface):
17
17
  return ns.select_device(Interface.get_obj(device_id))
18
18
 
19
19
  def get_selected_parameter(self, ns):
20
- return DeviceParameter.serialize_device_paramater(ns.selected_parameter)
20
+ return DeviceParameter.serialize_device_parameter(ns.selected_parameter)
21
21
 
22
22
  def get_selected_track(self, ns):
23
23
  return Track.serialize_track(ns.selected_track)
@@ -36,4 +36,3 @@ class SongView(Interface):
36
36
 
37
37
  def set_highlighted_clip_slot(self, ns, slot_id):
38
38
  ns.highlighted_clip_slot = Interface.get_obj(slot_id)
39
-
@@ -1,5 +1,7 @@
1
1
  from __future__ import absolute_import
2
+
2
3
  from .Interface import Interface
4
+ from .MixerDevice import MixerDevice
3
5
  from .Device import Device
4
6
  from .Clip import Clip
5
7
  from .ClipSlot import ClipSlot
@@ -18,16 +20,19 @@ class Track(Interface):
18
20
  super(Track, self).__init__(c_instance, socket)
19
21
 
20
22
  def get_arrangement_clips(self, ns):
21
- return list(map(Clip.serialize_clip, ns.arrangement_clips))
23
+ return map(Clip.serialize_clip, ns.arrangement_clips)
22
24
 
23
25
  def get_devices(self, ns):
24
- return list(map(Device.serialize_device, ns.devices))
26
+ return map(Device.serialize_device, ns.devices)
25
27
 
26
28
  def get_clip_slots(self, ns):
27
- return list(map(ClipSlot.serialize_clip_slot, ns.clip_slots))
29
+ return map(ClipSlot.serialize_clip_slot, ns.clip_slots)
28
30
 
29
31
  def get_group_track(self, ns):
30
32
  return Track.serialize_track(ns.group_track)
31
33
 
34
+ def get_mixer_device(self, ns):
35
+ return MixerDevice.serialize_mixer_device(ns.mixer_device)
36
+
32
37
  def duplicate_clip_to_arrangement(self, ns, clip_id, time):
33
38
  return ns.duplicate_clip_to_arrangement(self.get_obj(clip_id), time)
@@ -0,0 +1,34 @@
1
+ import { Ableton } from "..";
2
+ import { Namespace } from ".";
3
+ export declare type DocumentView = "Session" | "Arranger";
4
+ export declare type DetailView = "Detail" | "Detail/Clip" | "Detail/DeviceChain";
5
+ export declare type View = "Browser" | DocumentView | DetailView;
6
+ export declare enum NavDirection {
7
+ "up" = 0,
8
+ "down" = 1,
9
+ "left" = 2,
10
+ "right" = 3
11
+ }
12
+ export interface GettableProperties {
13
+ browse_mode: boolean;
14
+ focused_document_view: DocumentView;
15
+ }
16
+ export interface TransformedProperties {
17
+ }
18
+ export interface SettableProperties {
19
+ }
20
+ export interface ObservableProperties {
21
+ browse_mode: boolean;
22
+ focused_document_view: DocumentView;
23
+ }
24
+ export declare class ApplicationView extends Namespace<GettableProperties, TransformedProperties, SettableProperties, ObservableProperties> {
25
+ constructor(ableton: Ableton);
26
+ availableMainViews(): Promise<View[]>;
27
+ focusView(view: View): Promise<any>;
28
+ hideView(view: View): Promise<any>;
29
+ isViewVisible(view: View, mainWindowOnly?: boolean): Promise<any>;
30
+ scrollView(view: View, direction: NavDirection): Promise<any>;
31
+ showView(view: View): Promise<any>;
32
+ toggleBrowse(): Promise<any>;
33
+ zoomView(view: View, direction: NavDirection): Promise<any>;
34
+ }
@@ -0,0 +1,127 @@
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.ApplicationView = exports.NavDirection = void 0;
55
+ var _1 = require(".");
56
+ var NavDirection;
57
+ (function (NavDirection) {
58
+ NavDirection[NavDirection["up"] = 0] = "up";
59
+ NavDirection[NavDirection["down"] = 1] = "down";
60
+ NavDirection[NavDirection["left"] = 2] = "left";
61
+ NavDirection[NavDirection["right"] = 3] = "right";
62
+ })(NavDirection = exports.NavDirection || (exports.NavDirection = {}));
63
+ var ApplicationView = /** @class */ (function (_super) {
64
+ __extends(ApplicationView, _super);
65
+ function ApplicationView(ableton) {
66
+ return _super.call(this, ableton, "application-view") || this;
67
+ }
68
+ ApplicationView.prototype.availableMainViews = function () {
69
+ return __awaiter(this, void 0, void 0, function () {
70
+ return __generator(this, function (_a) {
71
+ return [2 /*return*/, this.sendCachedCommand("available_main_views")];
72
+ });
73
+ });
74
+ };
75
+ ApplicationView.prototype.focusView = function (view) {
76
+ return __awaiter(this, void 0, void 0, function () {
77
+ return __generator(this, function (_a) {
78
+ return [2 /*return*/, this.sendCommand("focus_view", [view])];
79
+ });
80
+ });
81
+ };
82
+ ApplicationView.prototype.hideView = function (view) {
83
+ return __awaiter(this, void 0, void 0, function () {
84
+ return __generator(this, function (_a) {
85
+ return [2 /*return*/, this.sendCommand("hide_view", [view])];
86
+ });
87
+ });
88
+ };
89
+ ApplicationView.prototype.isViewVisible = function (view, mainWindowOnly) {
90
+ if (mainWindowOnly === void 0) { mainWindowOnly = true; }
91
+ return __awaiter(this, void 0, void 0, function () {
92
+ return __generator(this, function (_a) {
93
+ return [2 /*return*/, this.sendCommand("is_view_visible", [view, mainWindowOnly])];
94
+ });
95
+ });
96
+ };
97
+ ApplicationView.prototype.scrollView = function (view, direction) {
98
+ return __awaiter(this, void 0, void 0, function () {
99
+ return __generator(this, function (_a) {
100
+ return [2 /*return*/, this.sendCommand("scroll_view", [direction, view, true])];
101
+ });
102
+ });
103
+ };
104
+ ApplicationView.prototype.showView = function (view) {
105
+ return __awaiter(this, void 0, void 0, function () {
106
+ return __generator(this, function (_a) {
107
+ return [2 /*return*/, this.sendCommand("show_view", [view])];
108
+ });
109
+ });
110
+ };
111
+ ApplicationView.prototype.toggleBrowse = function () {
112
+ return __awaiter(this, void 0, void 0, function () {
113
+ return __generator(this, function (_a) {
114
+ return [2 /*return*/, this.sendCommand("toggle_browse")];
115
+ });
116
+ });
117
+ };
118
+ ApplicationView.prototype.zoomView = function (view, direction) {
119
+ return __awaiter(this, void 0, void 0, function () {
120
+ return __generator(this, function (_a) {
121
+ return [2 /*return*/, this.sendCommand("zoom_view", [direction, view, true])];
122
+ });
123
+ });
124
+ };
125
+ return ApplicationView;
126
+ }(_1.Namespace));
127
+ exports.ApplicationView = ApplicationView;
@@ -0,0 +1 @@
1
+ import "jest-extended";
@@ -0,0 +1,65 @@
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
+ "browse_mode",
43
+ "focused_document_view",
44
+ ];
45
+ describe("Application", function () {
46
+ it("should be able to read all properties without erroring", function () { return __awaiter(void 0, void 0, void 0, function () {
47
+ return __generator(this, function (_a) {
48
+ switch (_a.label) {
49
+ case 0: return [4 /*yield*/, tests_1.withAbleton(function (ab) { return __awaiter(void 0, void 0, void 0, function () {
50
+ return __generator(this, function (_a) {
51
+ switch (_a.label) {
52
+ case 0: return [4 /*yield*/, Promise.all(gettableProps.map(function (p) { return ab.application.view.get(p); }))];
53
+ case 1:
54
+ _a.sent();
55
+ return [2 /*return*/];
56
+ }
57
+ });
58
+ }); })];
59
+ case 1:
60
+ _a.sent();
61
+ return [2 /*return*/];
62
+ }
63
+ });
64
+ }); });
65
+ });
@@ -1,5 +1,6 @@
1
1
  import { Ableton } from "..";
2
2
  import { Namespace } from ".";
3
+ import { ApplicationView } from "./application-view";
3
4
  export interface GettableProperties {
4
5
  bugfix_version: number;
5
6
  major_version: number;
@@ -18,5 +19,6 @@ export interface ObservableProperties {
18
19
  }
19
20
  export declare class Application extends Namespace<GettableProperties, TransformedProperties, SettableProperties, ObservableProperties> {
20
21
  constructor(ableton: Ableton);
22
+ view: ApplicationView;
21
23
  pressCurrentDialogButton(index: number): Promise<any>;
22
24
  }
package/ns/application.js CHANGED
@@ -53,10 +53,13 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
53
53
  Object.defineProperty(exports, "__esModule", { value: true });
54
54
  exports.Application = void 0;
55
55
  var _1 = require(".");
56
+ var application_view_1 = require("./application-view");
56
57
  var Application = /** @class */ (function (_super) {
57
58
  __extends(Application, _super);
58
59
  function Application(ableton) {
59
- return _super.call(this, ableton, "application") || this;
60
+ var _this = _super.call(this, ableton, "application") || this;
61
+ _this.view = new application_view_1.ApplicationView(_this.ableton);
62
+ return _this;
60
63
  }
61
64
  Application.prototype.pressCurrentDialogButton = function (index) {
62
65
  return __awaiter(this, void 0, void 0, function () {
package/ns/index.d.ts CHANGED
@@ -3,9 +3,9 @@ export declare class Namespace<GP, TP, SP, OP> {
3
3
  protected ableton: Ableton;
4
4
  protected ns: string;
5
5
  protected nsid?: string | undefined;
6
- protected transformers: Partial<{
6
+ protected transformers: {
7
7
  [T in keyof TP]: (val: T extends keyof GP ? GP[T] : unknown) => TP[T];
8
- }>;
8
+ };
9
9
  protected cachedProps: Partial<{
10
10
  [T in keyof GP]: boolean;
11
11
  }>;
@@ -0,0 +1,53 @@
1
+ import { Ableton } from "..";
2
+ import { Namespace } from ".";
3
+ import { DeviceParameter, RawDeviceParameter } from "./device-parameter";
4
+ export declare enum PanningMode {
5
+ Stereo = 0,
6
+ StereoSplit = 1
7
+ }
8
+ export declare enum CrossfadeAssignment {
9
+ A = 0,
10
+ None = 1,
11
+ B = 2
12
+ }
13
+ export interface GettableProperties {
14
+ crossfade_assign: CrossfadeAssignment;
15
+ crossfader: RawDeviceParameter;
16
+ cue_volume: RawDeviceParameter;
17
+ left_split_stereo: RawDeviceParameter;
18
+ panning: RawDeviceParameter;
19
+ panning_mode: PanningMode;
20
+ right_split_stereo: RawDeviceParameter;
21
+ sends: RawDeviceParameter[];
22
+ song_tempo: RawDeviceParameter;
23
+ track_activator: RawDeviceParameter;
24
+ volume: RawDeviceParameter;
25
+ }
26
+ export interface TransformedProperties {
27
+ crossfader: DeviceParameter;
28
+ cue_volume: DeviceParameter;
29
+ left_split_stereo: DeviceParameter;
30
+ panning: DeviceParameter;
31
+ right_split_stereo: DeviceParameter;
32
+ sends: DeviceParameter[];
33
+ song_tempo: DeviceParameter;
34
+ track_activator: DeviceParameter;
35
+ volume: DeviceParameter;
36
+ }
37
+ export interface SettableProperties {
38
+ crossfade_assign: CrossfadeAssignment;
39
+ panning_mode: string;
40
+ }
41
+ export interface ObservableProperties {
42
+ crossfade_assign: CrossfadeAssignment;
43
+ panning_mode: string;
44
+ sends: RawDeviceParameter[];
45
+ }
46
+ export interface RawMixerDevice {
47
+ id: string;
48
+ volume: string;
49
+ }
50
+ export declare class MixerDevice extends Namespace<GettableProperties, TransformedProperties, SettableProperties, ObservableProperties> {
51
+ raw: RawMixerDevice;
52
+ constructor(ableton: Ableton, raw: RawMixerDevice);
53
+ }
@@ -0,0 +1,52 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.MixerDevice = exports.CrossfadeAssignment = exports.PanningMode = void 0;
19
+ var _1 = require(".");
20
+ var device_parameter_1 = require("./device-parameter");
21
+ var PanningMode;
22
+ (function (PanningMode) {
23
+ PanningMode[PanningMode["Stereo"] = 0] = "Stereo";
24
+ PanningMode[PanningMode["StereoSplit"] = 1] = "StereoSplit";
25
+ })(PanningMode = exports.PanningMode || (exports.PanningMode = {}));
26
+ var CrossfadeAssignment;
27
+ (function (CrossfadeAssignment) {
28
+ CrossfadeAssignment[CrossfadeAssignment["A"] = 0] = "A";
29
+ CrossfadeAssignment[CrossfadeAssignment["None"] = 1] = "None";
30
+ CrossfadeAssignment[CrossfadeAssignment["B"] = 2] = "B";
31
+ })(CrossfadeAssignment = exports.CrossfadeAssignment || (exports.CrossfadeAssignment = {}));
32
+ var MixerDevice = /** @class */ (function (_super) {
33
+ __extends(MixerDevice, _super);
34
+ function MixerDevice(ableton, raw) {
35
+ var _this = _super.call(this, ableton, "mixer-device", raw.id) || this;
36
+ _this.raw = raw;
37
+ _this.transformers = {
38
+ crossfader: function (v) { return new device_parameter_1.DeviceParameter(ableton, v); },
39
+ cue_volume: function (v) { return new device_parameter_1.DeviceParameter(ableton, v); },
40
+ left_split_stereo: function (v) { return new device_parameter_1.DeviceParameter(ableton, v); },
41
+ panning: function (v) { return new device_parameter_1.DeviceParameter(ableton, v); },
42
+ right_split_stereo: function (v) { return new device_parameter_1.DeviceParameter(ableton, v); },
43
+ sends: function (v) { return v.map(function (s) { return new device_parameter_1.DeviceParameter(ableton, s); }); },
44
+ song_tempo: function (v) { return new device_parameter_1.DeviceParameter(ableton, v); },
45
+ track_activator: function (v) { return new device_parameter_1.DeviceParameter(ableton, v); },
46
+ volume: function (v) { return new device_parameter_1.DeviceParameter(ableton, v); },
47
+ };
48
+ return _this;
49
+ }
50
+ return MixerDevice;
51
+ }(_1.Namespace));
52
+ exports.MixerDevice = MixerDevice;
@@ -0,0 +1 @@
1
+ import "jest-extended";
@@ -0,0 +1,81 @@
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
+ //"crossfade_assign", (not applicable to the master track)
43
+ "crossfader",
44
+ "cue_volume",
45
+ "left_split_stereo",
46
+ "panning",
47
+ "panning_mode",
48
+ "right_split_stereo",
49
+ "sends",
50
+ "song_tempo",
51
+ "track_activator",
52
+ "volume",
53
+ ];
54
+ describe("Mixer Device", function () {
55
+ it("should be able to read all properties without erroring", function () { return __awaiter(void 0, void 0, void 0, function () {
56
+ return __generator(this, function (_a) {
57
+ switch (_a.label) {
58
+ case 0: return [4 /*yield*/, tests_1.withAbleton(function (ab) { return __awaiter(void 0, void 0, void 0, function () {
59
+ var masterTrack, mixerDevice;
60
+ return __generator(this, function (_a) {
61
+ switch (_a.label) {
62
+ case 0: return [4 /*yield*/, ab.song.get("master_track")];
63
+ case 1:
64
+ masterTrack = _a.sent();
65
+ return [4 /*yield*/, masterTrack.get("mixer_device")];
66
+ case 2:
67
+ mixerDevice = _a.sent();
68
+ return [4 /*yield*/, Promise.all(gettableProps.map(function (p) { return mixerDevice.get(p); }))];
69
+ case 3:
70
+ _a.sent();
71
+ return [2 /*return*/];
72
+ }
73
+ });
74
+ }); })];
75
+ case 1:
76
+ _a.sent();
77
+ return [2 /*return*/];
78
+ }
79
+ });
80
+ }); });
81
+ });
package/ns/song-view.d.ts CHANGED
@@ -26,8 +26,8 @@ export interface SettableProperties {
26
26
  draw_mode: boolean;
27
27
  follow_song: boolean;
28
28
  highlighted_clip_slot: number;
29
- selected_scene: number;
30
- selected_track: number;
29
+ selected_scene: RawScene['id'];
30
+ selected_track: RawTrack['id'];
31
31
  }
32
32
  export interface ObservableProperties {
33
33
  detail_clip: any;
package/ns/track.d.ts CHANGED
@@ -2,6 +2,7 @@ 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 { MixerDevice, RawMixerDevice } from "./mixer-device";
5
6
  import { Clip, RawClip } from "./clip";
6
7
  import { Color } from "../util/color";
7
8
  export interface GettableProperties {
@@ -37,6 +38,7 @@ export interface GettableProperties {
37
38
  is_part_of_selection: boolean;
38
39
  is_showing_chains: boolean;
39
40
  is_visible: boolean;
41
+ mixer_device: RawMixerDevice;
40
42
  mute: boolean;
41
43
  muted_via_solo: boolean;
42
44
  name: string;
@@ -51,6 +53,7 @@ export interface TransformedProperties {
51
53
  devices: Device[];
52
54
  clip_slots: ClipSlot[];
53
55
  arrangement_clips: Clip[];
56
+ mixer_device: MixerDevice;
54
57
  }
55
58
  export interface SettableProperties {
56
59
  arm: boolean;
@@ -124,5 +127,5 @@ export declare class Track extends Namespace<GettableProperties, TransformedProp
124
127
  * Duplicates the given clip into the arrangement of this track at the provided destination time and returns it.
125
128
  * When the type of the clip and the type of the track are incompatible, a runtime error is raised.
126
129
  */
127
- duplicateClipToArrangement(clipOrId: Clip | number, time: number): Promise<any>;
130
+ duplicateClipToArrangement(clipOrId: Clip | string, time: number): Promise<any>;
128
131
  }
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 mixer_device_1 = require("./mixer-device");
22
23
  var clip_1 = require("./clip");
23
24
  var color_1 = require("../util/color");
24
25
  var Track = /** @class */ (function (_super) {
@@ -35,6 +36,7 @@ var Track = /** @class */ (function (_super) {
35
36
  clip_slots: function (clip_slots) {
36
37
  return clip_slots.map(function (c) { return new clip_slot_1.ClipSlot(ableton, c); });
37
38
  },
39
+ mixer_device: function (mixer_device) { return new mixer_device_1.MixerDevice(ableton, mixer_device); },
38
40
  };
39
41
  _this.cachedProps = {
40
42
  arrangement_clips: true,
@@ -49,7 +51,7 @@ var Track = /** @class */ (function (_super) {
49
51
  */
50
52
  Track.prototype.duplicateClipToArrangement = function (clipOrId, time) {
51
53
  return this.sendCommand("duplicate_clip_to_arrangement", {
52
- clip_id: typeof clipOrId === "number" ? clipOrId : clipOrId.raw.id,
54
+ clip_id: typeof clipOrId === "string" ? clipOrId : clipOrId.raw.id,
53
55
  time: time,
54
56
  });
55
57
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ableton-js",
3
- "version": "2.7.4",
3
+ "version": "2.9.0",
4
4
  "description": "Control Ableton Live from Node",
5
5
  "main": "index.js",
6
6
  "author": "Leo Bernard <admin@leolabs.org>",