teodly/inferno

GitHub: teodly/inferno

这是一个基于 Rust 的 Dante 协议非官方开源实现,旨在让 Linux 系统能够作为 Dante 音频设备进行网络音频收发。

Stars: 248 | Forks: 24

# - Dante 协议的非官方实现 [GitLab](https://gitlab.com/lumifaza/inferno) | [GitHub](https://github.com/teodly/inferno) | [主要作者网站](https://info.lumifaza.org/) 本项目以[一个地方](https://en.wikipedia.org/wiki/Inferno_(Dante)命名,那是为那些创建未公开文档的网络协议的人准备的归宿。 目前处于高度实验阶段。我不建议将其用于严肃用途。 不过,它破坏已经正常工作的 Dante 网络的可能性很低。 如果你知道自己在做什么,并且具备基本的 Linux 命令行经验,它完全可以用于非关键任务,例如听音乐、通过调音台播放多轨录音以进行混音练习、录制排练。 非常感谢 [Project Pendulum](https://github.com/pendulum-project)(由 [Trifecta Tech Foundation](https://trifectatech.org/)发起)创建和维护 [Statime](https://github.com/pendulum-project/statime),并在视听网络功能所需特性上的合作!如果没有它,音频传输的实现将会困难得多。 # 功能 * 从 Dante 设备和虚拟设备接收音频,以及向其发送音频 * 兼容 Dante Controller 和 [network-audio-controller](https://github.com/chris-ritsen/network-audio-controller)(`netaudio` 命令行工具)的大部分功能 ## 与其他 AoIP 虚拟声卡的比较 | | **Inferno** | [DVS](https://www.getdante.com/products/software-essentials/dante-virtual-soundcard) | [AES67 Linux daemon](https://github.com/bondagit/aes67-linux-daemon) | |---|---|---|---| | 成熟度 | ⏳ Alpha 阶段但已在生产环境使用 | ✅ 生产就绪 | ✅ 可能稳定 | | 平台 | Linux | Mac, Windows | Linux | | 支持的协议 | Dante | Dante | AES67 | | 直接支持的音频后端 | ALSA | CoreAudio, ASIO, WDM | ALSA | | 与 DAW 兼容 | 💣 实验性 | ✅ 是 | ✅ 是 | | 使用 Dante Controller 跳线盘路由音频 | ✅ 是! | ✅ 是 | 🚫 仅限 AES67->Dante | | 使用 Dante Controller 配置 | ⏳ 部分支持(通道名称,TX 组播) | ✅ 是 | 🚫 否 | | 与 Dante Domain Manager 兼容 | 🚫 否 | ✅ 是 | 🚫 否(但可能进行 AES67 集成) | | 支持的时钟协议 | [PTPv1](https://github.com/teodly/statime/tree/inferno-dev) ☑️, PTPv2 ☑️ | PTPv1 ✅ | PTPv2 ✅ | | 时钟主控 | PTPv2 ☑️ 通过 [Statime](https://github.com/pendulum-project/statime) | 🚫 否(但在 Dante Via 中可能) | ☑️ 通过外部守护进程 | * 从现代 Dante 硬件流式传输音频 | ✅ 是 | ✅ 是 | ✅ 是 | * 从/向 DVS、Dante Via 和旧版 Dante 硬件流式传输音频 | ✅ 是 | ✅ 是 | 🚫 否 | * 从/向 AES67 流式传输音频 | 🚫 否 | 🚫 否 | ✅ 是 | | 最低延迟 | 取决于你的内核 | 4ms | ... | | 发送和接收组播 | ✅ 是 | ✅ 是 | ✅ 是 | | 操作系统集成 | 完全用户态 | 内核驱动和用户态服务 | 内核驱动和用户态辅助程序 | | 轻量级录音应用 | ✅ 是 (Inferno2pipe) | 🚫 否 | ☑️ FFmpeg 配合 RTP 输入即可实现 | | 磁盘空间和 RAM 占用 | 🌱 低 (~12MB RAM) | 🔥 高 | 🌱 低 | | 编写语言 | Rust | C++, Java | C++, C | | 许可证 | 🥰 FOSS, copyleft | 🔒 闭源 | 🥰 FOSS, copyleft | | [DRM](https://drm.info/what-is-drm.en.html) | 😊 无 | 🔒 需要激活,禁止虚拟机 | 😊 无 | | 价格 | 免费 | 🤑 50-80 美元 ... *仅用于一个 **设备驱动程序*** | 免费 | | 隐私 | 😊 无跟踪 | 😡 需要注册,默认启用遥测 | 😊 无跟踪 | * ✅ - 可用 * 💣 - 实验性 * ☑️ - 不是本软件的一部分,但集成很容易实现 * ⏳ - 即将实现(大概在 2025-06 之前) * 🚫 - 未实现且近期无计划 ## 怪癖,使用前请阅读: * Dante 协议没有公开文档。所有内容都是通过逆向工程得出的,或者基于其他逆向工程项目。实现中的某些内容是猜测的。因此,虽然它在我的设置中有效,但在你的设置上可能无效。 * 注意到与 NTP 时钟同步存在冲突。内置时钟过滤器不够用。[正确修复它很复杂。](https://github.com/pendulum-project/statime/issues/389#issuecomment-2214559362) 如果你的网络接口支持硬件时间戳,你可以通过将 `/dev/ptp0` 用作 [`CLOCK_PATH`](#configuration) 并使用[不使用全局系统时钟的 PTP 守护进程](https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/AES67#setting-up-ptp-time-sync) 来变通解决,但你需要在一台 Dante 设备上启用 PTPv2 (AES67),因为 ptp4l 与 PTPv1 不兼容。 * 要在 Statime 中修复此问题,需要为硬件时间戳实现 [PHC-only 模式](https://github.com/pendulum-project/statime/issues/517),为软件时间戳实现 [基于 CLOCK_MONOTONIC 且具有任意时间刻度的虚拟时钟](https://github.com/pendulum-project/statime/issues/389) * Inferno2pipe 由传入的媒体流计时。当未连接任何内容时,“时间将停止”(即录音将暂停),直到再次连接某些内容——除非至少连接了一个通道,否则不会生成静音。 # 快速开始 1. [安装 Rust](https://rustup.rs/) 2. 如果使用防火墙,请打开 UDP 端口:4455, 8700, 4400, 8800(如果指定了 [`INFERNO_ALT_PORT`](#environment-variables),则为其他端口),5353。此外,允许来自可能的发送方的传入 UDP 流量(端口号由操作系统分配,因此无法预先知道) 3. 确保 seccomp、SELinux 或其他内核级安全机制没有阻止与时钟相关的系统调用。例如,如果你想将 `alsa_pcm_inferno` 与 PipeWire 一起使用,并且 PipeWire 服务由 systemd 管理,请将 [`os_integration/systemd_allow_clock.conf`](os_integration/systemd_allow_clock.conf) 复制到 `$HOME/.config/systemd/user/pipewire.service.d/override.conf`(或者,如果已存在,则追加到其中) 4. 如果想使用 Inferno2pipe 以外的任何东西, 需要时钟同步守护进程。Inferno 与修改版的 [Statime](https://github.com/pendulum-project/statime) 兼容: * 目前,即使只是捕获音频,也总是需要 Statime,但这并非设计使然,将会修复 * `git clone --recurse-submodules -b inferno-dev https://github.com/teodly/statime` * `cd statime && cargo build` * 在 `inferno-ptpv1.toml` 中调整网络接口 * `sudo target/debug/statime -c inferno-ptpv1.toml` * 在使用 Inferno 期间禁用全局系统时间同步(`systemctl stop chronyd.service`) * 实验性时钟保护已添加到我们的 Inferno 分支中,所以如果你很勇敢,可以跳过它。 5. 使用 `--recursive` 选项克隆此仓库(某些依赖项在子模块中) 6. `cd` 到所需的程序/库目录 * 简单的命令行音频录音机:[`Inferno2pipe`](inferno2pipe/README.md) * 用于 ALSA 的虚拟声卡:[`alsa_pcm_inferno`](alsa_pcm_inferno/README.md) - 也可以与 PipeWire 一起使用,应该可以与 JACK 一起使用(尚未测试) 7. 如果使用 `alsa_pcm_inferno`,请安装 alsa 开发库。 * 在 Debian/Ubuntu/Mint 上:`sudo apt install libasound2-dev` * 在 Arch 上:`pacman -S alsa-lib` * 在 Fedora/Centos 上:`dnf install alsa-lib-devel` 8. `cargo build` 9. 按照特定程序/库的 README 中的说明进行操作 ## 交叉编译 如果你想在 Raspberry Pi 或其他单板计算机上使用 Inferno,通常在台式机/服务器/笔记本电脑(*主机*)上编译并将生成的二进制文件复制到*目标设备*会更快。此外,你不会耗尽 SD 卡空间或 RAM。 幸运的是,有一个**实际上零配置**的工具可以做到这一点:[`cross`](https://crates.io/crates/cross)。安装它,然后代替执行 `cargo build`,执行: ``` cross build --release --target=aarch64-unknown-linux-gnu ``` 你将在 `target/aarch64-unknown-linux-gnu/release` 中找到编译好的二进制文件。 目前,目标系统上唯一需要的依赖项是 ALSA 库(如果使用 `alsa_pcm_inferno`)。其他所有内容都存储在二进制文件中。 不需要在主机系统上安装依赖项——`cross` 会根据 `Cargo.toml` 中的说明在其容器内安装它们。 如果你需要为不同的架构进行编译,请在运行 `cross` 之前将其添加到 `Cargo.toml`(复制粘贴 `workspace.metadata.cross.target` 部分)。这仅对 `alsa_pcm_inferno` 是必需的。Statime 没有任何共享库依赖项。 ## 你更喜欢 Docker 吗? 这不适用于通常的桌面系统使用,但如果你正在使用 ALSA 将音频应用程序打包到 Docker 容器中,我们已经为你准备好了!请参阅 `test/containerized_trx` 目录以获取灵感。 请记住: * 时钟同步仍然是你的责任。我不想用服务管理使基础镜像复杂化,因此未包含 PTP 守护进程。`usrvclock-rs` 要求所有容器的套接字路径(包括客户端套接字)相同,因此需要为 `/tmp` 设置共享卷。未来版本可能会将 Statime 作为单独的容器包含在内。 * Dante 协议需要良好的计时。允许实时优先级。 * 网络路由(包括组播)可能很难正确配置,但 `--network=host` 是你的朋友。或者将容器与你的 AoIP 网络桥接。NAT 是你的敌人。 * 要保持状态持久化,请将 `/root/.local/state/inferno_aoip` 挂载为卷(如果你的应用程序不以 root 身份运行,则为不同用户的卷) # 法律和道德事项 免责声明:Dante 使用 Audinate 拥有专利的技术。此源代码也可能使用这些专利。如果你想: * 靠它赚钱 * 在(或从)适用软件专利的地区分发二进制文件 请咨询律师。 本项目不声称已获得 Audinate 的授权或批准。 请不要使用本项目来制作假冒的 Dante 设备/软件,这是不道德且非法的(而 Audinate 的做法仅仅是不道德)。请始终说明该实现是非官方的,且未得到 Audinate 的认可。也许你可以在法律上声称它与 Dante 协议的子集兼容,但我不是律师。 ## 许可证 本项目在 GPLv3-or-later 和 AGPLv3-or-later 下双重许可。你可以选择使用哪种许可证,或者保留两者。例如: * 如果你想将其集成到已经获得 GPL 许可的项目中,你有权这样做。 * 如果你想将其分叉到在云中运行的东西(或通常在公共 Internet 上),使用 AGPL 并在分叉时**移除** GPL 将对自由软件社区有益。 # 已测试 ## Dante 设备 * Audinate AVIO * AVIO-AES3 * AVIO-DAI2 * AVIO-DIOUSBC * Ben & Fellows 523019 4x4 平衡模拟 I/O 模块(基于 Dante UltimoX4) * MUSIC Group * Klark Teknik DN32-DANTE(在 Behringer X32 中)(基于 Dante Brooklyn II) * Behringer Aoip-Dante(在 Behringer Wing-Rack 中)(基于 Dante Brooklyn III) * Orban Optimod 5750(基于 Dante Broadway) * Soundcraft * Vi2000 * Vi3000 * Allen&Heath * SQ-5 * SQ-6 * Qu-5D * Yamaha Dante-MY16-AUD(在 Yamaha LS9 中)(也测试了旧的 3.x Dante 固件版本) * ESI planet 22c * Dante Via @ OS X 和 Windows 11 * Dante Virtual Soundcard @ Windows 10 ## 控制软件 * Dante Controller @ Windows 10, 11 * network-audio-controller ## 主机 * x86_64 Linux * Arch * Ubuntu * Fedora * aarch64 (ARM 64-bit) Linux * Raspberry Pi 5 - Raspberry Pi OS & Armbian Bookworm * Raspberry Pi 4(无硬件 PTP)- Raspberry Pi OS Lite (64bit) * Raspberry Pi Zero 2 W(带 USB 以太网)- Raspberry Pi OS Lite (bit) - 注意构建时间很长 # 仓库结构 * `inferno_aoip` - 用于模拟 Dante 音频 over IP 设备的主要库 crate。将来还将实现控制器功能。**如果你想基于 Inferno 开发应用程序,请从这里开始**。 * `inferno2pipe` - 捕获音频,将交错的 32 位整数样本写入 Unix 命名管道(或原始文件)。还提供了用于录制为更方便格式的辅助脚本。**如果你想使用 Inferno 捕获音频而无需设置整个音频堆栈,请从这里开始** * `alsa_pcm_inferno` - 用于 ALSA 的虚拟声卡。**如果你曾经梦想过 Linux 版的 Dante Virtual Soundcard,请从这里开始** * `searchfire` - [Searchlight](https://github.com/WilliamVenner/searchlight) mDNS crate 的分支,经过修改以与 Dante 的 mDNS 兼容 # 时钟选项 ## 软件时间戳 这是默认选项,与所有 NIC(网卡)和 Dante 设备兼容。它需要[我们的分支或 Statime 守护进程](https://github.com/teodly/statime/tree/inferno-dev)。 在 `inferno-ptpv1.toml` 配置文件中更改网络接口,并使用以下命令运行守护进程: ``` sudo target/debug/statime -c inferno-ptpv1.toml ``` 如果你想要额外的稳定性,请禁用时间同步,通常以下命令之一就足够了: ``` sudo systemctl stop chronyd.service sudo systemctl stop systemd-timesyncd.service sudo systemctl stop ntpd.service ``` 如果 `virtual-system-clock-base` 设置为 `monotonic` 或任何以 `monotonic` 开头的值,这应该不再需要,但此修复/变通方法非常新,所以请小心。 如果你配置了足够高的 `TX_LATENCY_NS` 和 `RX_LATENCY_NS`(TODO:多高才算足够?),你可以尝试使用 `monotonic_coarse`,这应该会减少 CPU 负载。 你可以在 Statime 配置中将协议从 PTPv1 更改为 PTPv2——这允许主控操作(目前仅针对 PTPv2 实现),因此即使网络中没有物理 Dante 设备,也可以使用 Inferno。但是,网络中必须至少存在一台启用了 AES67 的 Dante 设备,才能使 Inferno 和 Dante 设备互操作。 ## 硬件时间戳 如果你的网卡支持硬件时间戳(使用 `ethtool -T` 检查),你可以直接使用其时钟,而无需依赖系统时钟。它比软件时间戳更准确,这意味着你可能会使用更低的音频延迟。 将 Inferno 的配置选项 `CLOCK_PATH` 设置为 PTP 时钟设备路径,通常是 `/dev/ptp0`。 如果你需要 PTPv1(不带 AES67 的 Dante),你需要使用我们的 Statime 分支,因为没有其他开源 PTPv1 守护进程。在 `inferno-ptpv1.toml` 中,将 `hardware-clock` 选项设置为 `auto` 并启动守护进程: ``` sudo target/debug/statime -c inferno-ptpv1.toml ``` 如果你能接受 PTPv2,你可以使用不同的 PTP 实现,例如 [linuxptp](https://www.linuxptp.org/): ``` sudo ptp4l -i enp0s31f6 -p /dev/ptp0 -l6 -E -H -s -m -4 --priority1 255 --priority2 255 --domainNumber 0 --freq_est_interval=7 --delay_filter_length=240 --dscp_event 46 ``` 或 [未修补(上游)Statime](https://github.com/pendulum-project/statime)。 使用 Statime 和 ptp4l 时,音频数据包延迟抖动相似,但 DC 中的时钟直方图显示,从长远来看 ptp4l 的变化更剧烈,而 Statime 在启动期间几秒钟内不稳定。 请注意,Inferno 非常频繁地查询时钟,这可能会比使用系统时钟给 CPU 带来更大的负载。如果你想避免这种情况,但仍然获得硬件时间戳的一些好处,请在 Statime 配置中指定 `hardware-clock`,但保持 Inferno 的 `CLOCK_PATH` 未设置。此外,请阅读[软件时间戳](#software-timestamping)部分。 # 配置 可以通过以下方式设置配置: * 环境变量 - 在设置名称前添加 `INFERNO_` 前缀 * ALSA 插件配置 - 建议在你的 `asoundrc` 中指定它们,因为过长的 ALSA 设备字符串可能会被截断(发生在 PipeWire 中,不确定其他应用程序) ## 设置 所有设置都有默认值。在简单的设置中,你应该能够在不指定任何参数的情况下启动。 * `BIND_IP` - 绑定到哪个本地 IP。如果你有多个网络接口,可能需要指定它。或者,可以指定网络接口名称,在这种情况下,将使用属于该接口的第一个地址。 * `DEVICE_ID` - 用作设备 ID 的 16 位十六进制数字(8 字节)。Dante 设备通常使用用零填充的 MAC 地址。Inferno 默认使用 `00000000`。设备 ID 是保存状态时的存储键。 * `NAME` - 广告设备的名称。如果未指定,将根据应用程序名称和 IP 地址生成名称。可能会在将来的版本中删除,当它可以从 DC 设置并因此存储在配置文件中时。 * `SAMPLE_RATE` - 此设备将运行的采样率 * `PROCESS_ID` - 0 到 65535 之间的整数。在单个 IP 地址上启动多个实例时必须提供且唯一。指定不同的 `DEVICE_ID` 是不够的。 * `ALT_PORT` - 套接字侦听器使用的 UDP 端口范围的开始。如果未指定,将使用硬件设备中看到的标准 Dante 端口。在单个 IP 地址上启动多个实例时必须提供。目前使用 4 个端口(`ALT_PORT` 到 `ALT_PORT+3`),但这将来可能会改变,所以最好将不同的实例至少分开 10 个端口。 * `RX_CHANNELS` - 接收通道数,默认为 2,如果应用程序支持更改通道数,将被覆盖。 * `TX_CHANNELS` - 发送通道数,默认为 2,如果应用程序支持更改通道数,将被覆盖。 * `RX_LATENCY_NS` - 以纳秒为单位的接收延迟,即相对于 PTP 媒体时钟等待媒体数据包的时间。相当于 Dante Controller 中的延迟设置。默认为 10ms。可能会在将来的版本中删除,当它可以从 DC 设置并因此存储在配置文件中时。 * `TX_LATENCY_NS` - 以纳秒为单位的发送延迟,即此设备将从我们接收的设备要求的接收延迟。相当于 Dante Virtual Soundcard 中的延迟设置。默认为 10ms。 * `CLOCK_PATH` - [usrvclock](https://gitlab.com/lumifaza/usrvclock) 套接字或 PTP 设备的路径。如果是后者,请确保[你被允许](https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/78642cc53bd84c2ad529f2175cc50a658d1e52c0/src/daemon/90-pipewire-aes67-ptp.rules) 读取它。此外,如果你想查看 DC 中的实际频率偏移,则需要写入权限。(时钟从未在 Inferno 内部调整,但读取频率的系统调用需要写入访问权限) # 音频稳定性提示 ## 设置适当的延迟 禁用 Inferno。运行 cyclictest 至少 20 分钟,同时执行你通常在计算机上执行的操作: ``` cyclictest --mlockall --smp --priority=80 --interval=5000 --distance=0 ``` 你还可以添加一些人工系统负载: ``` stress -m `nproc` -c `nproc` ``` 在 cyclictest 输出中,最后一列是以微秒为单位的最坏情况延迟。将其乘以 1000,加上一些余量和网络传输时间,你就得到了 `TX_LATENCY_NS` 和 `RX_LATENCY_NS` 的最低安全值。如果这些值高于你可接受的延迟,你将很难使用 Inferno(以及一般的计算机音频)。还要记住,Dante 官方允许的最大延迟是 40ms。你可以尝试遵循教程使延迟更可预测: * [Professional audio @ Arch wiki](https://wiki.archlinux.org/title/Professional_audio)(不仅限于 Arch) * [Performance tuning @ PipeWire wiki](https://wiki.archlinux.org/title/Professional_audio) * [Fedora Pipewire Low Latency Audio Configuration Reference Guide](https://linuxmusicians.com/viewtopic.php?t=27121)(特定于 Fedora) * 使用 `isolcpus` [或 `cset`](https://unix.stackexchange.com/a/692558) 隔离 CPU 内核,并将音频进程和网卡 IRQ 固定到隔离的内核 * 如果没有其他帮助,请尝试 `PREEMPT_RT` 内核 ## 依赖项 本项目依赖于 Statime([上游](https://github.com/pendulum-project/statime),[我们的分支](https://github.com/teodly/statime/tree/inferno-dev)),所以如果你想提供帮助,也请查看它的 TODO 列表!最重要的是: * [PTPv1 支持](https://github.com/pendulum-project/statime/pull/602) - 从机已经工作但尚未上游 * [PHC-only 模式](https://github.com/pendulum-project/statime/issues/517)(用于硬件时间戳) * [任意时间刻度的独立时钟](https://github.com/pendulum-project/statime/issues/389)(用于软件时间戳)- 已经有点工作了,但由于 Linux 使用 CLOCK_REALTIME 进行软件时间戳而不稳定,并且尚未完全上游 # 更新日志 ## 0.5.0 * 与 JACK 一起工作,应该可以与任何使用声卡作为中断源的应用程序一起工作 * 引入了自动化集成测试,该测试启动多个实例,在它们之间流式传输音频数据并检查其正确性(包括音频比较)。目前测试 JACK、PipeWire、aplay、arecord 与 alsa_pcm_inferno。计划支持 SoX 和 Inferno2pipe。 * Dockerfile * 修复 CPU 锁定预防代码中的逻辑错误 ## 0.4.3 * 支持单调时钟作为基础,并带有防跳变保护(Statime) * 减少 CPU 过载时的滚雪球效应,发送器滞后并尝试一次传输多个数据包:最大滞后设置为 `TX_LATENCY_NS`,如果发送线程锁定超过 5ms,将强制休眠 2ms ## 0.4.2 * 优化:从环形缓冲区索引计算中删除模除法 ## 0.4.1 * 暂时禁用 SafeClock,没有太大帮助并且会损害 PHC * 修复在可以每个流发送大量通道的设备(例如 Behringer Wing)上的恐慌 ## 0.4.0 * 重构 - 为引入控制器功能做准备 * 组播发送器 ## 0.3.3 * 修复在路由表中没有默认路由的情况下启动(Searchfire) ## 0.3.2 * 可更改的 RX 和 TX 通道名称 * RX 和 TX 延迟可通过环境变量或 ALSA 插件参数配置 * 重新许可为 GPL-or-AGPL,以简化分叉到 AGPL 项目,因为本项目的某些部分在云应用程序中可能有用 ## 0.3.1 * 从 ALSA 插件参数读取配置 - 对于 PipeWire 中的多个源和接收器很有用 * 发送统计信息(时钟、延迟、信号电平) * 可更改的 usrvclock 路径 ## 0.3.0 * 引入了 ALSA PCM 插件 - 与大多数 Linux 音频应用程序兼容的虚拟声卡 * 使用记录的协议接收时钟:[usrvclock](https://gitlab.com/lumifaza/usrvclock) * 各种内部更改,主要与允许使用外部缓冲区(ALSA 插件中的 mmap 模式所需)有关 * 接收组播 * 能够使用非默认网络端口以允许在单个 IP 地址上运行多个实例 * 删除了 Inferno Wired,因为 ALSA 插件与 PipeWire 配合良好。对于好奇的人来说,[这是最后一个版本](https://gitlab.com/lumifaza/inferno/-/blob/3941765700696f545425a5479be25091fda514d4/inferno_wired/src/main.rs)。 ## 0.2.0 * 音频发送器 * Inferno Wired 的 Alpha 版本 - 用于 PipeWire 的虚拟音频源和接收器 * 从为 PTPv1 和虚拟时钟支持而修改的 [Statime](https://github.com/teodly/statime) 接收时钟 - 目前仅限 Linux(因为 CLOCK_TAI 仅限 Linux) * 提高接收线程优先级以减少操作系统 UDP 输入队列溢出的可能性 ## 0.1.0 初始版本 # 待办事项 可能会按它们将被实现的顺序排列 * 能够在 Dante Controller 中更改设置 此时,Inferno 将大致成为 Dante Virtual Soundcard 的替代品。 * 可配置的实时线程优先级 * 在 DC 中报告迟到的数据包 * 在没有 PTP 守护进程的情况下以较低的时钟精度运行 - 对于 Linux 以外的操作系统有用 * 从文本文件读取配置 * 能够作为时钟源工作(PTPv1 主控)- Statime * 如果你使用 PTPv2,这已经是可能的——理论上你应该能够建立仅 Inferno 的 AoIP 网络——尚未测试 * 向集成测试添加更多应用程序和 Linux 发行版 * 完美发送器(内部始终使用 32 位整数;16 位和 24 位输出的 TX 抖动可通过 `TX_SOURCE_BIT_DEPTH` 配置) * 命令行助手 / TUI / GUI * 安装程序脚本,支持交叉编译 * 对网络数据包序列化器和反序列化器进行更多重构,以便在即将推出的控制器应用程序中重用更多代码(因为 DC 臃肿且是闭源的,用户体验很差) * AES67 * 主网络和辅助网络支持,适用于双网卡计算机 * API:无需重启设备服务器即可更改通道数(对于类似 Dante Via 的操作很有用,其中发送器和接收器可以动态添加和删除) * 并不是真正需要复制 Via 的功能,因为现在支持在单个 IP 地址上运行多个 Inferno 实例 * `grep -r TODO inferno_aoip/src` # 设计 * 99% 安全的 Rust(unsafe 是必需的,因为 ALSA 插件 API 没有安全的 Rust 绑定) * 不需要外部库,依赖项是 Rust crates # 动机 多年来,我一直使用自由(言论自由意义上的)开源软件。我也着迷于音乐与技术之间的联系。有一天,我的音响工程师同事向我展示了 Dante 的工作原理,它是多么易于使用并且(大多数时候)稳定。问题在于它不是一个开放标准,没有开源实现,而且我无法在我最喜欢的操作系统——Linux 上使用它。现在我可以了。 ## 为什么不使用 AES67? * AES67 只是媒体传输的标准,而不是控制标准,因此需要手动建立流。NMOS 可以解决这个问题,但我怀疑 Audinate 会在合理的未来实现它。 以下是 Dante 中 AES67 实现的限制,而不是一般的 AES67: * Dante Virtual Soundcard 和 Dante Via 不支持它 * 一些较旧的 Dante 设备(没有固件升级)也不支持它 * 它仅支持组播 * 采样率锁定为 48kHz # 其他与 Dante 相关的开源项目 * [network-audio-controller](https://github.com/chris-ritsen/network-audio-controller) - 命令行连接和设备控制器,Dante Controller 的替代品 * [companion-module-audinate-dantecontroller](https://github.com/bitfocus/companion-module-audinate-dantecontroller) - 用于控制 Dante 设备的 Bitfocus Companion 模块 * [inferno_runners](https://github.com/maze42d/inferno_runners) - 用于运行 Inferno 的脚本,带有基于 PipeWire 的声卡间桥接和 [USB audio gadget](https://www.diyaudio.com/community/threads/linux-usb-audio-gadget-rpi4-otg.342070/) * [dante-aes67-relay.js](https://gist.github.com/philhartung/87d336a3c432e2ce5452befcad1b945f) - 将 Dante 组播流中继到 AES67 * [wycliffe](https://github.com/jsharkey/wycliffe),包含在视频控制软件中的接收器实现——逆向工程 Dante 的最早公开尝试 * [AES67 音频资源列表](https://aes67.app/resources) 位于 [AES67 Stream Monitor](https://aes67.app/) 网站(Dante 与 AES67 兼容,但并非在所有设备上,并且需要手动配置) ## 替代方案 据我所知,没有其他与 Dante 兼容的音频传输非官方实现。但是,如果 AES67 适合你的用例,你可能想要使用: * [AES67 Linux daemon](https://github.com/bondagit/aes67-linux-daemon) 配合内核级虚拟声卡 * [pipewire-aes67](https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/AES67) * [aes67-recorder](https://github.com/voc/aes67-recorder)([与 Dante 一起使用的教程](https://behringer.world/viewtopic.php?t=197)) * AES67 也可以由任何支持 RTP 数据包中原始音频的软件接收,例如 FFmpeg 或 GStreamer。 * ... Dante 组播同样简单……只需在每个 UDP 数据包的前面切掉 9 个字节 ;)
标签:ALSA, AoIP, Dante 协议, DNS解析, PTP, Statime, 云资产清单, 内核驱动, 可视化界面, 媒体传输, 开源项目, 录音, 现场扩声, 网络协议, 网络音频, 虚拟声卡, 请求拦截, 逆向工程, 通知系统, 非官方实现, 音频, 音频 over IP, 音频制作, 音频发送, 音频接收