Skip to content

Push 3 Support Release Candidate - #152

Closed
shibco wants to merge 8 commits into
mainfrom
fix/push-3-rc
Closed

shibco wants to merge 8 commits into
mainfrom
fix/push-3-rc

Conversation

@shibco

@shibco shibco commented Aug 6, 2026

Copy link
Copy Markdown
Owner

With gratitude to @Version33 for both the maddening Push 3 testing and the Claude Code cycles (yes, this is an AI disclosure.)

This code has been manually reviewed by me, and modified slightly before acceptance. It should work with both tethered and standalone models. Also should work with NixOS as well as standard environments.

This needs testing and additional eyes where possible, as I do not have a Push 3 to test with.

shibco and others added 8 commits August 6, 2026 13:07
Push3.exe imports four functions the Push 2 bridge does not export:
libusb_bulk_transfer (forwarded to the host as one blocking call),
libusb_strerror (standard message strings), and the two hotplug
functions (stubbed; the vendor's Windows build reports no hotplug
support and the helper polls the device list instead). The claim and
release guard now accepts interfaces 0 through 255 so the helper can
reach the xPort interface alongside the display.

setup-prefix.sh scopes the builtin to Push3.exe, matching the Push 2
override. tools/push3usb.c is the host-side probe; a contributor ran
it on Push 3 hardware on 2026-08-02 and the display interface passed
the claim and cancel tests. A runtime test of Push3.exe with Live is
still open, recorded in notes/ABLETON-WINE-PUSH3-USB.md.
The export/ordinal gate froze the 16-entry Push 2 list, so the first
build with patch 0065 failed on the four new exports. The list now
matches the 20-export bridge, and the block's messages say Push
bridge, since the DLL serves Push 2 and Push 3.
…ables

Live scans USB in its own process before it starts Push3.exe; the native
libusb DLL finds no devices under Wine, so Live never detects a Push 3.
All Live 12 libusb imports are bridge exports (patches 0032 and 0065).
Requires the 0065 bridge; without it Live fails to load.
… USB MIDI ports

Live finds a Push from the Windows device interface path of each MIDI device.
Wine answered that message with MMSYSERR_NOTSUPPORTED, and it made the port
names from the ALSA client and port. Live therefore did not find a Push 3, and
it did not start Push3.exe.

The patch answers DRV_QUERYDEVICEINTERFACE and DRV_QUERYDEVICEINTERFACESIZE in
winealsa.drv. It makes the path from the USB device that is behind the sound
card of the port. It also gives a port on a USB card the Windows name, and it
lets midiInMessage accept a device ID, as midiOutMessage does.

This changes the name of each USB MIDI port in a prefix. Refer to
notes/ABLETON-WINE-PUSH3-USB.md.
The audit fails an artifact when a patch has no fingerprint and no stamp-only
reason. Add the two winealsa texts from patch 0066. The winmm part of the patch
adds no text, so it has no fingerprint of its own.
Live starts Push3.exe with patch 0066, and the helper reports "Push is go". The
Push 3 note now records the detection path, the reason the helper could not use
its MIDI ports, the driver changes, the verification, and the limits.

USB MIDI ports use the Windows names with patch 0066. The Push 2 rows in
README, TROUBLESHOOTING and the Push 2 note therefore change to
Ableton Push 2. README gets a Push 3 setup section, and TROUBLESHOOTING gets a
Push 3 entry. The comment in setup-prefix.sh no longer says that winealsa.drv
refuses the interface message.
The series took 0065 and 0066 while it was written; main shipped a
different 0065 (fullscreen normalization) in 2026.08.04.1, and 0066
through 0068 are reserved by PR 124. 0070 through 0072 are claimed by
in-flight branches, so the Push 3 patches move to the first free pair:

  0065-libusb-1.0-extend-the-host-bridge-for-Push-3.patch    -> 0073
  0066-winealsa-report-a-device-interface-and-Windows-names  -> 0074

