Skip to content

Commit d4ff4b8

Browse files
committed
Improve touchstrip support, other minor fixes
1 parent 03e67dc commit d4ff4b8

File tree

5 files changed

+36
-10
lines changed

5 files changed

+36
-10
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ Utils to interface with [Ableton's Push 2](https://www.ableton.com/en/push/) fro
55
These utils follow Ableton's [Push 2 MIDI and Display Interface Manual](https://github.com/Ableton/push-interface/blob/master/doc/AbletonPush2MIDIDisplayInterface.asc) for comunicating with Push 2. I recommend reading Ableton's manual before using this tool.
66

77
So far I only implemented some utils to **interface with the display** and some utils for **interaction with pads, buttons, encoders and the touchstrip**. More detailed interaction with each of these elements (e.g. changing color palettes, support for led blinking, advanced touchstrip configuration, etc.) has not been implemented. Contributions are welcome :)
8-
*EDIT*: customization of color palettes and led animations is now implemented!
8+
**UPDATE**: customization of color palettes and led animations is now implemented!
99

1010
I only testd the package in **Python 3** and **macOS**. Some things will not work on Python 2 but it should be easy to port. I don't know how it will work on Windows/Linux. ~~It is possible that MIDI port names (see [push2_python/constants.py](https://github.com/ffont/push2-python/blob/master/push2_python/constants.py#L12-L13)) need to be changed to correctly reach Push2 in Windows/Linux~~. **UPDATE**: MIDI port names should now be cross-platform, but I have not tested them on Linux/Windows.
1111

