Coder Social home page Coder Social logo

ableton-js's Introduction

Ableton.js

Current Version

Ableton.js lets you control your instance or instances of Ableton using Node.js. It tries to cover as many functions as possible.

This package is still a work-in-progress. My goal is to expose all of Ableton's MIDI Remote Script functions to TypeScript. If you'd like to contribute, please feel free to do so.

Sponsored Message

I've used Ableton.js to build a setlist manager called AbleSet. AbleSet allows you to easily manage and control your Ableton setlists from any device, re-order songs and add notes to them, and get an overview of the current state of your set.

AbleSet Header

Prerequisites

To use this library, you'll need to install and activate the MIDI Remote Script in Ableton.js. To do that, copy the midi-script folder of this repo to Ableton's Remote Scripts folder and rename it to AbletonJS. The MIDI Remote Scripts folder is usually located at ~/Music/Ableton/User Library/Remote Scripts

After starting Ableton Live, add the script to your list of control surfaces:

Ableton Live Settings

If you've forked this project on macOS, you can also use yarn to do that for you. Running yarn ableton:start will copy the midi-script folder, open Ableton and show a stream of log messages until you kill it.

Using Ableton.js

This library exposes an Ableton class which lets you control the entire application. You can instantiate it once and use TS to explore available features.

Example:

import { Ableton } from "ableton-js";

// Log all messages to the console
const ableton = new Ableton({ logger: console });

const test = async () => {
  // Establishes a connection with Live
  await ableton.start();

  // Observe the current playback state and tempo
  ableton.song.addListener("is_playing", (p) => console.log("Playing:", p));
  ableton.song.addListener("tempo", (t) => console.log("Tempo:", t));

  // Get the current tempo
  const tempo = await ableton.song.get("tempo");
  console.log("Current tempo:", tempo);

  // Set the tempo
  await ableton.song.set("tempo", 85);
};

test();

Events

There are a few events you can use to get more under-the-hood insights:

// A connection to Ableton is established
ab.on("connect", (e) => console.log("Connect", e));

// Connection to Ableton was lost,
// also happens when you load a new project
ab.on("disconnect", (e) => console.log("Disconnect", e));

// A raw message was received from Ableton
ab.on("message", (m) => console.log("Message:", m));

// A received message could not be parsed
ab.on("error", (e) => console.error("Error:", e));

// Fires on every response with the current ping
ab.on("ping", (ping) => console.log("Ping:", ping, "ms"));

Protocol

Ableton.js uses UDP to communicate with the MIDI Script. Each message is a JSON object containing required data and a UUID so request and response can be associated with each other.

Used Ports

Both the client and the server bind to a random available port and store that port in a local file so the other side knows which port to send messages to.

Compression and Chunking

To allow sending large JSON payloads, requests to and responses from the MIDI Script are compressed using gzip and chunked to fit into the maximum allowed package size. The first byte of every message chunk contains the chunk index (0x00-0xFF) followed by the gzipped chunk. The last chunk always has the index 0xFF. This indicates to the JS library that the previous received messages should be stiched together, unzipped, and processed.

Caching

Certain props are cached on the client to reduce the bandwidth over UDP. To do this, the Ableton plugin generates an MD5 hash of the prop, called ETag, and sends it to the client along with the data.

The client stores both the ETag and the data in an LRU cache and sends the latest stored ETag to the plugin the next time the same prop is requested. If the data still matches the ETag, the plugin responds with a placeholder object and the client returns the cached data.

Commands

A command payload consists of the following properties:

{
  "uuid": "a20f25a0-83e2-11e9-bbe1-bd3a580ef903", // A unique command id
  "ns": "song", // The command namespace
  "nsid": null, // The namespace id, for example to address a specific track or device
  "name": "get_prop", // Command name
  "args": { "prop": "current_song_time" }, // Command arguments
  "etag": "4e0794e44c7eb58bdbbbf7268e8237b4", // MD5 hash of the data if it might be cached locally
  "cache": true // If this is true, the plugin will calculate an etag and return a placeholder if it matches the provided one
}

The MIDI Script answers with a JSON object looking like this:

{
  "data": 0.0, // The command's return value, can be of any JSON-compatible type
  "event": "result", // This can be 'result' or 'error'
  "uuid": "a20f25a0-83e2-11e9-bbe1-bd3a580ef903" // The same UUID that was used to send the command
}

If you're getting a cached prop, the JSON object could look like this:

