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