Ableton Link
这是Ableton Link的代码库,它是一种可以跨多个设备上运行的多个应用程序同步音乐节拍、速度和相位的技术。连接到本地网络的设备上的应用程序会自动发现彼此,并形成一个音乐会话,其中每个参与者都可以独立演奏:任何人都可以开始或停止,同时保持同步。任何人都可以改变速度,其他人会跟随。任何人都可以加入或离开,而不会中断会话。
许可证
Ableton Link采用双重许可,包括GPLv2+和专有许可。如果您想将Link集成到专有软件应用程序中,请联系link-devs@ableton.com。
构建和运行Link示例
Link依赖于作为子模块的asio-standalone
。在检出主仓库后,需要使用以下命令加载这些子模块:
git submodule update --init --recursive
Link使用CMake为基于Catch的单元测试和示例应用程序生成构建文件。
$ mkdir build
$ cd build
$ cmake ..
$ cmake --build .
示例应用程序和单元测试的输出二进制文件将放置在CMake二进制目录的bin
子目录中。
将Link集成到您的应用程序中
测试计划
为确保用户在使用Link时获得最佳体验,所有支持Link的应用程序保持一致的行为非常重要。这包括例如与其他应用程序同步播放,以及加入时不劫持集体的速度。为确保您的应用程序按预期运行,请确保它符合测试计划。
构建Link
Link是一个仅头文件的库,因此将其集成到您的应用程序中应该很简单。
基于CMake的项目
如果您使用CMake,只需在CMakeLists.txt文件中添加以下内容:
include($PATH_TO_LINK/AbletonLinkConfig.cmake)
target_link_libraries($YOUR_TARGET Ableton::Link)
您可以选择让您的构建目标依赖于${link_HEADERS}
,这将使Link头文件在您的IDE中可见。此变量由Link的CMakeLists.txt导出到PARENT_SCOPE
。
其他构建系统
要在非CMake项目中包含Link库,您必须执行以下操作:
- 将
link/include
和modules/asio-standalone/asio/include
目录添加到您的包含路径列表中 - 根据您构建的平台,定义
LINK_PLATFORM_MACOSX=1
、LINK_PLATFORM_LINUX=1
或LINK_PLATFORM_WINDOWS=1
如果遇到任何编译器错误/警告,请查看compile-flags.cmake,它可能提供一些有关构建Link所需编译器标志的见解。
构建要求
平台 | 最低要求 | 可选(仅示例需要) |
---|---|---|
Windows | MSVC 2015 | Steinberg ASIO SDK 2.3 |
Mac | Xcode 9.4.1 | |
Linux | Clang 3.6 或 GCC 5.2 | libportaudio19-dev |
其他具有良好C++11支持的编译器应该也能工作,但未经验证。
iOS开发者不应使用此仓库。有关iOS LinkKit SDK的信息,请访问http://ableton.github.io/linkkit。
文档
Link概念的概述可以在http://ableton.github.io/link找到。初次接触Link的人应该从那里开始。[Link.hpp](include/ableton/Link.hpp)头文件包含完整的Link公共接口。有关Link
类型的使用示例,请参见此仓库中的LinkHut项目。
时间和时钟
Link通过计算会话中设备系统时钟之间的关系来工作。由于获取系统时间值的机制和这些值的单位在不同平台上有所不同,Link定义了一个Clock
抽象,并有特定平台的实现。请参见:
- Link.hpp中的
Link::clock()
方法 - platforms/darwin/Clock.hpp中的OSX和iOS时钟实现
- platforms/windows/Clock.hpp中的Windows时钟实现
- platforms/stl/Clock.hpp中基于C++标准库
std::chrono::steady_clock
的实现
在音频回调的上下文中正确使用系统时间变得有些复杂。音频设备通常有一个独立于系统时钟的采样时钟。Link维护系统时间和节拍时间之间的映射,因此不能直接使用音频系统提供的采样时间。
在OSX和iOS上,CoreAudio渲染回调会传递一个AudioTimeStamp
结构,其中mHostTime
成员表示音频缓冲区将传递给音频硬件的系统时间。这正是使用Link推导缓冲区中样本对应节拍时间值所需的信息。不幸的是,并非所有平台都在音频回调中提供这些数据。
当系统时间戳未与音频缓冲区一起提供时,客户端在音频回调中能做的最好的就是获取当前系统时间,并根据提供的采样时间对其进行过滤。过滤是必要的,因为音频回调不会以完全规律的间隔调用,因此查询的系统时间相对于采样时钟会表现出抖动。Link库提供了一个HostTimeFilter实用类,它在系统时间和采样时间之间执行线性回归,以提高音频回调中使用的系统时间值的准确性。请参见示例中用于各种平台的音频回调实现,以了解实际使用方法。请注意,对于基于Windows的系统,我们建议使用ASIO音频驱动程序。
延迟补偿
如前一节所讨论的,客户端在音频回调中提供的系统时间要么表示缓冲区将提交给音频硬件的时间(对于OSX/iOS),要么表示调用回调的时间(当回调中的代码查询系统时间时)。请注意,这两者都不是我们实际想要在设备之间同步以保持同步播放的时间。
为了让多个设备同步播放,我们需要同步它们的信号到达扬声器或输出线的时刻。如果不进行这种补偿,具有不同输出延迟的设备的输出信号将表现出持续的偏移。因此,在将系统时间值传递给Link方法之前,应该加上音频系统的输出延迟。这种延迟补偿的示例可以在示例应用程序的平台实现中找到。