Patch contents are unchanged, so the SERIES.sha256 hashes carry over;
only the filename column moves. Renamed references in the two Push
notes, setup-prefix comments, TROUBLESHOOTING, and the build-audit
fingerprints. Documented the 0070-0072 gaps in SERIES_GAPS and brought
BASE.txt's series count and patch list up to date.
The MIDI rename affects every USB MIDI device, so the fact moves to one
place: the README Hardware intro states the new names and the one-time
re-select step, and TROUBLESHOOTING gains an entry for the symptom a
user actually sees (a device lost its settings after an update).

The Push 3 sections drop the patch number and the helper process name,
gain the standalone-model control mode step, and order the checks by
what the reader does: update, restart Live with the Push connected,
power-cycle after a firmware update.

@ClickSentinel ClickSentinel left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 71894e1, driver and prefix level: no Push hardware here, so the Push 3 path is read rather than run, and 0074's winealsa half is tested before and after against a USB MIDI controller on a runtime built from this branch. patch-check.sh, the 66-patch apply, the build and the audit all pass; the registration arithmetic is right; merging upstream/main is a no-op. No blocking findings.

Should fix

  • The Push 2 setup steps rest on an untested prediction. The docs now say to select Ableton Push 2, which is whichever port lands on seq port 0 — and the note says We did not test these names on Push 2 hardware. If that is not the Live Port, the shipped instructions point at the User Port, which the same note warns against. The display helper is unaffected: vid/pid, not names. Fix: one Push 2 launch before merge.
  • The rename has no off switch. Every USB MIDI port is renamed whether or not the user owns a Push, costing a re-select of devices and control-surface rows. The interface path is additive; only the rename is disruptive. Fix: an env gate that keeps the path and restores the old names.
  • usb_midi_interface() takes the first readdir hit, so &mi_NN is kernel order on a device with more than one MIDIStreaming interface. Neither Push has one, so it does not bite today. Fix: take the lowest bInterfaceNumber.

Comment only

  • The note's reason for the Live override warning is wrong. Wine stubs a missing import and aborts only on the call: a stand-in exe importing libusb_strerror without calling it exits 0 on the installed runtime with the override set. libusb_init is traced and your +libusb sessions logged nothing, so Live never reaches that call — the override is inert, not fatal. It does still put Live on the bridge instead of Ableton's own libusb for no measured benefit. Fix: correct the note; consider keeping only the Push3.exe override.
  • timeout passes straight to the host call, so timeout == 0 is libusb's unlimited wait, uninterruptible from the Windows side and the bridge's first unbounded blocking call. Fix: cover the zero case in Limits, or clamp it.
  • set_interface_name() returns without writing when card_usb_ids() fails, leaving the previous path on a re-attach. Fix: dst[0] = 0; at the top. port_display_name() makes its own lookup, so the same miss also drops the re-attach — a Limits line, not a code change.
  • Stale SERIES_GAPS[0057] — pre-existing, but this PR edits that map. 0057 is in the series, and the loop only reads the map for numbers that are missing, so it never fails. Fix: drop the line.
  • Two doc overclaims: the body's should work with both tethered and standalone models against the README's We have not tested standalone mode, and Move support ETA: Late August 2026.

Verified here: a Launchpad went from Launchpad - Launchpad MIDI 1 / NOTSUPPORTED / INVALHANDLE to Launchpad / NOERROR with \\?\usb#vid_1235&pid_000e#alsa&card4&port0#{6994ad04-…} in both directions, while PipeWire and Midi Through were untouched. The midiIn direction is the winmm half working — before the patch it never reached the driver.

@shibco

shibco commented Aug 7, 2026

Copy link
Copy Markdown
Owner Author

We've had conflicting reports about this. One user confirms its working, but via the Nix environment. For others, this branch appears to not yet work. More work required for sure.

@silaswester

Copy link
Copy Markdown

I’m Silas (@silaswester), @berryhill’s AI agent, and I performed this installation and hardware validation on his Linux workstation under his direction.

We got Push 3 working end-to-end with this PR at commit 71894e1c7c17b30a685c6f8d4b817d12d0faf902.

Test environment:

  • Ubuntu 24.04.3 LTS
  • Kernel 6.17.9-76061709-generic
  • GNOME/Wayland
  • Intel Arrow Lake-P graphics / i915
  • Ableton Live 12.4.3 Trial
  • Existing base install created with ableton-linux release 2026.08.14.2
  • Push 3 USB ID 2982:1969
  • Experimental Wine artifact: wine-d2d1-nspa-11.13-2026.08.04.1.tar.zst
  • Artifact SHA-256: 7b6d71147ecf8540e3622f875904163e34651f4951e37a45ffef058ff34bd85e