{
  "data": { "data": 0.0, "etag": "4e0794e44c7eb58bdbbbf7268e8237b4" },
  "event": "result", // This can be 'result' or 'error'
  "uuid": "a20f25a0-83e2-11e9-bbe1-bd3a580ef903" // The same UUID that was used to send the command
}

Or, if the data hasn't changed, it looks like this:

{
  "data": { "__cached": true },
  "event": "result", // This can be 'result' or 'error'
  "uuid": "a20f25a0-83e2-11e9-bbe1-bd3a580ef903" // The same UUID that was used to send the command
}

Events

To attach an event listener to a specific property, the client sends a command object:

{
  "uuid": "922d54d0-83e3-11e9-ba7c-917478f8b91b", // A unique command id
  "ns": "song", // The command namespace
  "name": "add_listener", // The command to add an event listener
  "args": {
    "prop": "current_song_time", // The property that should be watched
    "eventId": "922d2dc0-83e3-11e9-ba7c-917478f8b91b" // A unique event id
  }
}

The MIDI Script answers with a JSON object looking like this to confirm that the listener has been attached:

{
  "data": "922d2dc0-83e3-11e9-ba7c-917478f8b91b", // The unique event id
  "event": "result", // Should be result, is error when something goes wrong
  "uuid": "922d54d0-83e3-11e9-ba7c-917478f8b91b" // The unique command id
}

From now on, when the observed property changes, the MIDI Script sends an event object:

{
  "data": 68.0, // The new value, can be any JSON-compatible type
  "event": "922d2dc0-83e3-11e9-ba7c-917478f8b91b", // The event id
  "uuid": null // Is always null and may be removed in future versions
}

Note that for some values, this event is emitted multiple times per second. 20-30 updates per second are not unusual.

Connection Events

The MIDI Script sends events when it starts and when it shuts down. These look like this:

{
  "data": null, // Is always null
  "event": "connect", // Can be connect or disconnect
  "uuid": null // Is always null and may be removed in future versions
}

When you open a new Project in Ableton, the script will shut down and start again.

When Ableton.js receives a disconnect event, it clears all current event listeners and pending commands. It is usually a good idea to attach all event listeners and get properties each time the connect event is emitted.

Findings

In this section, I'll note interesting pieces of information related to Ableton's Python framework that I stumble upon during the development of this library.

  • It seems like Ableton's listener to output_meter_level doesn't quite work as well as expected, hanging every few 100ms. Listening to output_meter_left or output_meter_right works better. See Issue #4
  • The playing_status listener of clip slots never fires in Ableton. See Issue #25

ableton-js's People

Contributors

chozilla avatar coeur-de-loup avatar devthane avatar fizzy123 avatar leolabs avatar shahyar avatar theactualwalko avatar zoetrope69 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ableton-js's Issues

Getting clip info

Hi,

First of all, thanks for your incredible work! Iโ€™m having a hard time figuring out where/how I can add event listeners to clips for a given song. Could you please point me to some documentation on how to access each name spacesโ€™ observable traits?

E.g. I see that if I want Song-View traits, I need to go through ableton.song.view.addEventListener. How do I do the same for all the clips loaded up?

get_prop() timeout on large dataset

Hi! First of all, thanks for this, it's an awesome library!

I'm having issues with timeouts, I'm doing a map of device parameters which have automation on them, which needs to be done on a large number of tracks, and i've encountered a couple of issues:

  1. The AutomationState enum is incorrectly setup, the AutomationState.Playing should be on the second slot, not the third as it is now, and the .Overridden should be on the third one, to accurately reflect what's happening in ableton.
  2. The mapping is not capturing all of the tracks, and i can't find a pattern in which it happens.
  3. This is the most urgent one, the framework times out after 2000ms, so i've changed it to 20000ms, but the timeout still happens, even though i'm not quite sure why. I'll attach the code and the ableton project for you to test out, i might be missing something really obvious.

Thanks a lot, and thank you for this beautiful piece of software! :) Cheers!

TimeoutIssue.zip

PS. I'm using Ableton 11.0.12.

Latency problems when upgrading to 3.3.0 from 3.1.7

Hi! I've just updated to the 3.3.0 version of this library from 3.1.7 and am noticing some significant differences in latency.

Here is the code I'm using to test the latency:

const { Ableton } = require("ableton-js");
const ableton = new Ableton({ logger: console });

(async () => {
  let start = (new Date()).getTime()
  await ableton.start();
  let time = await ableton.song.get("current_song_time");
  console.log(time)
  console.log("all set")
  console.log(((new Date()).getTime() - start))
})()