12+
Code examples are shown at the end of this readme file. For an example of a full application that I built using `push2-python` and that allows you to turn your Push2 into a standalone MIDI controller (using a Rapsberry Pi!), check the [Pysha](https://github.com/ffont/pysha) source source code repository.
13+
1214

1315
## Table of Contents
1416

@@ -83,7 +85,7 @@ MIDI configuration calls happen in the same thread because of limitations of the
8385

8486
### Setting action handlers for buttons, encoders, pads and the touchstrip
8587

86-
You can easily set action handlers that will trigger functions when the physical pads, buttons, encoders or the touchtrip are used. You do that by **decorating functions** that will be triggered in response to the physical actions. For example, you can set up an action handler that will be triggered when
88+
You can easily set action handlers that will trigger functions when the physical pads, buttons, encoders or the touchstrip are used. You do that by **decorating functions** that will be triggered in response to the physical actions. For example, you can set up an action handler that will be triggered when
8789
the left-most encoder is rotated in this way:
8890

8991
```python

push2_python/__init__.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class Push2(object):
3737
pads = None
3838
buttons = None
3939
encoders = None
40-
touchtrip = None
40+
touchstrip = None
4141
use_user_midi_port = False
4242
last_active_sensing_received = None
4343
function_call_interval_limit_overwrite = PUSH2_RECONNECT_INTERVAL
@@ -64,7 +64,7 @@ def __init__(self, use_user_midi_port=False):
6464
self.pads = Push2Pads(self)
6565
self.buttons = Push2Buttons(self)
6666
self.encoders = Push2Encoders(self)
67-
self.touchtrip = Push2TouchStrip(self)
67+
self.touchstrip = Push2TouchStrip(self)
6868

6969
# Initialize MIDI IN connection with push
7070
self.configure_midi(skip_midi_out=True)
@@ -219,7 +219,7 @@ def on_midi_message(self, message):
219219
# are not interested in (probably some internal state which Ableton uses but we don't care about?)
220220

221221
# Send received message to each "part" so it is processes accordingly
222-
for func in [self.pads.on_midi_message, self.buttons.on_midi_message, self.encoders.on_midi_message, self.touchtrip.on_midi_message]:
222+
for func in [self.pads.on_midi_message, self.buttons.on_midi_message, self.encoders.on_midi_message, self.touchstrip.on_midi_message]:
223223
action_taken = func(message)
224224
if action_taken:
225225
break # Early return from for loop to avoid running unnecessary checks
@@ -447,7 +447,13 @@ def function(push):
447447

448448

449449
def on_touchstrip():
450-
"""Shortcut for registering handlers for ACTION_TOUCHSTRIP_TOUCHED events.
450+
"""Shortcut for registering handlers for ACTION_TOUCHSTRIP_TOUCHED events. Push2's
451+
touchstrip can be configured to work eithher as a pitch bend "wheel" (the default)
452+
or as a modualtion "wheel". When configured as pitch bend, the touchstrip values received
453+
in this method (see below) will correspond to pitch bend values [-8192, 8128]. If configured as
454+
modulation wheel, this function will receive the value of the modulation [0, 127]. Both
455+
modes can be configured by calling "set_modulation_wheel_mode" or "set_pitch_bend_mode" methods
456+
in Push2.touchstrip.
451457
Functions decorated with this decorator will be called with the following positional
452458
arguments:
453459
* Push2 object instance

push2_python/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def is_push_midi_out_port_name(port_name, use_user_port=False):
6464
MIDO_NOTEOFF = 'note_off'
6565
MIDO_POLYAT = 'polytouch'
6666
MIDO_AFTERTOUCH = 'aftertouch'
67-
MIDI_PITCWHEEL = 'pitchwheel'
67+
MIDO_PITCWHEEL = 'pitchwheel'
6868
MIDO_CONTROLCHANGE = 'control_change'
6969

7070
PUSH2_SYSEX_PREFACE_BYTES = [0xF0, 0x00, 0x21, 0x1D, 0x01, 0x01]

push2_python/touchstrip.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import mido
22
import weakref
3-
from .constants import MIDI_PITCWHEEL, ACTION_TOUCHSTRIP_TOUCHED
3+
from .constants import MIDO_PITCWHEEL, MIDO_CONTROLCHANGE, ACTION_TOUCHSTRIP_TOUCHED, PUSH2_SYSEX_PREFACE_BYTES, PUSH2_SYSEX_END_BYTES
44
from .classes import AbstractPush2Section
55

66

@@ -9,8 +9,26 @@ class Push2TouchStrip(AbstractPush2Section):
99
See https://github.com/Ableton/push-interface/blob/master/doc/AbletonPush2MIDIDisplayInterface.asc#Touch%20Strip
1010
"""
1111

12+
def set_modulation_wheel_mode(self):
13+
"""Configure touchstrip to act as a modulation wheel
14+
See https://github.com/Ableton/push-interface/blob/master/doc/AbletonPush2MIDIDisplayInterface.asc#2101-touch-strip-configuration
15+
"""
16+
msg = mido.Message.from_bytes(PUSH2_SYSEX_PREFACE_BYTES + [0x17, 0x0C] + PUSH2_SYSEX_END_BYTES)
17+
self.push.send_midi_to_push(msg)
18+
19+
def set_pitch_bend_mode(self):
20+
"""Configure touchstrip to act as a pitch bend wheel (this is the default)
21+
See https://github.com/Ableton/push-interface/blob/master/doc/AbletonPush2MIDIDisplayInterface.asc#2101-touch-strip-configuration
22+
"""
23+
msg = mido.Message.from_bytes(PUSH2_SYSEX_PREFACE_BYTES + [0x17, 0x68] + PUSH2_SYSEX_END_BYTES)
24+
self.push.send_midi_to_push(msg)
25+
1226
def on_midi_message(self, message):
13-
if message.type == MIDI_PITCWHEEL:
27+
if message.type == MIDO_PITCWHEEL:
1428
value = message.pitch
1529
self.push.trigger_action(ACTION_TOUCHSTRIP_TOUCHED, value)
1630
return True
31+
elif message.type == MIDO_CONTROLCHANGE:
32+
value = message.value
33+
self.push.trigger_action(ACTION_TOUCHSTRIP_TOUCHED, value)
34+
return True

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from setuptools import setup, find_packages
22

33
setup(name='push2-python',
4-
version='0.3',
4+
version='0.4',
55
description='Utils to interface with Ableton\'s Push 2 from Python',
66
url='https://github.com/ffont/push2-python',
77
author='Frederic Font',

0 commit comments

Comments
 (0)