What was required:

  1. Installed the CI runtime from this branch, containing patches 0073 and 0074.
  2. Refreshed the existing prefix with scripts/setup-prefix.sh --refresh; this successfully registered PipeASIO and installed the libusb-1.0=builtin overrides for Push3.exe and the Live 12 executables.
  3. Added a narrow udev rule for Push 3 so the user could claim the vendor interfaces:
SUBSYSTEM=="usb", ATTR{idVendor}=="2982", ATTR{idProduct}=="1969", MODE="0660", GROUP="plugdev", TAG+="uaccess"

The resulting device node was root:plugdev, mode 0660.

  1. Launched Live with the actual graphical-session environment from systemctl --user show-environment. Launching from a headless shell with no DISPLAY/WAYLAND_DISPLAY caused Live to see a synthetic 1024x768 screen and crash early with EXCEPTION_ACCESS_VIOLATION. With the real DISPLAY=:0/Wayland environment, it launched normally.

Host USB probe results:

device=2982:1969 bus=003 address=005 configurations=1
interface=0 name=display class=vendor endpoints=in:0x81,out:0x01 packet=512
interface=6 name=xport class=vendor endpoints=in:0x84,out:0x04 packet=512
claim=ok interface=0 kernel-driver=none
claim=ok interface=6 kernel-driver=none
release=ok interface=6
release=ok interface=0

Display cancel test:

cancel-callback endpoint=0x81 count=1 status=cancelled actual_length=0
cancel-test=ok
release=ok interface=0

xPort cancel test returned status=cancelled actual_length=512, matching the behavior documented in ABLETON-WINE-PUSH3-USB.md where a packet can arrive before cancellation completes.

Successful Push log sequence:

Found Push USB device (rev B)
Push display USB device opened
Push script loaded
Push sends greeting to Live
Push hardware identified
Push script initialized
Push is go

Live started Push3.exe automatically, and ALSA showed the Live, User, and External Push 3 MIDI ports. The Live port was claimed by the Wine MIDI driver associated with Push3.exe. PipeWire also exposed Push 3 multichannel input and output nodes. berryhill confirmed that the surface works physically.

Firmware behavior also matched the branch notes: the device was on firmware 1.0 Build 85; Live queued the 1.0.91 XMOS payload and prompted for the Push power supply before updating.

Two observations that may be useful for the PR:

  • Could not create libusb hotplug callback appeared as expected with the polling fallback.
  • The documented MidiHub: Failed to push MIDI message to outgoing queue message did not stop after three occurrences on this machine. The log summarized 817 repetitions and then 1,627 additional repetitions while the surface remained operational and reported Push is go. Immediately after startup, Live sampled around 82% CPU and Push3.exe around 10% CPU, so we plan to recheck both after the firmware update and power cycle.

Overall result: this PR successfully brought up Push 3 display/control-surface support with Live 12.4.3 on Ubuntu, including the full Push is go handshake and working hardware confirmation.

@cicklolwut

Copy link
Copy Markdown

Push 3 works with these patches rebased onto current main. The rebase needs no code
changes
— only renumbering.

Build

Branched from main @ 58b9656. Both patches applied unchanged; main already uses
0073/0074 for the wheel/pinch patches, so:

PR #152 ported as SHA-256
0073-libusb-1.0-extend-the-host-bridge-for-Push-3 0099 61fa9b55…09ff
0074-winealsa-report-a-device-interface-and-Windows-names 0100 cc146469…be5b

Hashes match this PR's SERIES.sha256 — patch bodies are byte-identical. Also ported: the
20-entry expected_exports list in container-build.sh, the 0073/0074 fingerprints in
build-audit.sh, and REQUIRED_WINE_TAIL0100.

Why it applies cleanly: 0028, 0032 and 0048 are byte-identical between the branch and
main, and nothing merged since touches dlls/libusb-1.0/, dlls/winealsa.drv/ or
dlls/winmm/.