I'm running this code on a fresh new Ableton project. When I do so on 3.1.7, the script takes ~35ms. However, on 3.3.0, the script takes ~300ms.

I am downgrading for now and can help with any debugging. Thanks for your continued development on this great project!

[OFFTOP] how to use "output_meter_left" or any data for visualize

hi, thank you for this solution!!, is a very better for me)

please tell me if u know, how i can use "output_meter_left" data for visualize, im trying make self algorithm but attempt be fail, sorry for offtop, but i idk where i can ask this question, thanks for any reply!!!

How to use?

Sorry for a beginner question, but I'm not familiar with TypeScript and I feel that the process for using this library is different from other Node modules that I've tried.

I'm not really sure where the example code in the readme should go. Do I need to build the package before using it in my own index.js file or how is it meant to be implemented? Maybe a more detailed "getting started" section in the readme could help or maybe I just need to read more about the fundamentals of this setup in general. :)

Message too long

So I have a lot of tracks/scenes in my set. When I go to get clip_slots from a scene I get this message:

Error: error: (40, 'Message too long') at Ableton.handleIncoming (/Users/justin/My Files/Code/Music/Ableton/ableton-js/index.js:131:45)

any ways you can think of to trim down message size?

Creating Scenes

I've been playing around with this repo - it's really cool!
Is it possible to create scenes with names/bpm attached? I can't seem to figure it out.

When I create a scene, it returns a String, but I cannot access that specific scene or perform any actions on it...like set name or tempo.

Would appreciate any help, thanks!

How do I get the ID of an object?

I have a clip that I would like to place in the Arrangement View.

"Track" has the function "duplicateClipToArrangement", which takes the ClipID as an argument.. But how do I actually get that ID?

How to set track's input sub routing?

I'm fiddling around with ableton-js and got to a point where I would like to edit a tracks's sub routing.

Let's say I want to set it to my audio interface's stereo channel 3&4.

I tried to get the setter to work:

await track.set('current_input_sub_routing', 0)

This raises the error

(node:8883) UnhandledPromiseRejectionWarning: Error: Python argument types in
    None.None(Track, int)
did not match C++ signature:
    None(TTrackPyHandle, TString)

Do you have a hint how the parameter should look like?

listener "playing_status" not working correctly

Hello,
I can't get to add "playing_status" listener, either to clipslot or clip itselft. Am I doing this correctly?

ableton.song.get("scenes").then(async (scenes) => {
  const firsScene = scenes[0];
  const clipSlots = await firsScene.get("clip_slots");
  const firstClipslot = clipSlots[0];
  firstClipslot.addListener("playing_status", (p) => console.log("status", p));
});

Clipslot works with listeners "is_triggered" and "has_clip", but not with "playing_status".

Is there a recommended practice to remove listener from clip or clipslot?

Thank you once again.

get clips

hey so I'm looking for a way to listen to each scene in my set, the number of clips it has, and whether they are recording, stopped, playing, etc.

It doesn't seem like the library has any notion of clips as of yet though, correct?

select Scene

Sorry for such a noob question, but I'm stuck for a while now and can not find an answer.

I am struggling to select a scene. Although I was able to get selected scene by using
let selectedScene = await ableton.song.view.get("selected_scene");
I can't set selected_scene.

I tried these without any success:

  await ableton.song.view.set("selected_scene", 4724534408);
   await ableton.song.view.set("selected_scene", "4724534408");
   await ableton.song.view.set("selected_scene", { nsid: "4724534408" });
   await ableton.song.view.set("selected_scene", { "nsid": "4724534408" });
   await ableton.song.view.set("selected_scene", selectedScene)

the error that I get is UnhandledPromiseRejectionWarning: Error: Python argument types in None.None(View, int)

I also tried using sendCommand without success:

let res = await ableton.sendCommand("song-view", null, "get_prop", {
    prop: "selected_scene",
  });

Any help would be appreciated.
Thank you in advance.

Enabling / disabling devices seems to be broken

To reproduce, place a plugin or any other effect device on the Master track and run

const song = await ableton.song
const master_track = await song.get('master_track')
const devices = await master_track.get('devices')
  
devices.forEach(async function(device) {
  await device.set("is_active", false)
})

This results in

return functionCallback.rej(new Error(data.data));
                                        ^

Error: can't set attribute
    at Ableton.handleUncompressedMessage (/Users/elias/Documents/Code/Scripts/ableton-js/node_modules/ableton-js/index.js:271:41)
    at Ableton.handleIncoming (/Users/elias/Documents/Code/Scripts/ableton-js/node_modules/ableton-js/index.js:250:22)
    at Socket.emit (node:events:513:28)
    at UDP.onMessage [as onmessage] (node:dgram:930:8)

ableton-js/src/ns/device.ts lists 'name' and 'is_active' as settable properties. Setting the name (e.g. on an effect rack) works fine.

Tested on the latest version of ableton-js and Live 11.3.13

Nothing but timeouts

Hi I've installed on OSX. I believe I've followed all the instructions, but whenever I call Ableton.song.get() I receive a timeout.

Here are the logs from Ableton:

0-03-04T13:51:10.619049: info: Python: INFO:_Framework.ControlSurface:619 - LOG: (AbletonJS) Starting on: ('127.0.0.1', 9001), remote addr: ('127.0.0.1', 9000) 2020-03-04T13:51:10.619076: info: RemoteScriptMessage: (AbletonJS) Starting on: ('127.0.0.1', 9001), remote addr: ('127.0.0.1', 9000) 2020-03-04T13:51:10.619238: info: Python: INFO:_Framework.ControlSurface:619 - LOG: (AbletonJS) Socket Event connect(None): null 2020-03-04T13:51:10.619262: info: RemoteScriptMessage: (AbletonJS) Socket Event connect(None): null

I don't see errors but 'connect(None): null seems a little weird. Any idea what is going on?

Send MIDI Signals

Would sending/receiving midi signals be out of scope for this project?

I've played around with it a bit and was able to get them to send from Ableton in a rough way. Wondering if I cleaned it up and created a PR if that would be welcome or not.

Thanks.

add lodash as dependency in package.json

Hi there,

it looks like lodash is not just a dev dependency but a runtime dependency of Ableton.js. When I do

import { Ableton } from 'ableton-js';

async function main() {
  ....
  const ableton = new Ableton();
  await ableton.start()
  ...
}

I get a MODULE_NOT_FOUND error (Error: Cannot find module 'lodash'). After installing lodash, everything works fine.

I think updating the package.json accordingly should fix this for all users of the library.

Best regards,
Samo

Warp Marker Support

Hey! Would love to get warp markers working for a personal project of mine. Has anyone started on implementing that or digging into how to get that to work? Otherwise, I'd be happy to knock it out. Thanks!

clip.removeNotes leads to MPE warning

Thank you so much for your amazing work with this repo. It will open many new possibilities for projects I have in mind.

When I run the following code I get a warning from Ableton:

await clip?.removeNotes(0, 0, 4, 128);
Screen Shot 2023-09-09 at 5 59 53 PM

It's not a big deal, because I can "Proceed" and disable the warning, but just wanted to make you aware.

Ableton Version: 11.3.10
ableton-js version: 3.3.2

Set pitch of clip

I'm trying to set the pitch of a clip.

Currently I've tried this to no avail:

clip_slots.forEach(async (slot) => {
      if (slot.raw.is_playing === true) {
        let clip = await slot.get("clip");
        let name = await clip.get("name");
        let pitch = await clip.set("pitch", 20);
        console.log(track + ': ' + name);
      }
});

Is the current_song_time format in ms?

I just started out with this module so maybe I am missing something, but I noticed this:

I subscribe to 'current_song_time' like this:

const ableton = new Ableton()
ableton.song.addListener('current_song_time', t => console.log('Time:', t))

The Ableton doc is at 120bpm and I step to clock time 3.1.1 which gives me the output Time: 8.

The specs say this:

Live.Song.Song.current_song_time Property
Get/Set access to the songs current playing position in ms.

Shouldn't the output be Time: 4000 for this setup? The value seems somehow fixed to the bar counter, not the implicit time value. When I change the signature and tempo, the output stays the same.

AbletonJS stops working after reinstallation node_modules

I suddenly get this error: Error: The command song.get_prop({"prop":"tracks"}) timed out after 2000 ms. Please make sure that Ableton is running and that you have the latest version of AbletonJS' midi script installed and renamed to "AbletonJS", listening on port 39041 and sending on port 39031.

After using the library for a month without a problem, it seems to have stopped working completely for the past two days. The problem started occuring when I accidentally installed all the packages again. I do obviously have Ableton running with AbletonJS as a control surface. I have been trying to find where exactly I had placed it, with the hopes of replacing it maybe that helps, but I can not find where I placed that remote script in Ableton, not at least where it was mentioned here or in other Ableton-sources.

