Package: aalink
aalink is a Python wrapper for Ableton Link built for interactive applications
using asyncio event loops.It provides awaitable objects for synchronizing Python code with other peers
in an Ableton Link session, but it may also be used for writing fully
standalone scripts with tempo/beat synchronization, such as applications
for light and sound control.Installationaalink requires at least Python 3.8. It can be installed using pip:pip3 install aalinkIt may be required to install the latest version of MSVC Runtime libraries
on Windows to use the binary wheels currently hosted on PyPI.Usageaalink uses asyncio. To connect to a Link session, create aLinkobject,
passing the asyncio event loop to the constructor, and await forLink.sync()as follows:importasynciofromaalinkimportLinkasyncdefmain():loop=asyncio.get_running_loop()link=Link(120,loop)link.enabled=TruewhileTrue:awaitlink.sync(1)print('bang!')asyncio.run(main())Link.sync(n)returns aFuturescheduled to bedonewhen Link time
reaches next n-th beat on the timeline.In the above example, awaiting forlink.sync(1)will pause and resume
themaincoroutine at beats 1, 2, 3, and so on.Keep in mind that awaiting forsync(n)does not cause a coroutine to sleep
for the given number of beats. Regardless of the moment when the coroutine is
suspended, it will resume when the next closest n-th beat is reached on the
shared Link timeline, e.g. awaiting forsync(2)at beat 11.5 will resume
at beat 12.Non-integral beat syncing is supported. For example:awaitlink.sync(1/2)# resumes at beats 0.5, 1, 1.5...awaitlink.sync(3/2)# resumes at beats 1.5, 3, 4.5...Sync events can be scheduled with an offset (also expressed in beats) by
passing anoffsetargument tosync(). Use this to add groove to the
coroutine rhythm.asyncdefarpeggiate():foriinrange(16):swing=0.25ifi%2==1else0awaitlink.sync(1/2,offset=swing)print('###',i)awaitlink.sync(1/2,offset=0)print('@@@',i)Combine synced coroutines to run in series or concurrently:importasynciofromaalinkimportLinkasyncdefmain():loop=asyncio.get_running_loop()link=Link(120,loop)link.enabled=Trueasyncdefsequence(name):foriinrange(4):awaitlink.sync(1)print('bang!',name)awaitsequence('a')awaitsequence('b')awaitasyncio.gather(sequence('c'),sequence('d'))asyncio.run(main())Limitationsaalink aims to be punctual, but it is not 100% accurate due to the processing
delay in the internal scheduler and the uncertainty of event loop iterations
timing.For convenience, the numerical values of futures returned fromsync()aren’t equal to the exact beat time from the moment the futures aredone.
They correspond to the previously estimated resume times instead.b=awaitlink.sync(1)# b will be 1.0, returned at beat 1.00190b=awaitlink.sync(1)# b will be 2.0, returned at beat 2.00027b=awaitlink.sync(1)# b will be 3.0, returned at beat 3.00005LicenseCopyright (c) 2023 Artem Popov <art@artfwo.net>aalink is licensed under the GNU General Public License (GPL) version 3.
You can find the full text of the GPL license in theLICENSEfile included
in this repository.aalink includes code from pybind11 and Ableton Link.pybind11Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>, All rights reserved.pybind11 licenseAbleton LinkCopyright 2016, Ableton AG, Berlin. All rights reserved.Ableton Link license