Skip to content

/live/clip/remove/notes without arguments does not delete MIDI note 127 (G9) #190

@paulmacmillan

Description

@paulmacmillan

Hi Daniel,

I found something on the clip api.

Description

The OSC command /live/clip/remove/notes without additional arguments does not remove MIDI note 127 (G9) from clips. This note remains in the clip even after the command is sent, which causes duplicates or "ghost notes" when synchronizing an external sequencer
with Ableton Live via OSC.

How to Reproduce

  1. Create a MIDI clip in Ableton Live with a note at pitch 127 (G9).
  2. Send the OSC command /live/clip/remove/notes with arguments [track_index, clip_index] (no additional arguments).
  3. Observe that note 127 is not deleted from the clip.
  4. Compare this with sending /live/clip/remove/notes with arguments [track_index, clip_index, 0, 128, -8192, 16384]; note 127 is deleted.

Expected Behaviour

When calling /live/clip/remove/notes without additional arguments, all notes in the clip should be removed (pitches 0–127). The current implementation only removes notes 0–126 because pitch_span = 127 defines a half-open interval [0, 127).


Voici l'issue formatée pour GitHub:

Root Cause

In abletonosc/clip.py, line 161:

elif len(params) == 0:
    pitch_start, pitch_span, time_start, time_span = 0, 127, -8192, 16384

The pitch_span = 127 covers pitches [0, 127), which excludes pitch 127. To cover the full MIDI range (0-127 inclusive), pitch_span should be 128.

Suggested Fix

Change line 161 to:

pitch_start, pitch_span, time_start, time_span = 0, 128, -8192, 16384

System Information

  • OS: macOS
  • OS Version: Sequoia
  • Live Version: Live 11.3.43 Suite
  • AbletonOSC Version: (from main branch ? not sure about this one, the only thing I'm certain about is that I set up my new macbook 4 weeks ago and downloaded the lib from github at this time)

Additional Context

This bug was discovered while developing an external sequencer (eLute) that syncs with Ableton Live via OSC. The sequencer sends remove/notes before add/notes to update clip contents, but notes at pitch 127 were persisting unexpectedly.

Workaround in user code: explicitly pass all 4 parameters with pitch_span = 128:

args: [
    { type: "i", value: trackIndex },
    { type: "i", value: clipSlotIndex },
    { type: "i", value: 0 },      // pitch_start
    { type: "i", value: 128 },    // pitch_span (covers 0-127 inclusive)
    { type: "f", value: -8192 },  // time_start
    { type: "f", value: 16384 }   // time_span
]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions