Triggering MIDI notes with a midi controller via Ableset interface with visual feedback

Almost certain this may have been spoken about before but with a quick search I couldn’t find a thread.

Above is a screenshot of midi notes that I have on my timeline that I have set up to control a Waves Tune plugin scale root, on/off & scale type within Logic on a completely separate Mac on the same network.

What I want to work out, is a way that rather than only being able to control it from the timeline, to fire a midi note within Ableset by pressing a pad OR potentially using a rotary knob to select a specific midi note and then have another pad to fire it (second option would total less buttons used on the midi controller)

With the power of canvas view - I then wonder if it’s possible to get some sort of visual feedback on all the above?

This is getting more complex pretty quick - but the way I imagine it is that the box with each of the notes you can see and their respective labels on the canvas view is outlined to show you have it ‘cued’ to fire and then when you fire the note the box fills in with colour to basically show that’s what’s currently active. Double bonus if it also reacts to what is on the timeline as well.

Anyway, I really appreciate all you do here and the fast responses to very specific individual questions, it’s above and beyond! Looking forward to hearing back on whatever creative solution there may be (if any)

Thank you!!

Hey Simon!

You can definitely trigger those MIDI notes from a Canvas button and have the Canvas reflect what’s happening on the timeline.
Your setup would look like this:


1. Canvas Button (fires the note + updates the visual state)

In your Canvas, add a Button and set Script On Press to:

if (shared("waves_note_60")) {
  // was already active → turn it off
  setShared("waves_note_60", false);
} else {
  // activate it
  setShared("waves_note_60", true);

  // send the MIDI note to your Waves/Logic Mac
  const output   = "YOUR MIDI DEVICE"; // exact name of the MIDI port that goes to Logic/Waves
  const channel  = 1;
  const note     = 60;      // or "C4"
  const velocity = 100;
  const duration = 120;     // ms

  sendOsc("/midi/send/note", output, channel, note, velocity, duration);
}

2. Visual feedback in the Canvas

For the element that represents this note, set Background Color to:

${ shared("waves_note_60") ? "yellow-300" : "yellow-900" }

This highlights the box whenever that note is active.


3. Making it react to the timeline using a +OSC track

On your Waves +OSC track, you can mirror the same behavior from Live’s timeline.

To fire the note from the timeline and update the Canvas:

/midi/send/note "YOUR MIDI DEVICE" 1 60 100 120; /shared/waves_note_60 true

And to turn it off from the timeline:

/shared/waves_note_60 false

Your OSC track would look like this:


Let me know if this works for you, I’m looking forward to your reply!

Adding to this, since you likely only need one note to be active at a time, you could use the same shared variable for each note.

I’ve built a small example here that you can try out: Autotune Note.json (9.7 KB)

This canvas lets you select the root note, scale, and state, and activate it by tapping “Send Scale”. I wasn’t sure which notes you were sending to the other computer, so I took a guess:

  • Root note: C0 – B0
  • Major: C1
  • Bebop: C#1
  • Off: D1
  • On: D#1

You can change those values in the buttons’ properties.

Since these buttons use shared variables, you can also change them from a connected MIDI controller using AbleSet’s MIDI mapping features.

To get feedback from the clips in your Live project, you could route the MIDI that goes to the other Mac into a loopback so it can be mapped to AbleSet again.

Alternatively, you could split your MIDI track into three tracks – one per “category” of commands. Then rename the clips to the note they send and name your track like this: AUTO TUNE NOTE +OSC [/shared/autotuneNote], AUTO TUNE SCALE +OSC [/shared/autotuneScale], AUTO TUNE ACTIVE +OSC [/shared/autotuneActive].

Let me know if this suits your use case and if you have any further questions :slight_smile:

Thank you for the responses!
Will let you know when I’ve tried this out. It does look like what I’m after!

This is great, I am not the best on scripting and I am hoping you can help clarify.

We run autotune on a Waves Server, the issue we have is being able to monitor/ get feedback from the Waves Server - Did the Tune Key actually change.

Is the instructions above able to do that or would there be an additional step?

Thank you for your help

Hey @Psnick,

The setup above gets you close, but not quite what you’re describing.

Right now the shared variable gets written from two places: the Canvas button, and the +OSC track on Live’s timeline. So the Canvas does reflect the timeline, not just your button presses. But notice what the +OSC clip actually does: it sends the MIDI note and sets the shared variable in the same clip. Those are two parallel actions, not cause and effect. The variable updates because the playhead reached the clip, not because the Waves Server confirmed anything.

So there are three separate states here:

  • The button was pressed — AbleSet knows
  • The timeline fired the note — AbleSet knows
  • The Waves Server actually changed the Tune Key — AbleSet has no idea

The loop closes inside AbleSet. For what you’re after, you need the Waves side to send something back.

Option 1 — MIDI back into AbleSet

Route MIDI from the Waves machine into the computer running AbleSet, then go to Settings → MIDI Mapping, OSC & Scripting → Edit MIDI Mapping. Either add a mapping for the specific note/CC and set the action to Custom Script, or click the ⋯ next to “Add New Mapping” and select Script to react to any incoming MIDI on that port.

The script has access to the midi object, so you can write the shared variable from what actually came back:

// runs when AbleSet receives MIDI from the Waves machine
if (midi.type === "note-on") {
  setShared("autotuneConfirmed", midi.note);
}

Option 2 — OSC back into AbleSet

If the Waves side can send OSC, it’s even simpler, no script needed. Send it straight to AbleSet’s OSC port (39051) and write the variable directly:

/shared/autotuneConfirmed 60

Keep the variable you already have for what was sent, and add this second one for what came back. Then colour the box only when both agree:

${ shared("waves_note_60") && shared("autotuneConfirmed") === 60 ? "green-500" : shared("waves_note_60") ? "yellow-600" : "green-950" }

Green means confirmed, yellow means sent but not confirmed, dark means off. That’s a genuine monitor rather than an indicator.

You can see this pattern in the official tutorial — MIDI feedback from an Apollo autotune plugin going into a shared variable: https://youtu.be/UQJqJ7Mvrk8?t=206

The part I can’t answer from here is whether your Waves rig can emit anything outbound. If the Tune instance is hosted in a DAW on that machine, the DAW can usually send MIDI or OSC back. If it’s SuperRack or MultiRack standalone, it depends on what that host exposes.

I’m looking forward to your reply!