Async Python interface for Ableton Link
Project description
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.
Installation
aalink requires at least Python 3.8. It can be installed using pip:
pip3 install aalink
It may be required to install the latest version of MSVC Runtime libraries on Windows to use the binary wheels currently hosted on PyPI.
Usage
aalink uses asyncio. To connect to a Link session, create a Link object, passing the asyncio event loop to the constructor, and await for Link.sync() as follows:
import asyncio
from aalink import Link
async def main():
loop = asyncio.get_running_loop()
link = Link(120, loop)
link.enabled = True
while True:
await link.sync(1)
print('bang!')
asyncio.run(main())
Link.sync(n) returns a Future scheduled to be done when Link time reaches next n-th beat on the timeline.
In the above example, awaiting for link.sync(1) will pause and resume the main coroutine at beats 1, 2, 3, and so on.
Keep in mind that awaiting for sync(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 for sync(2) at beat 11.5 will resume at beat 12.
Non-integral beat syncing is supported. For example:
await link.sync(1/2) # resumes at beats 0.5, 1, 1.5...
await link.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 an offset argument to sync(). Use this to add groove to the coroutine rhythm.
async def arpeggiate():
for i in range(16):
swing = 0.25 if i % 2 == 1 else 0
await link.sync(1/2, offset=swing)
print('###', i)
await link.sync(1/2, offset=0)
print('@@@', i)
Combine synced coroutines to run in series or concurrently:
import asyncio
from aalink import Link
async def main():
loop = asyncio.get_running_loop()
link = Link(120, loop)
link.enabled = True
async def sequence(name):
for i in range(4):
await link.sync(1)
print('bang!', name)
await sequence('a')
await sequence('b')
await asyncio.gather(sequence('c'), sequence('d'))
asyncio.run(main())
Limitations
aalink 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 from sync() aren’t equal to the exact beat time from the moment the futures are done. They correspond to the previously estimated resume times instead.
b = await link.sync(1) # b will be 1.0, returned at beat 1.00190
b = await link.sync(1) # b will be 2.0, returned at beat 2.00027
b = await link.sync(1) # b will be 3.0, returned at beat 3.00005
License
Copyright (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 the LICENSE file included in this repository.
aalink includes code from pybind11 and Ableton Link.
Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>, All rights reserved.
Copyright 2016, Ableton AG, Berlin. All rights reserved.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Hashes for aalink-0.0.6-cp312-cp312-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 14f65a57241d3fccc20365fa0c29b8715299810eafaef11f00f367c895bc818b |
|
MD5 | 179b64cf09f5a16b024b47ed2134d65c |
|
BLAKE2b-256 | f6825070fe1680b1ca537084843cbd903f1850e3613167ab203d7f35e6a80ebc |
Hashes for aalink-0.0.6-cp312-cp312-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9a97835802f915df77ddc2847855aac9add0d4c93d78ce13e5a190d0a4428979 |
|
MD5 | b8e579c1fe1168ba2c75d4785114e0ce |
|
BLAKE2b-256 | a0c45c54515e6b6619410b4e708e423699faac38fb0a33205cb5f4e39f07cde0 |
Hashes for aalink-0.0.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 69e06ac8aa6a0f900d171289e2ef17a21769126734e2a6ff3e873e198bf554d5 |
|
MD5 | f064f2e74c05f1437f7cef7894e74f66 |
|
BLAKE2b-256 | 283c87c921d8f714411cf00f5c28c6a371fde886f2e811c3c9299543606ed3b9 |
Hashes for aalink-0.0.6-cp312-cp312-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2caf812241d8d153a0cd91d86bf53e97f8986241c8ad87960c8e13985723570b |
|
MD5 | 92b407b632968fea629b1c6f38af0994 |
|
BLAKE2b-256 | 664377612d35ca562581aff42ab445c61643040c9983c4ec28230bd014b7bd97 |
Hashes for aalink-0.0.6-cp312-cp312-macosx_10_14_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8b3a38c0570456fcd063425a7bd97e2df09dd16e3cb339f6e272043d94b49580 |
|
MD5 | 292292e334a9476dd1fd3a3af464c63c |
|
BLAKE2b-256 | a1678984bd26fbb8a191aceac31548c9f3bc1bf2250ef06adabc3d29cb664318 |
Hashes for aalink-0.0.6-cp311-cp311-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 698caeda03291394b2052164541af1559a3016040a5d240cb310a50288075743 |
|
MD5 | c9018c2e402c9ae9d4cb8779f8e002c5 |
|
BLAKE2b-256 | 96a58105289e14a0119e771a4b412bd39aa8cc703af42b75a0c5b4685a138f93 |
Hashes for aalink-0.0.6-cp311-cp311-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | fbafd7a56e5bb3f43e6d5e023e932595378ad47dc1ddc82dd5b524db4df5fb48 |
|
MD5 | f6ec37378825712a7e7c94e0dfb03a37 |
|
BLAKE2b-256 | 6de6f6b12fcb61d55c2d9134e56f43c96f9227d20087efa1a47a19ef65b29e79 |
Hashes for aalink-0.0.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 59450538f3bf2ab66dee49aa55beefefdfed4f72d5c351d1f012434bd84c29cd |
|
MD5 | c550f3161745285fd0d699a20c6606cb |
|
BLAKE2b-256 | ac3f2f75a116b44649b56c45a0e744a2f33797d63a2ae422406c86b50dbd506a |
Hashes for aalink-0.0.6-cp311-cp311-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 766a06937091cdf53eff5993b7c6492b474b45fcc0335aa7cd8dc02f868ff7e6 |
|
MD5 | 01667d23b14541419b762a69ccb989de |
|
BLAKE2b-256 | 94874a46ea66f845ec78723e87d9b344a06633e801f77e65b6b6c192ea0edb2d |
Hashes for aalink-0.0.6-cp311-cp311-macosx_10_14_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | fdadebe438bcba15fe45da00f4190675912964cb1bbb19e08109d63c5a649a99 |
|
MD5 | 33ece4c3724214f8823bc05d690382c3 |
|
BLAKE2b-256 | 8a17a74565f7e5ed0cbd93cff1ec367fe61a81f02446990af53621788d331dd4 |
Hashes for aalink-0.0.6-cp310-cp310-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7836b36e2257d6c94d6b58534fd4fc967833e60ed5ef0bea6e746cac346efbc4 |
|
MD5 | 88d0adf2d1a081b5e85b2976de9b7c79 |
|
BLAKE2b-256 | c3882851e65a113a9c8da6dce84e623d80b69f46cc4f8ecc8e06068fd3361c92 |
Hashes for aalink-0.0.6-cp310-cp310-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 75a498f3cebe653ac116d2ac6063b41f3e6aad2531e947ceac0d51cb33cd72e3 |
|
MD5 | 0106c52da9405c540c0ab3c8b5a8a4e6 |
|
BLAKE2b-256 | e989621b81c19dbac425692fe32c67771c60f129c20bf9531d3e9aa5357eed2d |
Hashes for aalink-0.0.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | ef7f84520dcbf8bd180622b1c2b89f328362917059eb07430442fd0e2051a94b |
|
MD5 | a0684fa09439fb0f01fe4a7c88187a24 |
|
BLAKE2b-256 | d9a76ec37721392fbd90db3e4642b2d2eedc185a41e0be46f0733097b851a268 |
Hashes for aalink-0.0.6-cp310-cp310-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1f4ce935bbf3aa89994c75f551b86fdddc14d579d99b4b86a7a92aabbf6d3842 |
|
MD5 | ad10c823c5ce266f50f154e3b13e50f9 |
|
BLAKE2b-256 | 27ebe128a51d9a9ae926b7677a289a256afd637c7fd32d845e854f23c00e9a16 |
Hashes for aalink-0.0.6-cp310-cp310-macosx_10_14_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 981e8ef542faa06d4d4110d955cd453dc4685a1ae702273f0ca9787f0cd05f8c |
|
MD5 | 1040198eedad2a689874229236ed9c5c |
|
BLAKE2b-256 | 0c729d4027a656cb5a134e71b321478b82126190be43c133aa80f0997eb1e7ef |
Hashes for aalink-0.0.6-cp39-cp39-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 078c53910fe9602a306ac78ff9c9fcadad85cf43ddea66d1146d9e0b30ef8457 |
|
MD5 | 02c858275524a8c3d30b263083836c87 |
|
BLAKE2b-256 | 002afc0360c05c5699422865592f43c6702a558f42f7781a9fcd30c587faa5cd |
Hashes for aalink-0.0.6-cp39-cp39-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0cedb4a1fd85242c857ad8cf09f932426f7c465ca62f34155cfaaef0fc30a162 |
|
MD5 | f61745783bf361d9b7f3ff3141a6365a |
|
BLAKE2b-256 | cf410bb8ed2ae06c16d41fb531e64dd062d980aac411b25a07985122c5ffffe6 |
Hashes for aalink-0.0.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d120f322cb1abf874e4e0ed595c6d9ac606d10ff8347b4e894f5f24bafdfb085 |
|
MD5 | 10c72c9c6a7c8ef9dcceb4e4286097eb |
|
BLAKE2b-256 | f557344750f4f11ee2f4a6dfefdc3f4a0c26994486cc471e7f4ba2478fda6c77 |
Hashes for aalink-0.0.6-cp39-cp39-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1c4f5c27c0ef66ba80be6527aaa2e1173f53c9db4fbb4f700a6160c23c542aa9 |
|
MD5 | e46e9f22a05e2f823b654b54d65f4493 |
|
BLAKE2b-256 | a8bd893ae08850fe3f473e8727e14af664c441d0dec5c350696fc07940c48ff7 |
Hashes for aalink-0.0.6-cp39-cp39-macosx_10_14_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | a26f38f5497459f65fcbbf798f14608f551d906ee5be2aaaf509331828923849 |
|
MD5 | f7cf2b01ff91e50e5ea75f8e40a4cadb |
|
BLAKE2b-256 | b090551c1dc6405f35e71f9fa0d10f5a6c6ef70323aebda36d0fd930fad6d638 |
Hashes for aalink-0.0.6-cp38-cp38-win_amd64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | a197b760ed34e7c97ea3f270f7a22003f81efee4ecc71d24a092e7036c761535 |
|
MD5 | 29b9efc0cfa5a2edef4f437bc13dc734 |
|
BLAKE2b-256 | cd521fe06b8b1b5a1f56aab9698a7b3414ae20b16f4d80c4092801f331b18ca6 |
Hashes for aalink-0.0.6-cp38-cp38-musllinux_1_1_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | be40888b30f4ee7b3f80c5f1d80052b35c8f6592b1b6ce5754f443fe62a87da2 |
|
MD5 | 7d8983feb144466c9f4f8cf192e64542 |
|
BLAKE2b-256 | ba2f69f2802c63c843ae241f014729c6c0bf1d20b4311d197e9b8f06185e52cb |
Hashes for aalink-0.0.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 461f3559f51c94c424860f3da228281fec381814c1678abb0688d314c0b54bb4 |
|
MD5 | 143a6d04513c28a883b55a809c88ec79 |
|
BLAKE2b-256 | decaa3fe82d38e76b1ca9f24343d506856ee182dea03689604cdee1877f4d4e9 |
Hashes for aalink-0.0.6-cp38-cp38-macosx_11_0_arm64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 76949783923b457a2573b923f4216953dd3c190acd15bd15bc50ed6338027cd1 |
|
MD5 | 9bc0feacb858e24debcebc6a1138b93f |
|
BLAKE2b-256 | b01c3f87fb15000b3825bd96d90189aae55c594c0c0006b29c064aaf74ba041b |
Hashes for aalink-0.0.6-cp38-cp38-macosx_10_14_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | c89ee04c90fdccee522f7372cc19def80300874678d744b813a2e4bad3946275 |
|
MD5 | b04343b3dc1ffff2cdf2101ab39163ba |
|
BLAKE2b-256 | 00edad0e9c2118a2e71b96656dc01d66c32d6826ac19d5277adaa587a47781ea |