{"id":13431181,"url":"https://github.com/anzbert/f_link","last_synced_at":"2025-10-23T04:57:24.288Z","repository":{"id":60885078,"uuid":"542836456","full_name":"anzbert/f_link","owner":"anzbert","description":"Ableton Link support in Flutter","archived":false,"fork":false,"pushed_at":"2024-09-11T07:24:25.000Z","size":5906,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-10-28T11:51:54.646Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/anzbert.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-09-28T23:45:06.000Z","updated_at":"2024-09-11T07:24:29.000Z","dependencies_parsed_at":"2023-02-14T03:32:02.225Z","dependency_job_id":null,"html_url":"https://github.com/anzbert/f_link","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anzbert%2Ff_link","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anzbert%2Ff_link/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anzbert%2Ff_link/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anzbert%2Ff_link/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/anzbert","download_url":"https://codeload.github.com/anzbert/f_link/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243862770,"owners_count":20360207,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T02:01:01.113Z","updated_at":"2025-10-23T04:57:19.263Z","avatar_url":"https://github.com/anzbert.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"[![pub_package](https://img.shields.io/pub/v/f_link.svg?color=blue)](https://pub.dartlang.org/packages/f_link)\n\n# f_link\n\nf_link is a Flutter wrapper of [abl_link](https://github.com/Ableton/link/tree/master/extensions/abl_link), which is a C 11 extension made by Ableton for their C++ codebase.\nThis library attempts to be unopinionated and plain in\ncopying the functionality of abl_link, while providing some high level convenience and safety.\n\n[Ableton Link](https://ableton.github.io/link) is a technology that synchronizes musical beat, tempo,\nphase, and start/stop commands across multiple applications running\non one or more devices. Applications on devices connected to a local\nnetwork discover each other automatically and form a musical session\nin which each participant can perform independently: anyone can start\nor stop while still staying in time. Anyone can change the tempo, the\nothers will follow. Anyone can join or leave without disrupting the session.\n\n## Usage\n\n### Android\n\nAndroid apps must declare their use of the network in the Android manifest in `android/src/main/AndroidManifest.xml`. Add this permission request inside the `\u003cmanifest\u003e` scope:\n\n```\n\u003cuses-permission android:name=\"android.permission.INTERNET\" /\u003e\n```\n\n### MacOS\n\nRequires entitlements to be set to give the app network usage permissions. Add this key to `macos/Runner/DebugProfile.entitlements` and to `macos/Runner/Release.entitlements`:\n\n```\n\u003ckey\u003ecom.apple.security.network.client\u003c/key\u003e\n\u003ctrue/\u003e\n```\n\n## Implementation\n\n- f_link currently wraps around all functions available in ['abl_link.h'](https://github.com/Ableton/link/blob/master/extensions/abl_link/include/abl_link.h) and makes them publicly available. The destructors are implemented with [NativeFinalizer](https://api.dart.dev/stable/2.18.2/dart-ffi/NativeFinalizer-class.html), which should make manually destroying instances and freeing memory unnecessary.\n- Function documentation has been copied almost 1:1 from 'abl_link.h' as it should still apply.\n- Functions have been implemented as methods on either the `AblLink` or the `SessionState` struct depending on which of the two the original C function uses as a primary parameter and what seemed to be the most intuitive.\n- At this point, handling thread and realtime safety with Audio and App SessionStates is left up to the user, just like in the original library.\n- Callbacks have been omitted from this library (see Known Issues).\n\n## Known Issues\n\n### Audio Playback and Latency\n\nAudio playback and latency in Flutter requires some careful considerations as it is somewhat platform and integration dependent. Latency compensation would certainly need to be factored into the code either way.\n\nAbleton recommends to handle audio Session States in a separate thread to minimize latency. This could potentially be achieved with isolates and maybe even by integrating another low level native library to handle playback. I am happy to receive feedback on this issue and I may update the example at some point with a possible solution.\n\n### No iOS support yet\n\nAbleton provides a different SDK for iOS, called [LinkKit](https://github.com/Ableton/LinkKit), which uses a different API to [Link](https://github.com/Ableton/link). Potentially, this library could wrap around both LinkKit and Link in the future.\n\n### Registering callbacks with native code\n\nCallbacks are not implemented yet. Native callbacks are difficult to implement into the Dart event loop. Currently they could only safely be done with native ports, which I may attempt at some point. See this Issue for more details: https://github.com/dart-lang/sdk/issues/37022 . At this point the user has to implement a polling solutions instead of relying on callbacks (see Example).\n\n### Destructors\n\nNativeFinalizer should reliably destroy the native objects attached to AblLink and SessionState instances when they leave the current scope and become inaccessible. More investigations may be needed into the memory used by C++, to check if that reliably happens.\n\n## Feedback\n\nPull requests and feedback in the discussions section is very welcome!\n\n## License\n\nAbleton Link is dual licensed under GPLv2+ and a proprietary [license](https://github.com/Ableton/link/blob/master/LICENSE.md).\n\nThis means that this wrapper is automatically under the GPLv2+ as well. A copy of the license is distributed with the source code.\n\nIf you would like to incorporate Link into a proprietary software application, please contact Ableton at \u003clink-devs@ableton.com\u003e.\n\n## Links\n\nI also made an Ableton Link wrapper for Rust, called [rusty_link](https://crates.io/crates/rusty_link), to learn about FFI wrapping before making this plugin.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanzbert%2Ff_link","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanzbert%2Ff_link","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanzbert%2Ff_link/lists"}