Hi community,
there is a card in Trello called „Live Loop Control“. It describes a possible future method to dynamically control loop ranges.
For me it would be most welcome as it offers the possibility to react to an audience dynamically (repeat a chorus…) for songs needing some background sequencing or percussion by design (dancefloor, etc.).
Of course I also noticed that @brad wants to lay hands on the play range section but not in small pieces which probably won´t fit to each other, instead as whole package which I totally understand and support.
So I tried to find a method to realise this functionality only using cantabile onboard tools and hopefully was successful. I would like to introduce it to whom it may interest. The method is a bit cumbersome and uses some „dirty hacks“ and is only meant for the time till the Trello card is realised.
It is based on some ideas on looped play ranges @dave_dore introduced some time ago. My method should be able to satisfy the following needs:
- Define any number of looped play ranges inside a song
- Possibility to „arm“ a loop dynamically by a free selectable specific Midi-event
- Possibility to „disarm“ armed loops dynamically by a free selectable specific Midi-event
- Mechanism to automatically disarm a loop after it has looped once (but of course with the possibility to re-arm it as often as needed)
- Mechanism prohibiting arming of loops depending on song position (strongly necessary to prohibit arming of loop ranges lying in the past).
To achieve this first task is to create play ranges. As rule of thump I stick to:
- Create a play range for each loop you want to establish, set loop to On (Infinite)
- For each loop define a second play range where start position equals start position of loop and end position equals end position of whole play range, set loop to off
- Create one no loop play range where start and stop positions equal begin and end of the whole play range
The following screenshots show the play ranges of an example using 2 loops.
For realisation 3 functions were necessary:
- Conditioned bindings from Midi-events to indexed play ranges
- Bindings controlling the conditioned bindings depending on Transport position. This binding is responsible for suppression of arming a loop for some reasons: only one loop play range can be armed at a time, so it could be clever to interlock play ranges. Even more important: lock the arming for loops lying completely in the past.
- Mechanism automatically switching from a looped to the corresponding non looped play range if a looped play range just had looped
As there are no binding conditioned bindings available atm I split the first item into 2 parts:
A) A named (and so binding-controllable) routing from a Midi-port to a Midi loopback port
B) A binding from this Loopback port to the desired play range
The second item is already available (Transport → In Range → [name of conditioned routing] → Enabled → Normal) means: no need for a dirty hack
Third item was a bit tricky: when choosing the end of the loop range I found that this position was never really reached in reality resulting in a perpetually running loop.
Setting the position earlier lets play range change before reaching its end resulting in a never looping loop.
I found out there was a very small interval near the end of loop play range where the loop established once followed by changing to the non-looped play range. But as this only seems to exist due to more or less parasitic effects (run time) I decided to implement a more deterministic solution.
Unfortunately a binding from Transport Position to Play Range has no delay implemented which forced me to split this binding into:
A) Transport → On Position → Specific Trigger Event
B) On Specific Trigger → Delay → Select Play Range Indexed
This way it is possible to place switching position in uncritical distance to loops end and increase delay so that loop is established sufficiently before switching to no looped play range.
Finally I found it useful to implement 2 bindings choosing the largest play range on song load and on transport on stop.
Counting in a a binding for arming and disarming for a certain loop the whole method for one loop consists of one conditioned routing & 5 bindings.
It may be a good idea to wrap latest into a group. This way a first created group can simply be duplicated and only parameters have to be modified for a second, third… loop. Please don‘t forget to add one conditioned binding for each group…
Using Filters in the routing it is easily possible to use any sort of Midi event (f.e.
Note on, Controller events) for arming/disarming loops. Generally spoken it is possible to map a seperate event to each loop and event (arm/disarm). On the other hand it is also possible to only use 2 events (f.e. 2 pedals) for a complete song consisting of a bunch of looped play ranges if interlocking is done properly.
I hope I could clarify the method sufficiently.
Any comments or ideas warmly welcome of course,
kind regards, humphrey