Add audio channel and add clip from desktop

Hi, this project looks really cool.

I have 5 samples in a folder. Via JS, I want to open an audio channel for each sample in the folder and add those samples to each audio channel in Live.

Is this possible using your library?

I looked at the unofficial documentation for the live API methods here https://structure-void.com/PythonLiveAPI_documentation//Live10.0.2.xml
but couldn't really see anything that indicated I could add channels and load clips into them by using their /path. I saw a lot of event listeners but not actions.

What am I missing?

AbletonJS and React

Hello once again, thank you for such a cool module.
Do you think it would be possible to use ableton-js with React?
I am trying to use your module, but I get this error:

TypeError: dgram_1.default.createSocket is not a function
at node_modules/ableton-js/index.js:101

my minimal code looks like this


import React, { useEffect, useState } from "react";
import "./App.css";
import { Ableton } from "ableton-js";

const ableton = new Ableton();

function App() {
  return <div className="App"></div>;
}

export default App;


should I keep trying or is it impossible to use AbletonJS with React?
Sorry once again for noob question and thank you in advance for your time.

Reconnecting to Ableton fires unexpected events

When I disconnect and reconnect Ableton I get the following events:

  • Disconnect
  • Connect
  • Disconnect (unexpected)
  • Connect (unexpected)

I looked into the JS code further and it seem like it may be a bug in the Python midi-script or further up as this is what I see in the raw messages coming into the handleIncoming.

I am using:

  • Ableton Live 11 Intro
  • Macbook Pro (M1 Chip) - Monterey v12.2.1

Get a list of clips in a track in the arrangement view

Hello,
I am having troubles finding documentation on the arrangement view and how to access and modify clips there.
I would like to write a script that synchronizes the midi data on clips in the timeline with a session view clip in a slot with the same clip name.
Currently I am not sure if anything like that can be done with the python api.

Thanks for the help and best regards
\ chozilla

Can't "fire" a Clip to start playing

Goal: Trigger the first clip of the first track to start playing

Attempt:

    let tracks = await ableton.song.get("tracks")
    let firstTrack = tracks[0]

    let clipSlot = await firstTrack.get("clip_slots")
    let firstClipSlot = clipSlot[0]
    
    await firstClipSlot.sendCommand("fire")

Error:

UnhandledPromiseRejectionWarning: Error: The command clip_slot(10074456552).fire(undefined) timed out after 2000 ms.

From everything I've read, the command name should be "fire" with only optional parameters.
callclipfire.png

Am I missing something? I don't know what else to try...

Listen to master output level

Can your framework check the actual master volume level? But not the fader lever but real-time output level.
I want to create some simple visualization app.

Get clip name

Hey! Firstly, amazing job on the library.

Secondly, I'm trying to get a clip name after having selected it like so:

let clip_slots = await tracks['main'].get("clip_slots")

clip_slots.forEach(async (slot) => {
    if(slot.raw.is_playing === true) {
      let clip = await slot.get("clip"))
      console.log(clip)
    }
});

I can't seem to find a way in the transformers, etc, to get the name of a clip, any advice would be much appreciated.

mixer_device timeout

Hi I'm in the process of writing a grid control app similar to touchable.

when trying to get the mixer device of the master track with this code


  // Establishes a connection with Live
  await ableton.start();

  const masterTrack = await ableton.song.get("master_track");
  const mixerDevice = await masterTrack.get("mixer_device");

I get the following error

Process exited with code 1
Uncaught TimeoutError Error: The command track(live_140638798970484).get_prop({"prop":"mixer_device"}) timed out after 2000 ms. Please make sure that Ableton is running and that you have the latest version of AbletonJS' MIDI script installed and renamed to "AbletonJS".

In the Ableton log I see

2024-01-18T13:03:24.190397: info: Python: WARNING:AbletonJS:190 - UDP tick is lagging, delta: 1387.0ms
2024-01-18T13:05:22.665538: info: Python: INFO:AbletonJS:665 - Setting client port: 52760
2024-01-18T13:05:22.715287: info: Python: INFO:AbletonJS:715 - Error result(34bad700-d17a-4b88-86dd-f56d1dcd03ff): TypeError: ('isinstance() arg 2 must be a class, type, or tuple of classes and types',)

I am running version 3.4.1. I've tried re-copying the midi-script folder using the package.json script.

Get the volume of a track

