5个版本
0.1.4 | 2022年10月20日 |
---|---|
0.1.3 | 2021年12月3日 |
0.1.2 | 2021年11月30日 |
0.1.1 | 2021年11月30日 |
0.1.0 | 2021年11月30日 |
在音频类别中排名第392
被fluffl使用
120KB
3K SLoC
Adhoc Audio
纯Rust编写的音频压缩。它不链接到任何绑定,因此可以构建为wasm32-unknown-unknown。
这是什么?
这是我将拼凑在一起以压缩音频的音频编解码器的集合。我目前正在用它来
- 在客户端浏览器中压缩麦克风数据(使用此仓库编译为wasm)
- 将数据发送到服务器(POST请求多部分)
- 将压缩数据重新编码为标准格式(这里我将使用rust绑定到libavcodec或类似的东西)
目前,只有一个实际压缩音频的编解码器 AdhocCodec
和我编写的WAVE读取器/写入器实用工具 WavCodec
。
为什么?
在开发我正在编写的WASM应用程序期间,需要压缩从WEBAUDIO api接收的麦克风数据。需要一个纯Rust解决方案,以保持项目的构建步骤简单。据我所知,有一些纯Rust音频 解码器 用于VORBIS(lewton)、MP3(puremp3)等,但大多数这些crate不支持 编码。
性能
可能不是非常快,但我还没有真正测试过。编码/解码算法是O(N),因此应该足够快。如果无法满足我的速度要求,我一定会进行优化。`Vec`实现进行分配,因此应该有log(N)次分配。
压缩
压缩节省似乎在20%-70%之间,但我还没有进行广泛的测试以具体说明。然而,编解码器不是有损的,它在更高的“压缩级别”上对音频进行量化,以实现显著的存储空间节省。量化对音频质量的影响不大,我对这个发现感到非常惊讶。
编码示例
use adhoc_audio::{codec::Streamable, AdhocCodec, WavCodec};
use std::fs::File;
fn main() {
println!("compressing file example..");
//set up a buffer for reading/writing samples
let mut samples = [0.0; 1024];
//open wav file
let mut wav_reader = WavCodec::load(File::open("./resources/taunt.wav")
.unwrap()).unwrap();
let mut adhoc = AdhocCodec::new()
// level 0 means no quantization ,so its basically lossless at level 0
// levels 1-10 means quantization so compression is better but
// quality suffers (dithering is added to compensate)
.with_compression_level(7)
// AdhocCodec::with_info(.. ) MUST BE CALLED
// before calling encode/decode when you are
// creating a new instance of AdhocCodec
.with_info(wav_reader.info());
//'decode' wav stream bit-by-bit
//Note:in this case we are just reading PCM info
while let Some(samples_read) = wav_reader.decode(&mut samples) {
//encode wav data bit-by-bit
//memory is allocated as needed
adhoc.encode(&samples[0..samples_read]);
}
//write compressed audio back to disk
adhoc
.save_to(File::create("./resources/taunt.adhoc").unwrap())
.unwrap();
println!("taunt.adhoc written to: ./resources");
}
解码示例
use adhoc_audio::{codec::Streamable, AdhocCodec, WavCodec};
use std::fs::File;
fn main() {
println!("decompressing file from 'compress' example...");
//set up a buffer for reading/writing samples
let mut samples = [0.0; 1024];
//open wav file
let mut adhoc = AdhocCodec::load(
File::open("./resources/taunt.adhoc").expect("run example 'compress' before this one"),
)
.unwrap();
let mut wav_writer = WavCodec::new(adhoc.info());
//decode adhoc stream a chunk of samples at a time
while let Some(samples_read) = adhoc.decode(&mut samples) {
//encode wav data bit-by-bit
//memory is allocated as needed
wav_writer.encode(&samples[0..samples_read]);
}
//write compressed audio back to disk
wav_writer
.save_to(File::create("./resources/taunt_decompressed.wav").unwrap())
.unwrap();
println!("taunt.adhoc written to: ./resources");
}
命令行界面
此包有一个简单的命令行工具,用于在`.wav`和`.adhoc`格式之间转换。
在终端中,只需执行
cargo install --path .
要查看标志选项,请这样做
adhoc_audio -h
压缩
压缩WAV文件的最简单方法如下
adhoc_audio ./resources/taunt.wav
它将在当前目录创建一个taunt.codec
解压缩
构建第一个示例来解压缩taunt.codec
即可
adhoc_audio ./taunt.codec
解压缩后的WAV文件将被写入您的当前工作目录
依赖项
~0.6–1.7MB
~36K SLoC