#信号处理 #数字信号处理 #PCM #窗口 #汉宁

无需std dasp_window

音频PCM数字信号处理的窗口函数抽象(例如汉宁、矩形)。

2个版本

0.11.1 2021年3月25日
0.11.0 2020年5月29日

#888音频

Download history 18138/week @ 2024-03-14 19152/week @ 2024-03-21 18384/week @ 2024-03-28 24187/week @ 2024-04-04 22839/week @ 2024-04-11 24298/week @ 2024-04-18 23854/week @ 2024-04-25 30190/week @ 2024-05-02 23855/week @ 2024-05-09 39099/week @ 2024-05-16 36315/week @ 2024-05-23 40037/week @ 2024-05-30 38658/week @ 2024-06-06 42495/week @ 2024-06-13 36820/week @ 2024-06-20 34241/week @ 2024-06-27

160,960 每月下载量
3 个Crates中使用 (直接使用2个)

MIT/Apache

6KB
57 代码行

dasp Actions状态 docs.rs

Rust中的数字音频信号处理。

以前是 sample crate

一套提供PCM(脉冲编码调制)数字信号处理基础功能的Crates。换句话说,dasp提供了一套低级、高性能的工具,包括用于处理数字音频信号的类型、特性和函数。

dasp库不需要 动态分配1 并且没有 依赖。目标是设计一个类似于 std 的库,但用于音频DSP;专注于便携和快速的基础。

1: 除了有时在将 Signal 树转换为有向无环图时有用的特性门控的 SignalBus 特性之外。

在此处找到 API文档

Crates

dasp 是一组模块化Crates的集合,允许用户选择他们项目所需的确切工具集。以下Crates包含在这个仓库中

链接 描述
dasp Crates.io docs.rs 顶级API,具有所有Crates的功能。
dasp_sample Crates.io docs.rs 样本特质、类型、转换和操作。
dasp_frame Crates.io docs.rs 帧特质、类型、转换和操作。
dasp_slice Crates.io docs.rs 样本/帧切片的转换和操作。
dasp_ring_buffer Crates.io docs.rs 简单的固定和有界环形缓冲区。
dasp_peak Crates.io docs.rs 使用半/全波整流器进行峰值检测。
dasp_rms Crates.io docs.rs 使用可配置窗口进行RMS检测。
dasp_envelope Crates.io docs.rs 使用峰值和RMS实现进行包络检测。
dasp_interpolate Crates.io docs.rs 帧间速率插值(线性、sinc等)。
dasp_window Crates.io docs.rs 窗口函数抽象(汉宁窗、矩形窗)。
dasp_signal Crates.io docs.rs 音频帧流的迭代器API。

deps-graph

红色虚线表示可选依赖,黑色线条表示必需依赖。

特性

使用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_wavepositive_half_wavenegative_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环境中执行sincospowf32等操作。这意味着这些crate需要nightly工具链才能在no_std环境中构建。

贡献

如果dasp缺少您希望拥有的类型、转换或其他基本功能,请随时提交问题或pull request!人多力量大 :)

许可证

以下任一许可证下授权:

任选其一。

贡献

除非您明确声明,否则根据Apache-2.0许可证定义,您有意提交以包含在工作中的任何贡献,将根据上述条款双授权,不附加任何额外条款或条件。

依赖

~41KB