Hello, I have a small problem and I would be grateful if you could help me. I want to set the volume of tracks. But apparently for some reason I can do that with the library, I wrote track.get("mixer_device") which grants me access to the volume right? but then when I do mixer.get("volume") I get an error saying: mixer.get is not a function, thanks in advance :)

License file

Hello! Just came across this project and think this and AbleSet looks brilliant. Thank you for your hard work!

Would you consider adding a license to this repo so it can be used? I'm interested in playing around with this some locally and maybe using in combo with GoLang and web-assembly or something. Might be able to lend a hand with the repo as well if you'd be receptive to that. Thanks!

React Errors

Hi. I have a problem when building a React application. Whenever I import and use your library I get the errors shown in the screenshot. Installing the necessary pollyfill packages and configuring webpack did not change anything.

screencapture-localhost-3000-2023-08-10-14_11_04

Best regards,
John

Random Unhandled error events

Can't reliably reproduce it. Seems like it can happen on opening a new project but it also happened while working in a project. I have no ableton.on listeners in my script.

AbletonJS: 3.1.4

Node.js: v18.12.0

Ableton Live: 11.2.10

node:events:491
      throw er; // Unhandled 'error' event
      ^

Error [ERR_UNHANDLED_ERROR]: Unhandled error. ('Message could not be assigned to any request: {"event": "result", "data": true, "uuid": "9e2fd0f9-9bec-4c88-a128-f82b093df901"}')
    at new NodeError (node:internal/errors:393:5)
    at Ableton.emit (node:events:502:17)
    at Ableton.handleUncompressedMessage (/Users/user/Documents/Code/Scripts/ableton-js/node_modules/ableton-js/index.js:420:18)
    at Ableton.handleIncoming (/Users/user/Documents/Code/Scripts/ableton-js/node_modules/ableton-js/index.js:376:22)
    at Socket.emit (node:events:513:28)
    at UDP.onMessage [as onmessage] (node:dgram:930:8)
Emitted 'error' event on Ableton instance at:
    at Ableton.handleIncoming (/Users/user/Documents/Code/Scripts/ableton-js/node_modules/ableton-js/index.js:383:18)
    at Socket.emit (node:events:513:28)
    at UDP.onMessage [as onmessage] (node:dgram:930:8) {
  code: 'ERR_UNHANDLED_ERROR',
  context: 'Message could not be assigned to any request: {"event": "result", "data": true, "uuid": "9e2fd0f9-9bec-4c88-a128-f82b093df901"}'
}

Clip.set_notes(...) did not match C++ signature set_notes(...)

Hi, I'm enjoying this library very much.

One issue I've noticed (using Ableton 11) is that using set_notes on a Clip (and possibly other Set commands) will throw this error.

node:39754) UnhandledPromiseRejectionWarning: Error: Python argument types in
    Clip.set_notes(Clip, list)
did not match C++ signature:
    set_notes(TPyHandle<AClip>, boost::python::tuple)
    at Ableton.handleUncompressedMessage (/<path/to/project>/node_modules/ableton-js/index.js:186:41)

My JS code looks like this

    const tracks = await ableton.song.get('tracks')
    const clipSlots = await tracks[0].get('clip_slots')
    const clip = await clipSlots[0].get('clip')
    if(clip) {
      await clip.setNotes([{ pitch: 60, time: 0, duration: 1, velocity: 98, muted: false }])
    }

I've attempted to define a custom setter in Clip.py that converts a List to Tuple, but then it throws a similar type error

UnhandledPromiseRejectionWarning: Error: set_notes() argument after ** must be a mapping, not list

I've exhausted my rudimentary Python knowledge so I thought I'd raise a ticket, thanks! ๐Ÿ˜„

return set_fn(ns, value)

"create_midi_track() argument after ** must be a mapping, not list"

I'm trying to create a new Midi Track using ableton.song.createMidiTrack(1), however, I get the following error:

Error: create_midi_track() argument after ** must be a mapping, not list
    at Ableton.handleUncompressedMessage (D:\Desktop\musicgen-simple\node_modules\ableton-js\index.js:222:41)
    at Ableton.handleIncoming (D:\Desktop\musicgen-simple\node_modules\ableton-js\index.js:202:22)
    at Socket.emit (node:events:513:28)
    at UDP.onMessage (node:dgram:930:8)
[ERROR] 15:10:28 Error: create_midi_track() argument after ** must be a mapping, not list

I'm using Windows and the Live 11 Beta (11.2.10b1)

EDIT: Also occurs when using Live 11 (not Beta)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.