1个不稳定版本
0.11.0 | 2020年5月29日 |
---|
在 音频 中排名第 868
每月下载量 151,984
用于 26 个库(直接使用13个)
29KB
442 行
dasp
Rust中的数字音频信号处理。
以前称为 sample
库。
一套库,提供了处理PCM(脉冲编码调制)数字信号处理(DSP)的基本工具。换句话说,dasp
提供了一套低级、高性能的工具,包括用于处理数字音频信号的类型、特性和函数。
dasp
库不需要 动态分配1 且没有 依赖关系。目标是设计一个类似于 std,但用于音频DSP 的库;保持对便携和快速基础的关注。
1: 除了偶尔有用的功能门控的 SignalBus
特性,该特性在将 Signal
树转换为有向无环图时偶尔有用。
在这里找到 API文档。
库
dasp 是一个模块化的库集合,允许用户选择他们项目所需的确切工具集。以下库包含在这个存储库中
库 | 链接 | 描述 |
---|---|---|
dasp |
包含所有库功能的顶级API。 | |
dasp_sample |
样本特质、类型、转换和操作。 | |
dasp_frame |
帧特质、类型、转换和操作。 | |
dasp_slice |
样本/帧切片的转换和操作。 | |
dasp_ring_buffer |
简单的固定和有界环形缓冲区。 | |
dasp_peak |
使用半/全正/负波整流器进行峰值检测。 | |
dasp_rms |
使用可配置窗口的RMS检测。 | |
dasp_envelope |
峰值和均方根实现的环境检测。 | |
dasp_interpolate |
帧间速率插值(线性、sinc等)。 | |
dasp_window |
窗口函数抽象(汉宁、矩形)。 | |
dasp_signal |
音频帧流迭代器API。 |
红色虚线表示可选依赖,而黑色线条表示必需依赖。
功能
使用Sample特质以性能敏感的方式在不同位深之间进行转换,并保持泛型。为所有有符号整数、无符号整数和浮点原语类型以及一些自定义类型(包括11、20、24和48位有符号和无符号未打包整数)提供了实现。例如
assert_eq!((-1.0).to_sample::<u8>(), 0);
assert_eq!(0.0.to_sample::<u8>(), 128);
assert_eq!(0i32.to_sample::<u32>(), 2_147_483_648);
assert_eq!(I24::new(0).unwrap(), Sample::from_sample(0.0));
assert_eq!(0.0, Sample::EQUILIBRIUM);
使用Frame特质以在特定时间点的通道数量上保持泛型。为长度最多为32个元素的固定大小数组提供了实现。
let foo = [0.1, 0.2, -0.1, -0.2];
let bar = foo.scale_amp(2.0);
assert_eq!(bar, [0.2, 0.4, -0.2, -0.4]);
assert_eq!(Mono::<f32>::EQUILIBRIUM, [0.0]);
assert_eq!(Stereo::<f32>::EQUILIBRIUM, [0.0, 0.0]);
assert_eq!(<[f32; 3]>::EQUILIBRIUM, [0.0, 0.0, 0.0]);
let foo = [0i16, 0];
let bar: [u8; 2] = foo.map(Sample::to_sample);
assert_eq!(bar, [128u8, 128]);
使用(由“signal”特性启用的)“Signal”特质来处理产生Frame
的无限迭代器类型。Signal提供了添加、缩放、偏移、乘法、裁剪、生成、监控和缓冲Frame
流的流的方法。使用Signal可以轻松、可读地创建丰富和复杂的DSP图,具有简单且熟悉的API。
// Clip to an amplitude of 0.9.
let frames = [[1.2, 0.8], [-0.7, -1.4]];
let clipped: Vec<_> = signal::from_iter(frames.iter().cloned()).clip_amp(0.9).take(2).collect();
assert_eq!(clipped, vec![[0.9, 0.8], [-0.7, -0.9]]);
// Add `a` with `b` and yield the result.
let a = [0.2, -0.6, 0.5];
let b = [0.2, 0.1, -0.8];
let a_signal = signal::from_iter(a.iter().cloned());
let b_signal = signal::from_iter(b.iter().cloned());
let added: Vec<f32> = a_signal.add_amp(b_signal).take(3).collect();
assert_eq!(added, vec![0.4, -0.5, -0.3]);
// Scale the playback rate by `0.5`.
let foo = [0.0, 1.0, 0.0, -1.0];
let mut source = signal::from_iter(foo.iter().cloned());
let a = source.next();
let b = source.next();
let interp = Linear::new(a, b);
let frames: Vec<_> = source.scale_hz(interp, 0.5).take(8).collect();
assert_eq!(&frames[..], &[0.0, 0.5, 1.0, 0.5, 0.0, -0.5, -1.0, -0.5][..]);
// Convert a signal to its RMS.
let signal = signal::rate(44_100.0).const_hz(440.0).sine();;
let ring_buffer = ring_buffer::Fixed::from([0.0; WINDOW_SIZE]);
let mut rms_signal = signal.rms(ring_buffer);
“signal”模块还提供了一系列“Signal”源类型,包括
FromIterator
FromInterleavedSamplesIterator
Equilibrium
(静默信号)Phase
Sine
Saw
Square
Noise
NoiseSimplex
Gen
(从Fn() -> F生成帧)GenMut
(从FnMut() -> F生成帧)
使用(通过“slice”特性启用的)“slice”模块函数处理Frame
的块。提供了转换函数,用于安全地在交错Sample
的切片和Frame
的切片之间进行转换,而无需任何分配。例如
let frames = &[[0.0, 0.5], [0.0, -0.5]][..];
let samples = slice::to_sample_slice(frames);
assert_eq!(samples, &[0.0, 0.5, 0.0, -0.5][..]);
let samples = &[0.0, 0.5, 0.0, -0.5][..];
let frames = slice::to_frame_slice(samples);
assert_eq!(frames, Some(&[[0.0, 0.5], [0.0, -0.5]][..]));
let samples = &[0.0, 0.5, 0.0][..];
let frames = slice::to_frame_slice(samples);
assert_eq!(frames, None::<&[[f32; 2]]>);
“signal::interpolate”模块提供了一个Converter
类型,用于转换和插值Signal
的速率。这可以用于样本率转换和播放速率乘法。《Converter》可以使用多种插值方法,库中提供了Floor、Linear和Sinc插值。
“ring_buffer”模块提供了通用的Fixed
和Bounded
环形缓冲区类型,都可以与拥有、借用、堆和分配的缓冲区一起使用。
“peak”模块可用于监控信号的峰值。提供的峰值整流器包括full_wave
、positive_half_wave
和negative_half_wave
。
“rms”模块提供了一个灵活的Rms
类型,可用于RMS(均方根)检测。任何Fixed
环形缓冲区都可以用作RMS检测的窗口。
“envelope”模块提供了一个Detector
类型(也称为Follower),可用于检测信号的包络。Detector
对检测类型泛型 - Rms
和Peak
检测都提供了。例如
let signal = signal::rate(4.0).const_hz(1.0).sine();
let attack = 1.0;
let release = 1.0;
let detector = envelope::Detector::peak(attack, release);
let mut envelope = signal.detect_envelope(detector);
assert_eq!(
envelope.take(4).collect::<Vec<_>>(),
vec![0.0, 0.6321205496788025, 0.23254416035257117, 0.7176687675647109]
);
no_std
所有crates都可以在有和无std库的情况下编译。默认情况下启用std库,但是可以通过--no-default-features
禁用。
要启用一个crate的所有功能而没有std库,可以使用--no-default-features --features "all-no-std"
。
请注意,一些crate需要启用core_intrinsics
功能才能在no_std
环境中执行诸如sin
、cos
和powf32
等操作。这意味着这些crate需要使用nightly工具链才能在no_std
环境中构建。
贡献
如果dasp缺少您希望拥有的类型、转换或其他基本功能,请随时提交问题或拉取请求!人多力量大 :)
许可协议
在以下任一许可协议下授权:
- Apache License,版本2.0,(LICENSE-APACHE或https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT许可证(LICENSE-MIT或http://opensource.org/licenses/MIT)
任您选择。
贡献
除非您明确说明,否则您根据Apache-2.0许可证定义的任何旨在包含在作品中的贡献,将按上述方式双许可,不附加任何额外条款或条件。