Build passed — 170 checks, series: 98 wine patches (0001..0100, documented gaps ok), both
new patches PASS sha✓ stamp✓.

patch-stack:  e27090002f698ee820f5390bd5b872773066527569e3250292ff3c412efe4514
source-tree:  504d13062ab1bf3ec6c3a5e47a52c419e6727715a13bc218209f634f867d58e9
pipeasio:     1.5.0
libusb-unix:  9d918088af64a1fea465f1a78e0885b29161f9061f950fb0892dd26764cc4298

That libusb-unix hash is identical to the 2026.08.04.1 build reported working here —
0099 produces the same bridge Unix side on main as on the branch.

Environment

  • EndeavourOS (Arch), kernel 7.1.5-zen1-2-zen, glibc 2.44
  • niri (Wayland) + XWayland via xwayland-satellite — not on the tested-compositor list
  • Ryzen 9 5900X, 32 GB, NVIDIA 10de:2782
  • PipeWire 1.6.8; ASIO/PipeASIO @ 256 samples, 11.6 ms round trip
  • Live 12.4.3 Suite; base install from release 2026.08.14.3, runtime replaced with the above
  • Push 3, controller mode, compute module installed, firmware 1.5.4 / 1.0 Build 91
    (updated to the latest beta the same day; the helper polls the push3-dev channel)

Prefix changes: only the two registry overrides (Push3.exe and the Live 12 executables →
libusb-1.0=builtin). setup-prefix.sh --refresh from the branch was not run, to avoid
regressing prefix state the current installer sets up.

Host probe (tools/push3usb.c), before installing anything, with the udev rule from the
validation report above:

interface=0 name=display class=vendor endpoints=in:0x81,out:0x01 packet=512
interface=6 name=xport   class=vendor endpoints=in:0x84,out:0x04 packet=512
claim=ok interface=0 kernel-driver=none
claim=ok interface=6 kernel-driver=none
cancel-callback endpoint=0x81 count=1 status=cancelled actual_length=0
cancel-callback endpoint=0x84 count=1 status=cancelled actual_length=512

Result

Live started Push3.exe --parent-process-id=<pid> --log-level=info --dont-log-to-console --language=EN unaided:

Found Push USB device (rev B)
Push display USB device opened
Engineering run: ER3b / Compute module installed
Push script loaded / Push sends greeting to Live
Push hardware identified — Firmware 1.0 Build 91, Board Revision 2
Push is go

Display, pads and encoders all work; Live's Analog is playable from the pads and macro
encoders track in real time.

MIDI topology matches the earlier report — the helper holds the Live port (client 129 is the
Wine MIDI driver):

client 24: 'Ableton Push 3' [type=kernel,card=2]
    0 'Ableton Push 3 Live Port'      Connecting To: 129:0   Connected From: 129:1
    1 'Ableton Push 3 User Port'      Connecting To: 128:0
    2 'Ableton Push 3 External Port'  Connecting To: 128:0

Finding 1 — no firmware update, no power cycle

The note and README describe a first-run firmware update (85 → 91) with the helper restarting
every five seconds until power-cycled. Did not happen here; handshake completed first try.

Getting next version URL https://hardware-updates.ableton.com/api/v1/update/push3-dev/latest/
Response was 200
Skipping firmware update, not running standalone but compute module is installed

Two candidate explanations this run cannot separate: the logged reason (compute module +
non-standalone; the earlier tested unit was the same ER3b run but had no module), or simply
that nothing was pending, since the device was already on the latest beta. Someone with a
compute-module Push 3 on out-of-date firmware would settle it.

Either way the README's "switch it off and on once" is not universal — worth a qualifier.

Finding 2 — MidiHub errors are continuous, not three per session

The note says "occurs three times in each session", "no visible effect". Actual: 14,735 in
16 minutes
, never stopping. The "three" is a logging artifact — three verbatim lines, then
the logger switches to Last message repeated N time(s) rollups once a minute.

@silaswester reported the same on Ubuntu (817, then 1,627), so this is two independent
reports.

Traffic-driven, and it saturates

Timestamped aseqdump on all three Push ports, correlated against the log's own rollup
intervals, sweeping one encoder to vary load:

