Moving session box while a button is pressed / repeating an action while a condition is met

2.26K viewsCSS Community Scriptssession box
0

Hello everyone,

So I’d like to get a ‘long’ button pressed to continuously move the session box, so that it stops only when I release the button (e.g. when I press down and the box goes down several scenes until I release the button). Right now, I can only get one button press = one move. I tried a bit through both Session box navigation and through reactions (for instance by creating several times the same action) but I did not manage to create this behavior – but to be honest my knowledge at this point is still very limited.
Is there a way to mimic such behavior?  (it’s the original behavior for the APC40 MK2 but could be useful to anyone).

More generally I think the issue is about: “How can we repeat any action (like moving session box down one scene) as long as a condition is met (like button X is still pressed) ?” A bit like a ‘while’ condition in programming.

In the case ‘a button still pressed’ cannot be detected, I guess we could have something like “move the box down” several times with a very short delay between each move (so it’s not instantenous) when the button is pressed, and when the button is released, end this action (a bit like in the shift mode tutorial). But I have no clue how to programm that – I did’nt manage to get a box moving down several times in a row, and not idea how to implement a short delay between actions.

Any help is welcome!

Cheers

neoseed Answered question
0

Maybe something like this would work, it would require 2 Reactions:

Reaction 1:
Add a reaction which changes the value of a modifier to ‘1’ when the button is pressed,
set it to ‘0’ when button is released.
To achieve this you would use the current velocity value of the button in the condition section of the action block.

Condition:  ‘midi controller > current velocity value > button 1’s current velocity value’
‘is equal to’
127 (or whatever velocity value your button sends when pressed)

Action: ‘script > modifiers – set value of a modifier’
modifier: m1
value to set: 1

And then add a second action block in the Reaction which does the same but checks if button velocity is 0, if it is, set the modifier value to 0

Reaction 2:
write a while loop in the Reaction action (in custom code view), which keeps looping while the modifier is set to 1.
Include a timeout/delay to control the speed of the loop.

while self.get_modifier_value("m1"):
    # the session box navigation code - this will move the session box right
    self.set_sessionbox_offsets(self.get_sessbox_track_offset() + 1, self.get_sessbox_scene_offset())
     # Pause for 1 second before continuing the loop
    time.sleep(1)  # You can adjust the time in seconds

The listener for this could be either:
when the button is pressed (midi controller > button 1 was pressed)
Or
when the value of the modifier changes (script > modifiers >m1 modifier was updated)

JohnC Edited comment

One thing to note, this will probably pause execution of everything else while it is looping, so you couldn’t i.e turn a knob at the same time to adjust the volume

0

Hello! Thanks for the help. Unfortunately as soon as I press the button Ableton is crashing (hourglass appear, and then I must end the process as nothing answers). I’m pretty sure though that I followed the right instructions but I may be wrong. I tried several time, though

JohnC Posted new comment

Hmm, maybe it doesn’t like while loops

0

Try doing ‘while modifier is equal to 1’.

while self.get_modifier_value("m1") == 1:
    # the session box navigation code - this will move the session box right
    self.set_sessionbox_offsets(self.get_sessbox_track_offset() + 1, self.get_sessbox_scene_offset())
     # Pause for 1 second before continuing the loop
    time.sleep(1)  # You can adjust the time in seconds

JohnC Answered question
0

Hello everyone !
So, unfortunately both scripts proposed above by JohnC led to Ableton crashing.

With the help of ChatGPT and (way too) many hours of trial and error I finally managed to emulate the behavior of the APC40 Mk2 :  when you press, there is one immediate move of the session box and if you keep pressing, after a slight delay, the box repeatedly moves.

How to do it :
-So the core system is the system proposed by JohnC with two reactions and one modifier by direction. Reaction 1 is as he proposed.
-For Reaction 2 : I had to change the code using the code by John as a basis and asking ChatGPT for help. Here is the custom code for going DOWN : NB : I don’t know how to format in posts code – I think you would need to add tabulation. Anyway this is for reference ideally import the attached json file.

# Check if modifier “m3” is currently held
if self.get_modifier_value(“m3”) == 1:

#  FIRST SCROLL IMMEDIATELY
# This scrolls the session box down by 1 scene right away
self.set_sessionbox_offsets(
self.get_sessbox_track_offset(),
self.get_sessbox_scene_offset() + 1
)

# Define a repeating scroll function
# This function runs every X ms to continue scrolling while the button is held
def scroll_loop_down():
# Only scroll again if “m3” is still held
if self.get_modifier_value(“m3”) == 1:
# Scroll down by 1 scene
self.set_sessionbox_offsets(
self.get_sessbox_track_offset(),
self.get_sessbox_scene_offset() + 1
)
# Re-schedule this function to run again after X ms
self.schedule_message(1, scroll_loop_down)

# START THE FIRST SCROLL LOOP
# This schedules the first repeat scroll to happen – longer delay before 1st scroll
self.schedule_message(6, scroll_loop_down)

Be sure to change the modifiers but also the name of the def for each direction  scroll_loop_up() etc.

Necessity to check for boundaries : Also : for going UP and LEFT, there is the need to check for boundaries with an if condition :
#  FIRST SCROLL IMMEDIATELY (if not already at top)
if self.get_sessbox_scene_offset() > 0:
self.set_sessionbox_offsets(
self.get_sessbox_track_offset(),
self.get_sessbox_scene_offset() – 1
)

It seems these checks are not necessary for going DOWN or RIGHT.

Timing : it seems the numbers we give are theoretically milliseconds (ms). However in practice I did not observe that at all (puting like 50ms would lead to 3-4s delay !). I’m not sure why it’s the case, but I ended up with 6ms for the delay between going into scroll mode and 1ms for the mini delay once it scrolls across tracks or scenes and it seems to work.

Hope this will help others !

PS : Attached is the json script for moving the box in 4 directions on ACP40 mk2.

neoseed Edited answer
0

Hi Neoseed,

Have you tried using Python’s “threading” module?

When you use time.sleep it freezes Ableton during that time. The threading module makes it that this timer happens on a separate loop, so to speak. This way Ableton’s loop is able to keep running while your sleep timer is On.

Glenn V. Answered question