5 个版本 (3 个重大更新)
0.4.0 | 2024年2月6日 |
---|---|
0.3.0 | 2022年10月17日 |
0.2.0 | 2022年10月16日 |
0.1.1 | 2022年2月4日 |
0.1.0 | 2022年2月4日 |
#113 在 音频
每月下载 34 次
100KB
2.5K SLoC
Rocoder
用 Rust 编写的可实时编码的相位声码器。
Rocoder 是一个数字乐器命令行程序,通过放慢或加速音频并应用可实时编码的频率核来转换音频。它可以
- 改变音频速度
- 音调转换(尽管只沿谐波和亚谐波进行)
- 将任意代码转换应用于频域音频表示(仅限 Mac 和 Linux)
- 实时编译和重新加载转换代码
- 读取和写入音频文件
- 直接音频输入和播放
安装
- 如果您还没有,请在 https://rustup.rs/ 安装 Rust 工具链
- 通过运行
cargo install rocoder
来安装此工具 - 运行
rocoder -h
开始使用!
工作原理
rocoder 是一个相当简单的,可能并不完全正确的 相位声码器。它使用 3 个步骤处理音频,了解基础知识对于高级使用是必要的,特别是与频率核一起工作。
- 分析:输入音频在重叠的 汉宁窗口 中使用 FFT 分析。每个窗口分析发出其音频窗口的频域表示,编码为复数缓冲区。
- 处理:如果提供了频率核,则将每个频域窗口缓冲区传递给它进行任意代码定义的处理。
- 再合成:然后将处理过的频域缓冲区传递给逆 FFT 以进行再合成。再合成以允许音高转换和速度变化的方式进行。
使用方法
rocoder 使用一系列命令行参数进行控制。运行 rocoder -h
以列出它们。
-r
, --record
从默认音频输入设备获取音频输入。设置后,rocoder 将开始记录输入,直到您按下 Enter 键。它将自动尝试修剪音频的开始/结束部分,以去除静音。
--rotate-channels
将输入音频通道旋转 1 次。对于立体声输入,这将交换左右通道。
-a
, --amplitude
<amplitude>
输出振幅乘数。默认为 1
;
-b
, --buffer
<buffer-dur>
处理音频的最大持续时间。这主要用于您想更改实时代码更改的响应时间时。值以秒为单位指定,例如,-b 1.5
表示 1.5 秒。
-d
, --duration
<duration>
从输入源读取的音频量,如果提供了起始时间,则从起始时间开始。指定为持续时间字符串 hh:mm:ss.ss
,较大的部分可以省略,例如,1:0:0
表示 1 小时,1:30
表示 90 秒,1.5
表示 1.5 秒。
-f
, --factor
<factor>
拉伸因子;例如,5 表示减速 5 倍,0.2 表示加速 5 倍。默认为 1
(无速度变化)。
-x
, --fade
<fade>
应用于输出音频的淡入/淡出持续时间。有关指定格式,请参阅 --duration
。默认为 1
(1 秒)。
--freq-kernel
<freq-kernel>
rust 频率内核的路径。
-
, --input
<input>
要从中读取音频文件的路径。目前支持 .wav
(8、16、24、32 位整数和 32 位浮点格式)和 .mp3
。
-
, --output
<output>
音频输出文件的路径。如果设置,则不会将输出播放到设备;相反,rocoder 将尽可能快地运行并将输出持久化到磁盘。
此功能仅支持以32位浮点格式输出的 .wav
。
由于实现方式有缺陷,需要将整个输出文件放入内存中才能写入磁盘。
-p
、--pitch-multiple
<pitch-multiple>
非零整数音高倍数。大于1的正数用于音高移位,沿着谐波系列,而小于-1的负数用于沿着次谐波系列移位。
arg | result |
---|---|
1 |
无音高移位 |
2 |
升八度 |
3 |
升八度和五度 |
4 |
升两八度 |
5 |
升两八度和纯五度 |
-1 |
无音高移位 |
-2 |
降八度 |
-3 |
降八度和五度 |
0 |
[无效] |
默认为 1
(无音高移位)。
-s
、--start
<start>
输入音频中的起始时间。(关于参数格式,请参阅 --duration
)
-w
、--window
<window-len>
处理窗口的大小。小值会导致失真,而大值会导致模糊。推荐使用2的幂次以获得最佳性能。默认为 16384
。
现场编码
频率核仅在Mac和Linux上受支持。欢迎为支持Windows做出贡献。
频率核在重新合成之前修改频域数据,允许你对声音进行非常强大的转换。内核定义在Rust文件中,必须符合以下签名
#[no_mangle]
pub fn apply(elapsed_ms: usize, input: Vec<(f32, f32)>) -> Vec<(f32, f32)> {
todo!() // Your code here
}
需要 no_mangle
指令和 apply
名称。
输入是表示给定音频窗口频域的复数缓冲区。默认情况下,窗口长度约为16k个样本。函数的输出是输入的转换副本。
以下是一个简单的内核,它简单地通过乘以一个常数来增加输入音频的幅度
#[no_mangle]
pub fn apply(elapsed_ms: usize, input: Vec<(f32, f32)>) -> Vec<(f32, f32)> {
return input
.iter()
.map(|(real, im)| (real * 2.0, im * 2.0))
.collect();
}
如果将其保存到文件 kernel.rs
中,它可以与以下内容一起使用
cargo run --release -- \
-r -f 1 --freq-kernel path/to/kernel.rs
当rocoder正在运行并播放音频(不写入文件)时,它将监视此文件的变化,并自动在飞行中编译和热交换到进程。只需编辑文件并保存到你的内核中的现场代码即可!
库
此工具的各种功能都在crate库中公开,但此API目前尚未文档化且非常不稳定。
致谢
相位声码器算法的基本实现已从Paulstretch改编。
依赖关系
约10-41MB
约655K SLoC