bondagit/aes67-linux-daemon

GitHub: bondagit/aes67-linux-daemon

该项目是 AES67 音频网络互操作性标准的 Linux 守护进程实现,通过以太网进行 PTP 同步的实时音频流分发与管理,并提供配置用 WebUI。

Stars: 541 | Forks: 103

# AES67 Linux Daemon AES67 Linux Daemon 是 AES67 互操作性标准的 Linux 实现,用于通过以太网分发和同步实时音频。 有关更多信息,请参阅 [https://en.wikipedia.org/wiki/AES67](https://en.wikipedia.org/wiki/AES67)。 # 状态 ![Daemon 测试状态](https://static.pigsec.cn/wp-content/uploads/repos/cas/3c/3ca6da1dc15137caf9ea1df2074e4faf748a7aaec7c75376592409394028cf03.svg) ![WebUI 发布状态](https://static.pigsec.cn/wp-content/uploads/repos/cas/42/42ba98a60a0bb3b0ad908f024db145f9c5b831eb7df822f56ac578ee7d7215b3.svg) # 简介 该 daemon 是一个 Linux 进程,它使用 [Merging Technologies ALSA RAVENNA/AES67 Driver](https://bitbucket.org/MergingTechnologies/ravenna-alsa-lkm/src/master) 来处理 PTP 同步和 RTP 流,并提供 REST 接口用于配置和状态监控。 **ALSA AES67 Driver** 实现了一个虚拟 ALSA 音频设备,该设备可以使用 _Sources_ 和 _Sinks_ 进行配置,并使用 PTP 时钟进行计时。 _Source_ 从 ALSA 播放设备读取音频样本,并将 RTP 数据包发送到配置的多播或单播地址。 _Sink_ 从特定的多播或单播地址接收 RTP 数据包,并将它们写入 ALSA 捕获设备。 用户可以使用 ALSA 捕获设备从 RTP 流接收同步的传入音频样本,并使用 ALSA 播放设备将同步的音频样本发送到 RTP 流。 _Source_ 和 ALSA 播放设备之间的绑定取决于播放期间使用的通道以及配置的 _Source_ 通道映射。_Sink_ 和 ALSA 捕获设备之间的绑定取决于录制期间使用的通道以及配置的 _Sink_ 通道映射。 该驱动程序处理 PTP 和 RTP 数据包处理,并充当 PTP 时钟从设备,以与指定 PTP 域上的主时钟同步。所有配置的 _Sources_ 和 _Sinks_ 均使用相同的 PTP 时钟进行同步。 daemon 仅通过 _netlink_ 套接字与驱动程序进行控制、配置和状态监控通信。 daemon 实现了一个 REST 接口来配置和监控 _Sources_、_Sinks_ 和 PTP 从设备。有关更多信息,请参阅 [README](daemon/README.md)。 它还实现了兼容 AES67 标准的 SAP 源发现和通告,以及兼容 Ravenna 标准的 mDNS 源发现和通告。 提供了一个 WebUI 来允许进行 daemon 和驱动程序的配置及监控。WebUI 使用 daemon REST API,并公开了 daemon、PTP 从时钟、_Sources_ 和 _Sinks_ 的所有受支持的配置参数。WebUI 还可用于监控 PTP 从设备状态和 _Sinks_ 状态,以及浏览远程 SAP 和 mDNS 源。 ## 许可证 AES67 daemon 和 WebUI 采用 [GNU GPL](https://www.gnu.org/licenses/gpl-3.0.en.html) 许可。 该 daemon 使用了以下开源软件: * **Merging Technologies ALSA RAVENNA/AES67 Driver**,采用 [GNU GPL](https://www.gnu.org/licenses/gpl-3.0.en.html) 许可。 * **cpp-httplib**,采用 [MIT License](https://github.com/yhirose/cpp-httplib/blob/master/LICENSE) 许可。 * **Avahi common & client libraries**,采用 [LGPL License](https://github.com/lathiat/avahi/blob/master/LICENSE) 许可。 * **Boost libraries**,采用 [Boost Software License](https://www.boost.org/LICENSE_1_0.txt) 许可。 * **Freeware Advanced Audio Coder**,采用 [LGPL License](https://github.com/knik0/faac?tab=License-1-ov-file) 许可。 ## 前置条件 该 daemon 和测试已在基于 **ARMv7** 和 **x86** 平台的 **Ubuntu 18.04** 及更高版本的发行版上验证通过,使用环境如下: * Linux 内核版本 >= 4.10.x * GCC 版本 >= 7.x / clang >= 6.x(需要支持 C++17) * cmake 版本 >= 3.7 * boost 库版本 >= 1.65 * Avahi 服务发现(如果启用) >= 0.7 * Freeware Advanced Audio Coder(如果启用了流媒体) libfaac >= 1.30 以下平台已用于测试: 一台搭载 Allwinner H5 四核 64 位 Cortex A53 处理器的 NanoPi NEO2。 有关如何在此开发板上设置 Ubuntu 的更多信息,请参阅 [Armbian NanoPi NEO2 ](https://www.armbian.com/nanopi-neo-2/)。 一台搭载 Intel® Celeron® Processor N4020 处理器,2 核心/2 线程(4M 缓存,高达 2.80 GHz)的 Mini PC N40。 请参阅 [Minisforum N40 Mini PC](https://store.minisforum.com/products/minisforum-n40-mini-pc) 和 [如何在无风扇 Mini PC 上安装 Ubuntu](https://www.youtube.com/watch?v=2djTPJ02xK0)。 可以使用 [debian-packages.sh](debian-packages.sh) 脚本来安装编译和运行 AES67 daemon 以及[平台兼容性测试](#test)所需的所有包。 **_重要提示_** CPU 频率调节事件可能会影响 daemon 流,导致意外的失真,请参阅 [CPU 频率调节事件和脚本说明](#notes)。 **_重要提示_** 从 Linux 内核 5.10.x 起,需要更改某个内核参数来修复轮转调度器 导致延迟测试失败的问题,请参阅[实时调度器限制](#notes)。 **_重要提示_** 必须禁用或卸载 _PulseAudio_ 才能使 daemon 正常工作,请参阅 [PulseAudio 和脚本说明](#notes)。 ## 如何构建和设置 daemon 在你的目标机器(ARM 或 X86)上安装 Ubuntu Linux 发行版。**不要使用虚拟机**。 该 daemon 应该可以在 18.04 及更高版本的所有 Ubuntu 上运行,也可以使用其他发行版。 * 运行 [ubuntu-packages.sh](ubuntu-packages.sh) 脚本来安装所有必需的包 * 执行 [build.sh](build.sh) 脚本以下载并构建驱动程序、daemon 和 WebUI,请参阅[脚本说明](#notes)。 该脚本执行以下操作: * 检出、修补并构建 Merging Technologies ALSA RAVENNA/AES67 模块 * 检出 cpp-httplib * 构建并部署 WebUI * 构建 AES67 daemon * 编辑 daemon 配置文件 _daemon/daemon.conf_,并将 _interface_name_ 参数更改为你想要使用的以太网网络接口。例如:_eth0_ * 在主文件夹中执行以下命令来安装驱动程序: (cd 3rdparty/ravenna-alsa-lkm/driver && sudo insmod ./MergingRavennaALSA.ko) * 在主文件夹中执行以下命令来启动 daemon: cd daemon ./aes67-daemon -c daemon.conf * 如果你想将 daemon HTTP 服务器绑定到另一个地址,请使用 daemon 选项 _-a_。例如 _-a 0.0.0.0_ 可将 daemon HTTP 服务器绑定到所有本地网络接口。 * 打开浏览器并加载 http://[your_ip]:8080 处的 daemon 配置 WebUI * 在 WebUI 上,使用 Browser 选项卡查看网络上通告的其他 AES67 Sources。 * 在 WebUI 上,使用 Sinks 选项卡,通过手动指定远程 Source 或选择发现的远程 Source 之一来创建接收器(勾选 Use SDP 选项可启用此功能)。 * 在 WebUI 上,使用 Sources 选项卡创建一个 daemon 源 * 在 WebUI 上,使用 PTP 选项卡检查 daemon PTP 从设备的状态。只有当 PTP 从设备状态为 locked 时,才能通过 ALSA RAVENNA 设备接收或发送音频。 * 在 RAVENNA ALSA 设备上进行播放以通过 Source 发送音频,例如对于立体声 Source,使用: speaker-test -D plughw:RAVENNA -r 48000 -c 2 -t sine * 从 RAVENNA ALSA 设备进行录制以通过 Sink 接收音频,例如要录制到文件中的立体声 Sink,使用: arecord -D plughw:RAVENNA -c 2 -f cd -d 30 -r 48000 -t wav sink.wav * 要与其他 AES67 设备(例如 Dante 设备)运行互操作性测试,请使用以下说明。 ## 设备和互操作性测试 请参阅 [AES67 daemon 的设备和互操作性测试](DEVICES.md) ## 支持 ST-2022-7 从 daemon 3.0 版本和驱动程序 2.0 版本开始,增加了对 ST-2022-7 的支持。 当通过 daemon 的 _interface_name_ 参数配置了 2 个接口时,此功能会自动启用。 当启用 ST-2022-7 时: - 驱动程序的 PTP 从设备会从两个接口接收数据包,并自动选举出主时钟。 - 对于 Source,输出的数据包将通过两个接口传输。 - 对于 Sink,将从两个接口接收数据包,并相应地合并传入的流。 - AES67 控制(SAP 和 mDNS)在所有接口上运行。 从 daemon 版本 3.1 开始,daemon 和 WebUI 均支持为辅助接口(daemon 参数 _rtp_mcast_base_sec_ 和 _rtp_port_sec_)指定单独的地址和端口。 启用 ST-2022-7 时,daemon 会将这些值用于 Sources,并在关联的 SDP 文件中通告冗余的多播音频流。 例如: ``` v=0 o=- 2831159553 317021570 IN IP4 192.168.1.17 s=Daemon a8c01101 ALSA Source 0 t=0 0 a=group:DUP 1 2 m=audio 5004 RTP/AVP 98 c=IN IP4 239.1.0.1/15 a=source-filter: incl IN IP4 239.1.0.1 192.168.1.17 a=rtpmap:98 L24/48000/2 a=sync-time:0 a=framecount:48 a=ptime:1 a=mediaclk:direct=0 a=clock-domain:PTPv2 0 a=ts-refclk:ptp=IEEE1588-2008:00-1D-C1-FF-FE-50-36-33:0 a=recvonly a=mid:1 m=audio 5006 RTP/AVP 98 c=IN IP4 239.1.0.1/15 a=source-filter: incl IN IP4 239.1.0.1 192.168.1.18 a=rtpmap:98 L24/48000/2 a=sync-time:0 a=framecount:48 a=ptime:1 a=mediaclk:direct=0 a=clock-domain:PTPv2 0 a=ts-refclk:ptp=IEEE1588-2008:00-1D-C1-FF-FE-50-36-33:0 a=mid:2 ``` 如果创建 Source 时定义了特定的 RTP 地址,该地址将同时用于主接口和辅助接口,替换默认地址。 对于 Sink,当启用 ST-2022-7 时,daemon 会从远程 Source 的 SDP 文件中检索音频媒体冗余多播流的地址和端口。如果未指定,daemon 将使用为主接口指定的地址和端口。 主音频流始终通过主接口进行发送和接收,而冗余音频流始终通过辅助接口进行发送和接收。 单个接口可以同时配置为主接口和辅助接口。 ## HTTP Streamer HTTP Streamer 随 daemon 2.0 版本引入,用于通过 HTTP 文件流接收 AES67 音频流。 从 daemon 版本 2.2 开始,Streamer 支持兼容 [VideoLAN](https://www.videolan.org/) 的实时 HTTP 流。 可以通过 daemon 参数 _streamer_enabled_ 来启用 HTTP Streamer。 当 Streamer 处于活动状态时,daemon 会开始捕获配置的 _Sinks_,最大通道数由 _streamer_channels_ 参数配置。 捕获的 PCM 样本会被拆分为每个 sink 的 _streamer_files_num_ 个持续时间为 _streamer_file_duration_(以秒为单位)的文件,使用 AAC LC 编解码器压缩并通过 HTTP 提供服务。 ![Screenshot 2024-06-15 at 15 36 48](https://static.pigsec.cn/wp-content/uploads/repos/cas/0b/0b3aeac03aa90a4f9e886e1703d34393b3f36e3d61bdac3f4b523193a32ade27.png) 编译 HTTP streamer 需要 libfaac-dev 包。 启用 HTTP Streamer 并配置了一个或多个 _Sinks_ 后,可以在以下 URL 接收使用 AAC LC 编码的 HTTP Live 流:_http://[daemon_ip:port]/api/streamer/stream/:sinkId_ 请注意,由于 HTTP Streamer 使用 RAVENNA ALSA 设备进行捕获,因此无法将此类设备用于其他音频捕获。 ## AES67 USB 接收器和发射器 请参阅[将您的开发板用作 AES67 USB 接收器和发射器](USB_GADGET.md) ## 仓库内容 ### [daemon](daemon) 目录 此目录包含 AES67 daemon 的源代码。 该 daemon 可以针对多个平台进行交叉编译,并实现以下功能: * ALSA RAVENNA/AES67 设备驱动程序的通信和配置 * 通过 netlink 使用 ALSA RAVENNA/AES67 驱动程序控制和配置最多 64 个多播和单播的 sources 和 sinks * 会话处理以及 SDP 解析和创建 * 用于 daemon 控制和配置的 HTTP REST API * 兼容 AES67 标准的 SAP 源发现、更新和通告 * 兼容 Ravenna 标准的 mDNS 源发现和通告(使用 Linux Avahi) * RTSP 客户端和服务器,根据 Ravenna 标准通过 DESCRIBE 和 ANNOUNCE 方法检索、返回和更新 SDP 文件 * 用于 SAP、PTP 和 RTP 会话的 IGMP 处理 * 集成 systemd watchdog 监控(自 daemon 版本 v1.6 起) 有关 AES67 daemon 配置和 daemon HTTP REST API 的更多信息,请参阅此目录中的 [README](daemon/README.md) 文件。 该目录还在 [tests](daemon/tests) 子目录中包含 daemon 测试。 daemon 测试可以通过 Docker 容器使用伪造版本的 daemon 驱动程序管理器来执行。 实现此功能是为了通过 GitHub 工作流自动执行测试。 要构建用于 daemon 回归测试的 Docker 镜像,请运行: ``` docker build --progress=plain -f ./Dockerfile.daemon_tests -t aes67-daemon-tests . ``` 要运行测试: ``` docker run aes67-daemon-tests ``` ### [webui](webui) 目录 此目录使用 React 实现的 AES67 daemon WebUI 配置。 使用 WebUI,用户可以执行以下操作: * 更改 daemon 配置,这会导致 daemon 重启 * 编辑 PTP 时钟从设备配置并监控 PTP 从设备状态 * 添加和编辑 RTP Sources * 添加、编辑和监控 RTP Sinks * 浏览远程 SAP 和 mDNS RTP sources ### [3rdparty](3rdparty) 目录 此目录用于下载第三方开源软件。 [ravenna-alsa-lkm repository 的 aes67-daemon 分支](https://github.com/bondagit/ravenna-alsa-lkm/tree/aes67-daemon) 包含 ALSA RAVENNA/AES67 模块代码以及对其应用的所有补丁。 ALSA RAVENNA/AES67 内核模块负责: * 注册为 ALSA 驱动程序 * 生成和接收 RTP 音频数据包 * PTP 从设备操作和 PTP 驱动的中断循环 * 用户空间和内核之间的 netlink 通信 原始模块已应用以下补丁: * 一组用于提高驱动程序稳定性和性能的补丁,请参阅 [367c166](https://github.com/bondagit/ravenna-alsa-lkm/commit/367c1665e8038272514a637ea03799350e8e12a8)。添加了 _audio_cpu_affinity_ 模块参数,将音频计时器绑定到特定的 CPU(自驱动程序 2.1 起)。 * 添加了对 ST-2022-7 的支持(自驱动程序 2.0 版本起)。此版本破坏了与旧版本的兼容性,并且需要新的 daemon。请参阅 [issue 248](https://github.com/bondagit/aes67-linux-daemon/issues/248) * 用于在 ANNOUNCE 消息中更新时更新当前主时钟的 grand master clock ID 的补丁(自驱动程序 v1.18 版本起)。请参阅驱动程序 [issue 34](https://github.com/bondagit/ravenna-alsa-lkm/issues/34) * 用于修复 PTP 主同步超时并具有较少限制的自旋锁的补丁(自驱动程序 v1.17 版本起)。请参阅 [issue 246](https://github.com/bondagit/aes67-linux-daemon/issues/246) * 用于修复 Linux Kernel v6.18 及更高版本的内核警告的补丁(自驱动程序 v1.16 版本起)。请参阅 [驱动程序 issue 32](https://github.com/bondagit/ravenna-alsa-lkm/issues/32) * 用于在 Linux Kernel v6.15 及更高版本上编译的补丁(自驱动程序 v1.15 版本起) * 用于正确释放网络设备的补丁,在某些 Linux Kernel 上,该问题会阻止设备重启和关机(自驱动程序 v1.14 起) * 使用 ALSA 管理的缓冲区分配以及在 Linux Kernel v6.12 及更高版本上编译的补丁(自驱动程序 v1.13 版本起) * 用于在 Linux Kernel v6.11 及更高版本上编译的补丁(自驱动程序 v1.11 版本起) * 支持采样率 192Khz 和 384Khz 的补丁(自驱动程序 v1.7 版本起) * 用于在 Linux Kernel v6.2 及更高版本上编译的补丁(自驱动程序 v1.7 版本起) * 如果超过 5 秒未收到来自 Master 的 announcement 消息,则使 PTP 从设备状态从 locked 变为 unlocked 的补丁(自驱动程序 v1.6 版本起)。请参阅 [issue 87](https://github.com/bondagit/aes67-linux-daemon/issues/87)。 * 用于修复在重新配置或 daemon 重启的情况下导致使用错误 Sources 和 Sinks 缓冲区偏移量问题的补丁(自驱动程序 v1.5 版本起)。请参阅 [issue 55](https://github.com/bondagit/aes67-linux-daemon/issues/55)。 * 允许配置更小的 ALSA 缓冲区大小以将端到端延迟降低至最高 8ms 的补丁(自驱动程序 v1.4 版本起)。请参阅[平台延迟测试](#latency) 并参阅 [issue 53](https://github.com/bondagit/aes67-linux-daemon/issues/53) * 从驱动程序功能中删除不受支持的非交错访问的补丁。这使得能够与 JACK audio 兼容(自驱动程序 v1.3 版本起) * 允许在 daemon 主机上使用 PTP 主时钟的补丁(自驱动程序 v1.1 版本起) * 重新设计驱动程序 PCM 接口,并简化和统一读写交错和内存映射访问模式处理的补丁 * 从 convert 函数中删除用户空间传输处理的补丁 * 添加对 AM824 (L32) 编解码器支持的补丁 * 初始化播放和捕获缓冲区的补丁 * 支持播放和捕获 ALSA 设备单声道的补丁 * 启用直接 PCM 传输模式而不是间接模式以启用 ALSA 插件使用的补丁 * 启用独立播放和捕获中断启动的补丁 * 禁用 PTP 数据包的 UDP 校验和检查的补丁 * 启用对 ARM 32 位和 64 位平台支持的补丁 * 启用网络环回设备的补丁 * 用于在 Linux Kernel v5 下编译的补丁 有关 Merging Technologies 模块以及正确的 Linux Kernel 配置和调优的更多信息,请参阅 [ALSA RAVENNA/AES67 Driver README](https://bitbucket.org/MergingTechnologies/ravenna-alsa-lkm/src/master/README.md)。 ### [systemd](systemd) 目录 此目录包含 daemon 的 systemd 配置文件。 daemon 与 systemd watchdog 集成。 要启用此功能,请使用 CMake 选项 _-DWITH_SYSTEMD=ON_ 重新编译 daemon 你可以使用 [systemd/install.sh](systemd/install.sh) 脚本在 _systemd_ 下安装 daemon: ``` cd systemd sudo ./install.sh ``` 在启动 daemon 之前,请编辑 _/etc/daemon.conf_ 并确保将 _interface_name_ 参数设置为你的以太网接口。 要启动 daemon,请使用: ``` sudo systemctl start aes67-daemon ``` 要停止它,请使用: ``` sudo systemctl stop aes67-daemon ``` 该 daemon 需要运行 _MergingRavennaALSA_ 模块。 你通常可以使用以下命令来安装该模块: ``` cd 3rdparty/ravenna-alsa-lkm/driver sudo make modules_install ``` 如果由于缺少内核证书而导致此操作无效,请按照以下说明操作: [无 OpenSSL sign-file signing_key.pem](https://superuser.com/questions/1214116/no-openssl-sign-file-signing-key-pem-leads-to-error-while-loading-kernel-modules) 在某些发行版上,你可能还需要使用以下命令创建模块加载配置文件: ``` echo 'MergingRavennaALSA' | sudo tee /etc/modules-load.d/MergingRavennaALSA.conf ``` 最后使用该命令加载模块: ``` sudo depmod -a ``` 并使用以下命令重新启动: ``` sudo reboot ``` ### [test](test) 目录 此目录包含用于在网络环回接口上运行 daemon 平台兼容性测试的文件。下面介绍了该 [test](#test)。 ## 运行平台兼容性测试 在尝试于特定主机或开发板上使用 AES67 daemon 之前,强烈建议运行平台测试。 平台测试在使用 ALSA RAVENNA/AES67 模块的环回网络设备上运行 RTP 会话的播放和录制,并检查是否有任何音频样本损坏或丢失。 此测试可以使用 [run\_test.sh](run_test.sh) 脚本执行。请参阅[脚本说明](#notes)。 该脚本允许用户测试特定配置,并可用于确保 daemon 能够在当前平台上顺畅地使用该配置运行。 ``` Usage run_test.sh sample_format sample_rate channels duration sample_format can be one of S16_LE, S24_3LE, S32_LE sample_rate can be one of 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000 channels can be one of 2, 4, 6, up to 64 duration is in the range 1 to 10 minutes ``` 例如,要测试典型的 AES67 配置,请运行: ``` ./run_test.sh S24_3LE 48000 2 5 ``` 测试执行以下操作: * 检查所有必需的可执行文件是否可用 * 停止正在运行的 daemon 实例并移除 ALSA RAVENNA/AES67 模块 * 编译 test 文件夹下的测试工具 * 验证输入参数,准备要播放的原始输入文件 *./test/test.raw* 以及 test 文件夹下的配置文件 * 停止 PulseAudio(如果已安装)。这会打开并占用 ALSA 播放和捕获设备,从而导致问题。请参阅 [PulseAudio](#notes)。 * 安装 ALSA RAVENNA/AES67 模块 * 在网络环回接口上启动 ptp4l 作为主时钟 * 启动 AES67 daemon,并根据测试目录中创建的状态文件创建一个 source 和一个 sink * 等待 Ravenna 驱动程序 PTP 从设备同步 * 在配置的 ALSA sink 上开始录制指定的时间段,并输出到原始文件 *./test/sink_test.raw* * 在配置的 ALSA source 上开始播放创建的测试文件 *./test/test.raw* * 等待录制和播放完成 * 检查录制的文件是否包含预期的音频样本序列 * 终止 ptp4l 和 AES67 daemon * 打印测试结果,结果可以是 *OK* 或 *failed at (location)* 如果测试结果为 OK,则意味着所选配置可以在你的平台上顺畅运行。 在搭载 Intel Celeron N4020 处理器的 _Mini PC_ 上成功测试了 64 声道配置。 在 _NanoPi NEO2 开发板_ 上成功测试了 24 声道配置。 如果测试报告失败,你可以尝试停止主机上运行的所有可能的额外负载,然后重试。 如果在此之后测试仍然系统性地失败,则意味着你无法在指定配置下实现良好的可靠性。 在这种情况下,你可以尝试在 daemon 配置文件中配置不同的驱动程序计时器基本滴答周期(*test/daemon.conf* 中的参数 *tic\_frame\_size\_at\_1fs*)。 默认情况下,此参数设置为 48(1ms 延迟),有效范围是从 48 到 480,步长为 48。 请注意,该参数的值越高(大于 48 的值)会导致更高的数据包处理延迟,这会破坏与某些设备的兼容性。 ## 运行平台延迟测试 平台延迟测试可用于测量在特定平台上可达到的最小端到端延迟。 该测试基于与平台兼容性测试相同的设置,其中 _Sink_ 被配置为接收来自 _Source_ 的音频样本, 两者均使用网络环回接口在同一设备上运行。 测试应用程序在 RAVENNA 播放设备上播放音频样本,并测量直到在 RAVENNA 捕获设备上接收到样本的时间。 测试设置和测得的端到端延迟如下图所示: ![image](https://static.pigsec.cn/wp-content/uploads/repos/cas/de/de681da89d0036a642b51f1c63e55fb5fdce12c3d996f9605cd0422df395da18.png) 此测试可以使用 [run\_latency\_test.sh](run_latency_test.sh) 脚本执行。请参阅[脚本说明](#notes)。 该脚本允许用户测试特定配置下的延迟,并可用于确保可以使用特定的 ALSA 缓冲区大小: ``` Usage run_latency_test.sh sample_format sample_rate channels duration frames sample_format can be one of S16_LE, S24_3LE, S32_LE sample_rate can be one of 44100, 48000, 88200, 96000, 192000, 384000 channels can be one of 2, 4, 6, up to 64 duration of the test in seconds frames buffer size in frames ``` 以帧为单位的指定缓冲区大小从 _tic_frame_size_at_1fs_ * 2(默认为 96)开始,步长为 _tic_frame_size_at_1fs_。 例如,要测试典型的 AES67 配置 1 分钟并使用 96 帧的缓冲区大小,请运行: ``` ./run_latency_test.sh S24_3LE 48000 2 60 96 ``` 如果测试期间没有发生欠载 错误,则可以使用请求的缓冲区大小,并在最后打印测得的端到端延迟: ``` Trying latency 96 frames, 2000.000us, 2.000000ms (500.0000Hz) Success Playback: *** frames = 480096 *** state : RUNNING trigger_time: 170.196886 tstamp : 0.000000 delay : 96 avail : 0 avail_max : 48 Capture: *** frames = 480000 *** state : RUNNING trigger_time: 170.196887 tstamp : 0.000000 delay : 0 avail : 0 avail_max : 48 Maximum read: 48 frames Maximum read latency: 1000.000us, 1.000000ms (1000.0000Hz) Playback time = 170.196886, Record time = 170.196887, diff = -1 End to end latency: 5.999 msecs Terminating processes ... daemon exiting with code: 0 ``` 之前的测试是在搭载 Ubuntu 发行版的 _NanoPi NEO2 开发板_ 上运行的。 在搭载 Intel Celeron N4020 处理器的 _Mini PC_ 上成功测试了 64 声道配置。 在 _NanoPi NEO2 开发板_ 上成功测试了 24 声道配置。 如果发生欠载,报告的状态将是: ``` state : XRUN ``` 并且无法使用指定的缓冲区大小。 **_重要提示_** 从 Linux 内核 5.10.x 起,需要更改某个内核参数来修复轮转调度器导致延迟测试失败的问题,请参阅[实时调度器限制](#notes)。 ## 运行 daemon 测试 要运行 daemon 测试,请使用以下命令安装 ALSA RAVENNA/AES67 内核模块: ``` sudo insmod 3rdparty/ravenna-alsa-lkm/driver/MergingRavennaALSA.ko ``` 使用以下命令设置内核参数: ``` sudo sysctl -w net/ipv4/igmp_max_memberships=66 ``` 确保没有 aes67-daemon 实例正在运行,进入 [tests](daemon/tests) 子目录并运行: ``` ./daemon-test -p ``` ## 说明 * 本仓库中的所有脚本均作为参考提供,以帮助设置系统和运行平台兼容性测试。 它们已从 **Ubuntu 18.04** 发行版开始进行了测试。 * 从 Linux 内核 5.10.x 起,需要更改某个内核参数来修复轮转调度器导致延迟测试失败的问题,请参阅 [issue 79](https://github.com/bondagit/aes67-linux-daemon/issues/96) 和 alsa-lib [issue-285](https://github.com/alsa-project/alsa-lib/issues/285)。 使用以下命令将所有实时任务可用的总带宽设置为 CPU 的 100%: sysctl -w kernel.sched_rt_runtime_us=1000000 默认情况下,此值设置为 95%。 * CPU 频率调节事件可能会对 daemon 流造成影响,导致几秒钟的意外失真,请参阅 [issue 96](https://github.com/bondagit/aes67-linux-daemon/issues/96)。 在运行 daemon 之前,请确保禁用 CPU 频率调节事件: 检查是否启用了 CPU 频率调节: cat /proc/sys/kernel/perf_cpu_time_max_percent 如果结果不为 0(通常设置为 25),请以下命令将其设置为 0: sudo sysctl -w kernel.perf_cpu_time_max_percent=0 你可能还需要查看当前的 CPU 频率调节策略(本例中为 cpu0): cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor 有关更多信息,请参阅 https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt。 * **PulseAudio** 可能会造成稳定性问题。 在运行 daemon 之前,请验证 PulseAudio 没有在运行: ps ax | grep pulseaudio 如果它正在运行,请尝试执行以下脚本来停止它: daemon/scripts/disable_pulseaudio.sh 如果在此之后进程仍然存在,请考虑以下两种解决方案之一,然后重新启动系统: * 使用以下命令将其完全卸载: sudo apt-get remove pulseaudio * 通过重命名可执行文件来禁用它: sudo mv /usr/bin/pulseaudio /usr/bin/_pulseaudio 其他禁用 PulseAudio 的方法可能会失败,仅仅杀死进程是不够的,因为它会立即重新生成。
标签:AES67, Bash脚本, PTP, RTP, WebUI, 守护进程, 网络音频, 请求拦截, 音视频流媒体