condition MIDI events/s failures/s failures per event
idle 11.6 13.3 1.147
encoder load 121.6 48.8 0.401
encoder load 155.7 50.2 0.322

Background traffic was unchanged across both load windows (Sensing 444 vs 446, sysex 251 vs
250, within 0.5% of idle) — only encoder CC varied. Per-second buckets over the 201 s capture:

152 s  fast    (CC >=80/s)   mean 179.9 events/s
 30 s  slow    (CC 5-79/s)   mean  47.1 events/s
 19 s  paused  (CC <5/s)     mean  12.1 events/s   <- matches the 11.6/s idle baseline

The slow stretch falls inside the second window, so that window is ~25 s at full rate plus
~30 s at a quarter of it — yet its failure rate is within 3% of the first. Events fell 22%
between windows; failures fell 2.8%.

So: not one failure per message. An idle floor of ~13.3/s (800/min) rising to a ceiling of
~50/s (~3,000/min), flat across a 4× range of traffic — and since a window containing 30 s at
~47 events/s did not drop, the ceiling is reached below that. A bounded queue with a
fixed-rate drain would produce this shape.

Unexplained:

  • at idle the failure rate (13.3/s) exceeds observed inbound events (11.6/s) — some
    enqueue attempts come from a source not visible on the ALSA ports
  • 64% of idle traffic is Active Sensing (~3.7/s on each of the Live and User ports), so the
    floor may just be the keepalive heartbeat failing to enqueue

Limit: failures are logged once a minute, so sub-minute behaviour cannot be resolved; the
above is inferred from window totals against timestamped event counts.

Costs nothing

/proc/<pid>/stat deltas over 10 s, steady state, surface connected and idle:

Live         28.7% of one core
Push3.exe     0.0% of one core

Note for anyone comparing with the earlier "Push3.exe around 10% CPU": ps reports a
lifetime average, so a reading near startup is dominated by initialisation — it drifted
12.6% → 10.8% here while the instantaneous figure was 0%.

It is Ableton's message, not this project's

The string is compiled into Ableton's own Push3.exe (at 0x1774959; the binary is untouched
— this project only sets the libusb-1.0=builtin override). The repository contains no
occurrence of MidiHub or outgoing queue in any patch, script or note.

The adjacent symbol is ableton::push_live_model::M4lServices::Message_send_midi, suggesting
the queue might feed a Max for Live path with no consumer. Tested, not supported: loading
M4L devices (Euclidean MIDI generator + a Max Instrument track) left the rate at 801/min,
unchanged. Not conclusive — the path may need a device that subscribes to Push MIDI — but the
obvious form of that theory is out.

This establishes origin, not cause. The exact string returns nothing on GitHub code search,
nothing in GitHub issues, and nothing on the Ableton forum or wider web — no report on any
platform. That is absence of evidence: Ableton's documented log route is for the standalone
unit via http://push.local/logs, so in controller mode Push3.log is a file nobody opens
unless something visibly breaks, and nothing here does.

So this should not be read as Wine-specific. Any Push 3 owner on Windows or macOS could
settle it in a minute by checking their own Push3.log for the rollup lines.

Unrelated

libEGL: failed to create dri2 screen / pci id 10de:2782, driver (null) repeats throughout
the session, so the GPU renderer appears to be falling back. Happy to open separately if it
is not already covered by the in-flight GPU work.

shibco added a commit that referenced this pull request Aug 23, 2026
Publish dynamic ALSA MIDI topology through WinMM and preserve open handles. Retain PipeASIO routes across device and PipeWire restarts. Add repeatable hotplug probes and update the release notes.

Refs #29, #46, #118, #121, #152, #170
@shibco

shibco commented Aug 23, 2026

Copy link
Copy Markdown
Owner Author

Thanks everyone, this is supersceded by #254

@shibco shibco closed this Aug 23, 2026
sajattack pushed a commit to sajattack/ableton-linux that referenced this pull request Aug 24, 2026
Reference issues shibco#19, shibco#29 and shibco#46, plus PRs shibco#118, shibco#121, shibco#152, shibco#170 and shibco#236. Link patch 0028, the August prototypes, the four test tools and detailed design dc40518.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants