#filter #quad #state #unit #processing #surge #buffer

nightly surge-qfunit

surge合成器 -- 用于语音处理的四阶滤波单元

26个版本

0.2.12-alpha.02023年4月7日
0.2.11-alpha.02022年12月19日
0.2.5-alpha.02022年6月21日
0.2.4-alpha.02022年3月14日
0.1.42-alpha.02021年10月27日

#9 in #surge

Download history 79/week @ 2024-04-01 72/week @ 2024-04-08 59/week @ 2024-04-15 67/week @ 2024-04-22 55/week @ 2024-04-29 53/week @ 2024-05-06 72/week @ 2024-05-13 48/week @ 2024-05-20 65/week @ 2024-05-27 19/week @ 2024-06-03 362/week @ 2024-06-10 61/week @ 2024-06-17 56/week @ 2024-06-24 3/week @ 2024-07-01 24/week @ 2024-07-08 98/week @ 2024-07-15

182 每月下载
用于 22 个crate(16 直接使用)

GPL-3.0 许可证

325KB
5.5K SLoC

surge-qfunit

50> /file surge-rs/surge-qfunit/src/qf_unit_state.rs

此源文件定义了QuadFilterUnitState结构体,它表示四阶滤波单元的状态。该结构体包含用于滤波器系数、寄存器、延迟缓冲区、活动掩码和组合写入位置的字段。

该结构体提供了访问和修改寄存器值的方法。`new`方法使用零初始化寄存器和空延迟缓冲区初始化一个新的`QuadFilterUnitState`实例。同时将`TablesHandle`结构体作为参数传递并存储为`QuadFilterUnitState`的字段。

请注意,此源文件使用了`z128!`宏,该宏返回一个包含四个初始化为零的`__m128向量的数组。这些向量在代码库中用于表示四个单精度浮点值打包到一个128位SIMD寄存器中。

51> /file surge-rs/surge-qfunit/src/qf_chain_state.rs

这是`QuadFilterChain`和`QuadFilterChainState`结构体的源代码。

QuadFilterChain

`QuadFilterChain`是一个表示`QuadFilterChainState`结构体链的结构体。它通常与`MAX_VOICES >> 2`个元素一起使用,每个`QuadFilterChainState`为四个声音执行滤波。

QuadFilterChainState

`QuadFilterChainState`是一个表示四阶滤波链状态的结构体。它包含多个字段,用于保存滤波器系数、寄存器、延迟缓冲区以及每个滤波单元的增益、反馈、混合和驱动参数。它还包括用于wavedata、反馈立体声通道和各种其他滤波器相关参数的字段。

结构体QuadFilterChainState有一个方法default_unit_state,该方法返回一个包含四个QuadFilterUnitState结构体的数组,这些结构体代表四通道滤波链中各个滤波单元的状态。

结构体QuadFilterChainState还有几个辅助方法,用于创建填充零的__m128向量。

52> /file surge-rs/surge-qfunit/src/do_dual1.rs

看起来do_dual1方法是对四通道滤波链状态执行滤波操作的几个方法之一。此方法接收四个参数

  • WaveshaperState的可变引用

  • QuadFilterChainState的可变引用

  • FbqGlobal的可变引用

  • 指向一个f32的指针,该指针将保存左声道输出

  • 指向一个f32的指针,该指针将保存右声道输出

该方法执行以下操作

  • 使用值0.5初始化一个常量值hb_c

  • 对于音频数据块中的每个样本

    • 通过添加d_feedback值来更新QuadFilterChainStatefeedback

    • feedback值乘以QuadFilterChainStatefeedback_line_l值,并对结果应用软剪辑函数

    • feedback值添加到QuadFilterChainStatedl[k]dr[k]值,并将结果分别存储在xy

    • 如果由常量A_FILTER_ACTIVE标识的滤波器处于活动状态,则使用QuadFilterChainState的第一个单元状态对x应用滤波器

    • 如果由常量B_FILTER_ACTIVE标识的滤波器处于活动状态,则使用QuadFilterChainState的第二个单元状态对y应用滤波器

    • QuadFilterChainStated_mix1d_mix2值分别添加到mix1mix2

    • 通过将x乘以mix1并将y乘以mix2来计算混合输出,并将结果相加

    • 如果由常量WAVESHAPER_ACTIVE标识的波形整形器处于活动状态,则使用WaveshaperStateQuadFilterChainStatedrive值将波形整形器应用于混合输出

    • QuadFilterChainStated_gain值添加到gain

    • 将混合输出乘以gain值,并对第一个单元状态的active值和混合输出应用位and操作的结果进行掩码

    • 将掩码后的输出存储在QuadFilterChainStatefeedback_line_l值中

    • 通过使用适当的参数调用qfc_write_outputs函数来写入左右声道输出值。

53> /file surge-rs/surge-qfunit/src/do_ring.rs

这两种方法似乎使用一个名为 QuadFilterChainState 的结构体对音频数据进行过滤和处理,该结构体包含与过滤链状态相关的各种数据。第一种方法 do_dual1 似乎实现了一种双滤波拓扑,其中两个独立的滤波器并行应用于音频数据。第二种方法 do_ring 实现了一种环调制拓扑,其中一个滤波器的输出用于调制另一个滤波器的输入。

这两种方法都对 QuadFilterChainState 结构体的字段执行操作,例如 unit_state,它似乎包含有关链中每个滤波器单元的信息,以及 gain,它似乎决定了处理后的音频信号的总体增益。其他字段如 feedbackmix1mix2 似乎用于中间计算。

这些方法还似乎使用一些外部状态,例如 wss,一个可变引用到 WaveshaperState 结构体,和 fbq,一个可变引用到 FbqGlobal 结构体。这些引用可能用于在程序的不同部分之间传递信息,或用于访问共享状态。

最后,这两种方法都包含一个对 qfc_write_outputs 的调用,这里未显示,但可能执行一些输出操作,例如将过滤后的音频数据写入缓冲区。

54> /file surge-rs/surge-qfunit/src/do_serial1.rs

这些是 Rust 模块中的三种方法,可能与其音频处理有关。这些方法实现不同的滤波拓扑,用于处理音频信号。所有三种方法具有类似的结构,其中它们遍历一个音频样本块,用不同的滤波器处理样本,混合结果,并输出最终信号。

似乎 do_dual1 方法实现了一种带反馈的双滤波拓扑。似乎 do_ring 方法实现了一种带反馈的环调制拓扑。似乎 do_serial1 方法实现了一种不带反馈的串行滤波拓扑。

每种方法都接受一个 WaveshaperState 结构体、一个 QuadFilterChainState 结构体、一个 FbqGlobal 结构体,以及两个指向输出左右声道的 *mut f32 指针。似乎 QuadFilterChainState 结构体包含不同滤波器的状态,而 FbqGlobal 结构体包含指向滤波器函数的指针。

总的来说,这些方法似乎是对音频滤波器的低级、性能关键实现,利用了现代 CPU 的 SIMD 功能来提高速度。

55> /file surge-rs/surge-qfunit/src/do_stereo.rs

所有这些函数似乎都是 Rust 仓库 QFC(四路滤波链)的一部分,该仓库实现了各种数字信号处理(DSP)算法,如滤波、波形整形和混合等。每个函数似乎都是具有 do_ 前缀的不同实现,它代表滤波链的特定处理拓扑。不同的实现似乎针对不同的滤波链进行了优化,并且它们接受各种布尔常量作为参数,以确定针对特定滤波链要激活哪些处理块。所有这些函数似乎都在使用 sse Rust 仓库提供的 SIMD 指令集操作 f32 值。

56> 所以,我们针对不同的拓扑有几个硬编码的滤波链

是的,这是正确的。这些函数实现了针对 QuadFilterChainState 结构体的不同滤波拓扑。不同的拓扑对应于将两个滤波器串联或并联的不同方式。具体的拓扑是通过调用基于所需滤波配置的相应函数来选择的。

57> 那么关于 QuadFilterChainState 本身,它是如何使用的?

QuadFilterChainState 是一个用于存储四通道滤波链状态的结构体。它包含多个数组和值,用于存储滤波系数和状态,以及滤波链使用的混合和反馈值。

以下是 QuadFilterChainState 结构体的定义

pub struct QuadFilterChainState {
    pub dl:               [__m128; BLOCK_SIZE_OS],
    pub dr:               [__m128; BLOCK_SIZE_OS],
    pub feedback_line_l:  __m128,
    pub feedback:        __m128,
    pub mix1:            __m128,
    pub mix2:            __m128,
    pub gain:            __m128,
    pub d_feedback:      __m128,
    pub d_mix1:          __m128,
    pub d_mix2:          __m128,
    pub d_gain:          __m128,
    pub unit_state:      [UnitState; 2],
    pub active:          [bool; 4],
    pub drive:           __m128,
    pub d_drive:         __m128,
    pub ws_lpf:          __m128,
}

该结构体中的几个关键字段包括

  • dldr:这些是存储左右声道输入音频数据的 4 元素向量(__m128)数组。

  • feedback_line_lfeedback:这些是存储左声道滤波链反馈值的向量。

  • mix1mix2:这些是存储左右声道滤波链混合值的向量。

  • gain:这是一个存储滤波链总增益的向量。

  • d_feedbackd_mix1d_mix2d_gaind_drive:这些是存储反馈、混合、增益和驱动参数的delta值(值的改变)的向量。

  • unit_state:这是一个包含两个 UnitState 结构体的数组,用于存储滤波链中两个滤波单元的状态。

  • active:这是一个包含四个布尔值的数组,指示滤波链中哪些滤波单元和通道是活动的。

  • drivews_lpf:这些是存储 waveshaper 使用的驱动和低通滤波值的向量。

QuadFilterChainState 结构体作为参数传递给滤波链函数,这些函数使用其字段执行滤波和混合操作。在每次调用滤波链函数时,QuadFilterChainState 结构体中的值会更新,以反映滤波参数和音频数据的更改。

58> 有趣 —— 它与 QuadFilterUnitState 有何区别?

QuadFilterUnitState 是一个按单元状态的结构体,它为 QuadFilterChain 中的每个四通道滤波单元保存状态信息。它包含如滤波系数、滤波状态变量等参数。

另一方面,QuadFilterChainState 是一个保存整个 QuadFilterChain 状态信息的结构体。这包括四个 QuadFilterUnitState 结构体,以及整个滤波链的状态变量,如反馈值、混合值和增益值。

换句话说,QuadFilterUnitState 包含单个滤波单元的状态信息,而 QuadFilterChainState 包含整个滤波链的状态信息。

59> 谢谢 —— 似乎我们可以选择激活哪种拓扑,这利用了多个四通道滤波单元。链是整个流程的管理结构

是的,这是正确的。QuadFilterChainState 是管理音频通过不同四通道滤波单元和其他处理阶段的主体结构。它为每个四通道滤波单元提供必要的状态信息,如滤波系数、滤波状态和反馈参数,以及混合系数以组合滤波信号。通过激活四通道滤波单元的不同组合,四通道滤波链可以实施不同的滤波拓扑。

另一方面,QuadFilterUnitState 包含每个独立四通道滤波单元的状态信息,例如滤波系数和状态,以及增益和激活标志。每个四通道滤波单元负责处理一个音频通道,而QuadFilterUnitState用于管理每个单元的状态。

依赖项

~11-20MB
~295K SLoC