moonloudness

    纯 MoonBit 的交错 PCM 流式响度与峰值分析库

    audio
    loudness
    ebu-r128
    bs1770
    dsp
    Download zip
    Version
    0.1.3
    License
    MIT
    Last updated
    3 days ago
    Downloads
    52

    No dependencies

    #MoonLoudness

    MoonLoudness 是一个纯 MoonBit 的流式响度与峰值分析库,输入为交错排列的 PCM 采样。它为媒体质检、批量处理、实时仪表和音频编辑工具提供可复用的进程内测量核心;解码、播放和增益应用仍由调用方负责。

    #安装

    需要 moonc 0.10.16 或更高版本;CI 固定编译器与 core 为 0.10.16+b1a0e846e。先运行 moon version --all 核对版本。0.1.3 完成这一工具链升级与 JSON 构造兼容,测量算法和公共 API 保持不变。

    模块:hutingyu-nuist/moonloudness@0.1.3。在下游 MoonBit 项目中添加依赖:

    moon add hutingyu-nuist/moonloudness@0.1.3

    无需 MoonCakes 凭据即可使用公开包。请检查依赖清单中实际解析的版本;打包成功不等于已经发布,精确版本的可用性以公开注册表为准。0.1.2 修复混合正常/超量程短时块的 LRA 不可用语义,公共 API 不变。

    也可以直接运行源码:

    git clone https://github.com/hutingyu-nuist/moonloudness.git cd moonloudness moon check --target wasm-gc moon test --target wasm-gc

    #支持的测量流程

    • 48,000 Hz、按完整帧交错排列的浮点 PCM;单声道(C)、立体声(L,R)和 5.0(L,R,C,Ls,Rs,不含 LFE)。
    • 逐声道 K 加权、400 ms 瞬时与 3 s 短时窗口、综合响度门控、响度范围(LRA)、采样峰值和四相 FIR 真峰值估计。
    • 修改状态前预检整个输入块:拒绝不完整帧、非有限数值以及绝对值大于 1e150 的采样。
    • 有界测量历史:默认保留 600 点,可配置为 0~100,000 点;以固定内存聚合已经结束的独立节目报告。
    • 可检查的门控阈值与块数、显式 GateStatus、独立于分析器状态的版本化 JSON,以及受调用方真峰值上限约束的非破坏性恒定增益建议。
    • 同步零拷贝 push_view、带校验的独立节目组组合,以及明确的历史与重置契约。

    门控与百分位数使用 0.01 LU 直方图桶,阈值保守量化到桶边界,以换取有界内存;它不是任意时长的精确音频块档案。本项目不声称通过 ITU-R BS.1770-5 或 EBU Tech 3341/3342/3343 一致性认证,也未运行 EBU 官方测试套件。

    #快速上手

    以下片段在导入本库为 @moonloudness 后使用;samples 是调用方提供的 Array[Double],包含完整的交错 PCM 帧:

    let layout = @moonloudness.ChannelLayout::mono()
    let config = match @moonloudness.MeterConfig::new(48000, layout) {
    Ok(value) => value
    Err(_) => panic()
    }
    let meter = @moonloudness.Analyzer::new(config)
    match meter.push(samples) { // Array[Double],完整交错帧
    Ok(_) => ()
    Err(_) => panic()
    }
    let report = meter.finish()
    match report.integrated_lufs() {
    Some(value) => println(value.to_string())
    None => println("综合响度暂不可用")
    }
    match report.true_peak_dbtp() {
    Some(value) => println(value.to_string())
    None => println("真峰值暂不可用")
    }

    Analyzer::push 接收归一化浮点采样;为了分析峰值余量,也接受 [-1,1] 之外、但不超过上述数值上限的有限值。库不包含解码器、容器读取器、重采样器、播放引擎、限幅器,也不会自动应用增益。

    #可运行示例

    在模块根目录执行:

    moon run examples/mono --target wasm-gc moon run examples/stereo --target wasm-gc moon run examples/surround --target wasm-gc moon run examples/batch --target wasm-gc moon run examples/reference --target wasm-gc

    • mono:分析 1 kHz 节目信号并检查增益建议。
    • stereo:分块输入,读取保留的时间序列与门控诊断。
    • surround:检查 5.0 布局的声道标签、权重和逐声道峰值。
    • batch:先逐节目质检,再汇总独立节目;汇总结果不能掩盖单项失败。
    • reference:输出原创合成信号的测量数据,供独立差分验证使用。

    所有示例自行生成信号,不依赖音频文件或网络。更多步骤见 示例说明。

    #检查、构建与测试

    python tools/check_toolchain.py moon info moon fmt --check moon check --deny-warn --target wasm-gc moon check --deny-warn --target js moon test --deny-warn --target wasm-gc moon test --deny-warn --target js moon build --release --target wasm-gc

    2026-10-20 对 0.1.2 修复树的本地验证:wasm-gc、wasm、js、native 的严格检查、release 构建、debug/release 测试均通过,每套 76/76,五个示例在四目标均可运行。Windows native 使用隔离目录中的 Zig 0.14.1 C 编译器,MinGW 头文件通过 -D_CRT_RAND_S 启用 rand_s 声明;没有修改 MoonBit runtime 或关闭警告。对应提交的 Ubuntu CI 仍须单独核验。保守源码和提交审计命令为 python tools/audit_delivery.py --strict:自动检查非空提交、不同源码树与作者,开发价值仍须人工审查。

    2026-11-01 对 0.1.3 的验收复测使用 moonc 0.10.16+b1a0e846e:三个可移植后端的严格检查、release 构建及 debug/release 共六套测试均为 76/76,五例×三个后端共 15 次运行成功,Python 工具测试 32/32,独立 FFmpeg 工程比较 60/60。Windows 本机 native 严格检查通过,但新编译器 runtime 要求 MSVC,本机仅有 MinGW,因此 native 编译和执行以本版本对应 Ubuntu CI 为证,不将旧版 Windows 运行结果计作本次通过。

    2026-10-14 的独立工程验证中,五组确定性合成信号、四项指标、三个可移植后端共 60/60 次比较通过预先声明的 FFmpeg 回归容差。该结果不是标准认证。见 验证说明、实测结果 和 批处理计时。计时包含进程启动和 PCM 生成,不是纯 DSP 运算耗时;仓库不分发外部音频测试资产。

    Python 控制器与审计测试:

    python -m unittest discover -s tools -p "test_*.py" -v

    这些可选控制器仅使用 Python 标准库;FFmpeg 差分验证另需安装 FFmpeg。

    #三类下游场景与数据交换

    1. 媒体入库与质检:已有解码器提供 48 kHz 交错 PCM 块;逐素材保留综合响度、LRA、采样峰值、真峰值和门控诊断,由质检系统按自身规则判定。即使聚合结果看似合格,批处理示例仍保留各素材的失败结果。
    2. 实时测量仪表:通过 push_view 输入有界块,读取 snapshot() 与按时间排序的历史。400 ms/3 s 窗口需要预热,有限历史不是音频档案;结束时冲刷 FIR 尾部,但不虚增输入帧数。
    3. 编辑与峰值余量工具:分析 mono/stereo/5.0 PCM,检查声道峰值并计算受上限约束的恒定增益建议。由下游决定是否应用,并对输出重新测量;固定门控的预测不能保证归一化后的实际响度。

    report.to_json() 输出独立的版本化对象,缺失值明确表示为 null,见 JSON 契约。LoudnessAggregator::add 与 merge 汇总独立节目的分布,而非平均 LUFS,也不会拼接跨节目的滤波器状态。

    #数值边界与非目标

    • 有限采样幅度允许至 1e150,但高于 +24 LUFS 的候选会令相应直方图门控不可用,而非截断成看似有效的结果。
    • 0.01 LU 的桶宽不能保证门控阈值附近的成员选择误差也不超过 0.01 LU。
    • 计数器限制单次会话长度:单声道约 12.43 小时、立体声约 6.21 小时、5.0 约 2.49 小时。
    • 不支持任意采样率、任意声道映射、LFE/5.1、文件解码、重采样、播放、编码、限幅、动态压缩或自动增益。

    #设计来源、许可与生态查重

    设计参考 ITU-R BS.1770-5 和 EBU Tech 3341/3342/3343。Rust sdroege/ebur128 v0.1.10 的固定提交用于能力参照;未复制或翻译其 Rust 源码。原创实现采用 MIT 许可。来源、第三方归属与 AI 使用说明见 THIRD_PARTY.md、LICENSE 和 AI_USAGE.md。

    有限检索范围内的候选对比与相邻项目源码、API、测试审查见 查重记录。结论仅为:在已记录检索范围内未发现成熟直接替代,不是对整个生态作绝对不存在的断言。

    AggregateReport

    pub struct AggregateReport {
    // private fields
    }

    Immutable combined result calculated over all accepted loudness blocks.

    AggregateReport::asset_count

    fn AggregateReport::asset_count(self : AggregateReport) -> Int

    AggregateReport::duration_seconds

    fn AggregateReport::duration_seconds(self : AggregateReport) -> Double

    AggregateReport::frame_count

    fn AggregateReport::frame_count(self : AggregateReport) -> Int

    AggregateReport::integrated_gate

    fn AggregateReport::integrated_gate(self : AggregateReport) -> IntegratedGateReport?

    AggregateReport::integrated_lufs

    fn AggregateReport::integrated_lufs(self : AggregateReport) -> Double?

    AggregateReport::integrated_status

    fn AggregateReport::integrated_status(self : AggregateReport) -> GateStatus

    AggregateReport::loudness_range_lu

    fn AggregateReport::loudness_range_lu(self : AggregateReport) -> Double?

    AggregateReport::lra_gate

    AggregateReport::lra_status

    fn AggregateReport::lra_status(self : AggregateReport) -> GateStatus

    AggregateReport::normalization_plan

    fn AggregateReport::normalization_plan(self : AggregateReport, target_lufs : Double, ceiling_dbtp : Double) -> Result[NormalizationPlan, NormalizationPlanError]

    AggregateReport::sample_peak_dbfs

    fn AggregateReport::sample_peak_dbfs(self : AggregateReport) -> Double?

    AggregateReport::sample_peak_linear

    fn AggregateReport::sample_peak_linear(self : AggregateReport) -> Double

    AggregateReport::sample_rate

    fn AggregateReport::sample_rate(self : AggregateReport) -> Int

    AggregateReport::true_peak_dbtp

    fn AggregateReport::true_peak_dbtp(self : AggregateReport) -> Double?

    AggregateReport::true_peak_linear

    fn AggregateReport::true_peak_linear(self : AggregateReport) -> Double

    AggregationError

    pub enum AggregationError {
    UnsupportedAggregateSampleRate(Int)
    ReportSampleRateMismatch(Int, Int)
    AggregateCounterOverflow
    InvalidAggregateCounters
    InvalidAggregateDistribution
    InvalidAggregatePeak
    }

    Errors returned while combining finalized reports.

    Analyzer

    pub struct Analyzer {
    // private fields
    }

    Stateful analyzer for interleaved PCM frames at 48 kHz.

    Analyzer::channel_sample_peak_linear

    fn Analyzer::channel_sample_peak_linear(self : Analyzer, channel : Int) -> Double?

    Returns one channel's maximum absolute input sample, or None for an invalid index.

    Analyzer::channel_sample_peaks_linear

    fn Analyzer::channel_sample_peaks_linear(self : Analyzer) -> Array[Double]

    Returns a detached copy of the channel-ordered sample-peak array.

    Analyzer::clear_history

    fn Analyzer::clear_history(self : Analyzer) -> Unit

    Drops historical points while keeping all live measurement state.

    Analyzer::duration_seconds

    fn Analyzer::duration_seconds(self : Analyzer) -> Double

    Returns the analyzed duration based on complete 48 kHz frames.

    Analyzer::finish

    fn Analyzer::finish(self : Analyzer) -> MeasurementReport

    Finalizes the input and flushes the Annex 2 interpolation FIR tail.

    Analyzer::frame_count

    fn Analyzer::frame_count(self : Analyzer) -> Int

    Returns the number of accepted frames.

    Analyzer::history

    fn Analyzer::history(self : Analyzer) -> Array[MeterSnapshot]

    Returns retained measurement points in chronological order.

    Analyzer::history_capacity

    fn Analyzer::history_capacity(self : Analyzer) -> Int

    Returns the configured maximum number of retained points.

    Analyzer::integrated_status

    fn Analyzer::integrated_status(self : Analyzer) -> GateStatus

    Gate is unavailable if any candidate exceeds the bounded +24 LUFS range.

    Analyzer::lra_status

    fn Analyzer::lra_status(self : Analyzer) -> GateStatus

    Analyzer::momentary_lufs

    fn Analyzer::momentary_lufs(self : Analyzer) -> Double?

    Returns the latest complete 400 ms momentary window when available.

    Analyzer::new

    fn Analyzer::new(config : MeterConfig) -> Analyzer

    Starts an empty analyzer with separate filter and window history.

    Analyzer::new_with_history_capacity

    fn Analyzer::new_with_history_capacity(config : MeterConfig, capacity : Int) -> Result[Analyzer, MeterError]

    Creates an analyzer with a bounded history capacity (zero disables retention).

    Analyzer::push

    fn Analyzer::push(self : Analyzer, samples : Array[Double]) -> Result[Unit, MeterError]

    Adds complete interleaved frames. The whole chunk is validated before mutation.

    Analyzer::push_view

    fn Analyzer::push_view(self : Analyzer, samples : ArrayView[Double]) -> Result[Unit, MeterError]

    Consumes a borrowed PCM view synchronously without copying or retaining it. Validation remains atomic; the caller must not mutate the view during this call.

    Analyzer::reset

    fn Analyzer::reset(self : Analyzer) -> Unit

    Restarts the analyzer with the same immutable stream configuration.

    Analyzer::sample_count

    fn Analyzer::sample_count(self : Analyzer) -> Int

    Returns the number of accepted interleaved samples.

    Analyzer::sample_peak_linear

    fn Analyzer::sample_peak_linear(self : Analyzer) -> Double

    Returns the largest absolute input sample in linear amplitude.

    Analyzer::short_term_lufs

    fn Analyzer::short_term_lufs(self : Analyzer) -> Double?

    Returns the latest complete 3 s short-term window when available.

    Analyzer::snapshot

    fn Analyzer::snapshot(self : Analyzer) -> MeterSnapshot

    Returns the current counters, levels, and peaks without changing analyzer state.

    Analyzer::true_peak_linear

    fn Analyzer::true_peak_linear(self : Analyzer) -> Double

    Returns the maximum Annex 2 four-phase FIR estimate in linear amplitude.

    ChannelLayout

    pub enum ChannelLayout {
    Mono
    Stereo
    FivePointZero
    }

    FivePointZero uses L, R, C, Ls, Rs order; it has no LFE channel.

    ChannelLayout::channel_label

    fn ChannelLayout::channel_label(self : ChannelLayout, index : Int) -> String?

    Returns the canonical short name for a channel index in this layout.

    ChannelLayout::channel_weight

    fn ChannelLayout::channel_weight(self : ChannelLayout, index : Int) -> Double?

    Returns the BS.1770 channel multiplier, or None for an invalid index.

    ChannelLayout::channels

    fn ChannelLayout::channels(self : ChannelLayout) -> Int

    Returns the number of interleaved samples in one frame.

    ChannelLayout::five_point_zero

    fn ChannelLayout::five_point_zero() -> ChannelLayout

    Returns the canonical 5.0 layout in L,R,C,Ls,Rs order.

    ChannelLayout::index_of

    fn ChannelLayout::index_of(self : ChannelLayout, label : String) -> Int?

    Finds the exact canonical channel label in a layout.

    ChannelLayout::mono

    Returns the canonical mono layout.

    ChannelLayout::stereo

    Returns the canonical left-right stereo layout.

    ChannelLayout::supported

    fn ChannelLayout::supported() -> Array[ChannelLayout]

    Returns the layouts implemented by this release.

    GateStatus

    pub enum GateStatus {
    WarmingUp
    BelowAbsoluteGate
    HistogramRangeExceeded(Int)
    Available
    } derive(Eq,
    Debug
    )

    Gate availability is distinct from logarithmic silence and numeric input validity.

    GateStatus::equal

    fn GateStatus::equal(GateStatus, GateStatus) -> Bool

    GateStatus::not_equal

    fn GateStatus::not_equal(x : GateStatus, y : GateStatus) -> Bool

    IntegratedGateReport

    pub struct IntegratedGateReport {
    // private fields
    }

    Auditable thresholds and counts used for integrated-loudness gating.

    IntegratedGateReport::absolute_threshold_lufs

    fn IntegratedGateReport::absolute_threshold_lufs(self : IntegratedGateReport) -> Double

    IntegratedGateReport::applied_threshold_lufs

    fn IntegratedGateReport::applied_threshold_lufs(self : IntegratedGateReport) -> Double

    IntegratedGateReport::candidate_block_count

    fn IntegratedGateReport::candidate_block_count(self : IntegratedGateReport) -> Int

    IntegratedGateReport::gated_block_count

    fn IntegratedGateReport::gated_block_count(self : IntegratedGateReport) -> Int

    IntegratedGateReport::integrated_lufs

    fn IntegratedGateReport::integrated_lufs(self : IntegratedGateReport) -> Double

    IntegratedGateReport::relative_threshold_lufs

    fn IntegratedGateReport::relative_threshold_lufs(self : IntegratedGateReport) -> Double

    LoudnessAggregator

    pub struct LoudnessAggregator {
    // private fields
    }

    Fixed-memory accumulator for independently measured programs at one sample rate.

    LoudnessAggregator::add

    Adds one finalized asset without retaining its report or PCM samples.

    LoudnessAggregator::asset_count

    fn LoudnessAggregator::asset_count(self : LoudnessAggregator) -> Int

    Number of finalized reports accepted so far.

    LoudnessAggregator::finish

    Produces a detached aggregate report; the accumulator remains usable afterward.

    LoudnessAggregator::frame_count

    fn LoudnessAggregator::frame_count(self : LoudnessAggregator) -> Int

    LoudnessAggregator::integrated_status

    fn LoudnessAggregator::integrated_status(self : LoudnessAggregator) -> GateStatus

    Includes range failures from every independently added program.

    LoudnessAggregator::lra_status

    LoudnessAggregator::merge

    Combines independent programs, not concatenated PCM: no cross-program windows or filter transitions are invented. Neither source nor reports are retained. Self-merge deliberately doubles the accepted programs. Histogram addition is associative up to floating-point energy-sum rounding.

    LoudnessAggregator::new

    Creates an accumulator compatible with the available coefficient set.

    LoudnessAggregator::sample_rate

    fn LoudnessAggregator::sample_rate(self : LoudnessAggregator) -> Int

    LraGateReport

    pub struct LraGateReport {
    // private fields
    }

    Auditable thresholds, accepted block counts, and percentiles for LRA.

    LraGateReport::absolute_threshold_lufs

    fn LraGateReport::absolute_threshold_lufs(self : LraGateReport) -> Double

    LraGateReport::applied_threshold_lufs

    fn LraGateReport::applied_threshold_lufs(self : LraGateReport) -> Double

    LraGateReport::candidate_block_count

    fn LraGateReport::candidate_block_count(self : LraGateReport) -> Int

    LraGateReport::gated_block_count

    fn LraGateReport::gated_block_count(self : LraGateReport) -> Int

    LraGateReport::loudness_range_lu

    fn LraGateReport::loudness_range_lu(self : LraGateReport) -> Double

    LraGateReport::percentile_10_lufs

    fn LraGateReport::percentile_10_lufs(self : LraGateReport) -> Double

    LraGateReport::percentile_95_lufs

    fn LraGateReport::percentile_95_lufs(self : LraGateReport) -> Double

    LraGateReport::relative_threshold_lufs

    fn LraGateReport::relative_threshold_lufs(self : LraGateReport) -> Double

    MeasurementReport

    pub struct MeasurementReport {
    // private fields
    }

    Result of finalizing one analyzer stream.

    MeasurementReport::channel_sample_peak_linear

    fn MeasurementReport::channel_sample_peak_linear(self : MeasurementReport, channel : Int) -> Double?

    Returns one channel's peak or None when the channel index is invalid.

    MeasurementReport::channel_sample_peaks_linear

    fn MeasurementReport::channel_sample_peaks_linear(self : MeasurementReport) -> Array[Double]

    Returns an independent array of the largest submitted sample magnitude per channel.

    MeasurementReport::duration_seconds

    fn MeasurementReport::duration_seconds(self : MeasurementReport) -> Double

    MeasurementReport::frame_count

    fn MeasurementReport::frame_count(self : MeasurementReport) -> Int

    Returns the count of complete input frames accepted by the analyzer.

    MeasurementReport::integrated_gate

    Returns the integrated-gate trace when at least one block passes the absolute gate.

    MeasurementReport::integrated_lufs

    fn MeasurementReport::integrated_lufs(self : MeasurementReport) -> Double?

    Returns integrated loudness after absolute and relative gating.

    MeasurementReport::integrated_status

    fn MeasurementReport::integrated_status(self : MeasurementReport) -> GateStatus

    MeasurementReport::loudness_range_lu

    fn MeasurementReport::loudness_range_lu(self : MeasurementReport) -> Double?

    Returns gated short-term loudness range, if enough signal passed the gates.

    MeasurementReport::lra_gate

    MeasurementReport::lra_status

    MeasurementReport::momentary_lufs

    fn MeasurementReport::momentary_lufs(self : MeasurementReport) -> Double?

    Returns the latest complete 400 ms measurement.

    MeasurementReport::normalization_plan

    fn MeasurementReport::normalization_plan(self : MeasurementReport, target_lufs : Double, ceiling_dbtp : Double) -> Result[NormalizationPlan, NormalizationPlanError]

    Recommends constant gain only; it does not normalize or limit the stream.

    MeasurementReport::sample_peak_dbfs

    fn MeasurementReport::sample_peak_dbfs(self : MeasurementReport) -> Double?

    Returns sample peak in dBFS; silence has no finite logarithmic value.

    MeasurementReport::sample_peak_linear

    fn MeasurementReport::sample_peak_linear(self : MeasurementReport) -> Double

    Returns the largest absolute submitted PCM sample.

    MeasurementReport::sample_rate

    fn MeasurementReport::sample_rate(self : MeasurementReport) -> Int

    MeasurementReport::short_term_lufs

    fn MeasurementReport::short_term_lufs(self : MeasurementReport) -> Double?

    Returns the latest complete 3 s measurement.

    MeasurementReport::to_json

    Detached machine-readable report, schema "moonloudness.measurement" v1. Keys are inserted in a fixed order, with no timestamps or mutable state. All optional measurements and gates are present: unavailable/non-finite numeric values become null, never NaN/Infinity. Counters are JSON numbers; units are explicit in field names (Hz, seconds, LUFS, LU, dBFS, dBTP). Layout is inferred from the public channel-peak count for the supported mono/stereo/5.0 layouts. Unknown layouts have null names/labels, not a guess. Nested loudness, gates, and peaks preserve the public getters verbatim. Every object/array is newly allocated; editing returned JSON cannot change the report, analyzer, cached report, or later exports.

    MeasurementReport::true_peak_dbtp

    fn MeasurementReport::true_peak_dbtp(self : MeasurementReport) -> Double?

    Returns true peak in dBTP; silence has no finite logarithmic value.

    MeasurementReport::true_peak_linear

    fn MeasurementReport::true_peak_linear(self : MeasurementReport) -> Double

    Returns the overall four-phase FIR estimate after flushing the interpolation tail.

    MeterConfig

    pub struct MeterConfig {
    // private fields
    }

    Immutable configuration for one 48 kHz PCM stream.

    MeterConfig::layout

    fn MeterConfig::layout(self : MeterConfig) -> ChannelLayout

    Returns the interleaved channel layout.

    MeterConfig::new

    fn MeterConfig::new(sample_rate : Int, layout : ChannelLayout) -> Result[MeterConfig, MeterError]

    Creates a configuration. Only the published 48 kHz coefficient set is enabled.

    MeterConfig::sample_rate

    fn MeterConfig::sample_rate(self : MeterConfig) -> Int

    Returns the configured sample rate in samples per second.

    MeterError

    pub enum MeterError {
    UnsupportedSampleRate(Int)
    IncompleteFrame(Int, Int)
    NonFiniteSample
    SampleMagnitudeTooLarge(Double)
    CounterOverflow
    InvalidHistoryCapacity(Int)
    AnalyzerFinished
    }

    Typed configuration and input errors.

    MeterSnapshot

    pub struct MeterSnapshot {
    // private fields
    }

    A detached point-in-time view of a streaming loudness analyzer.

    MeterSnapshot::channel_sample_peaks_linear

    fn MeterSnapshot::channel_sample_peaks_linear(self : MeterSnapshot) -> Array[Double]

    Returns channel peaks in the configured layout order as an independent array.

    MeterSnapshot::duration_seconds

    fn MeterSnapshot::duration_seconds(self : MeterSnapshot) -> Double

    MeterSnapshot::frame_count

    fn MeterSnapshot::frame_count(self : MeterSnapshot) -> Int

    MeterSnapshot::momentary_lufs

    fn MeterSnapshot::momentary_lufs(self : MeterSnapshot) -> Double?

    MeterSnapshot::sample_count

    fn MeterSnapshot::sample_count(self : MeterSnapshot) -> Int

    MeterSnapshot::sample_peak_dbfs

    fn MeterSnapshot::sample_peak_dbfs(self : MeterSnapshot) -> Double?

    Returns snapshot sample peak in dBFS, or None for digital silence.

    MeterSnapshot::sample_peak_linear

    fn MeterSnapshot::sample_peak_linear(self : MeterSnapshot) -> Double

    MeterSnapshot::sample_rate

    fn MeterSnapshot::sample_rate(self : MeterSnapshot) -> Int

    Returns the frame position represented by this snapshot.

    MeterSnapshot::short_term_lufs

    fn MeterSnapshot::short_term_lufs(self : MeterSnapshot) -> Double?

    MeterSnapshot::true_peak_dbtp

    fn MeterSnapshot::true_peak_dbtp(self : MeterSnapshot) -> Double?

    Returns the live FIR estimate in dBTP, or None for digital silence.

    MeterSnapshot::true_peak_linear

    fn MeterSnapshot::true_peak_linear(self : MeterSnapshot) -> Double

    NormalizationPlan

    pub struct NormalizationPlan {
    // private fields
    }

    Constant-gain advice constrained by an explicit true-peak ceiling. This value is informational: it never changes or limits audio samples. Predicted loudness holds the original gate membership fixed. Gain can move blocks across the absolute gate, so processed audio MUST be remeasured.

    NormalizationPlan::applied_gain_db

    fn NormalizationPlan::applied_gain_db(self : NormalizationPlan) -> Double

    NormalizationPlan::linear_gain

    fn NormalizationPlan::linear_gain(self : NormalizationPlan) -> Double

    Positive finite amplitude multiplier corresponding to applied_gain_db. Does not apply gain, change gating, or guarantee exact target loudness.

    NormalizationPlan::peak_constrained

    fn NormalizationPlan::peak_constrained(self : NormalizationPlan) -> Bool

    NormalizationPlan::peak_limited_gain_db

    fn NormalizationPlan::peak_limited_gain_db(self : NormalizationPlan) -> Double

    NormalizationPlan::predicted_integrated_lufs

    fn NormalizationPlan::predicted_integrated_lufs(self : NormalizationPlan) -> Double

    Fixed-gate estimate, not an exact remeasurement of gained audio. Absolute-gate membership can change after gain; remeasure the output.

    NormalizationPlan::predicted_true_peak_dbtp

    fn NormalizationPlan::predicted_true_peak_dbtp(self : NormalizationPlan) -> Double

    NormalizationPlan::requested_gain_db

    fn NormalizationPlan::requested_gain_db(self : NormalizationPlan) -> Double

    NormalizationPlan::target_lufs

    fn NormalizationPlan::target_lufs(self : NormalizationPlan) -> Double

    NormalizationPlan::true_peak_ceiling_dbtp

    fn NormalizationPlan::true_peak_ceiling_dbtp(self : NormalizationPlan) -> Double

    NormalizationPlanError

    pub enum NormalizationPlanError {
    MissingIntegratedLoudness
    InvalidTargetLufs(Double)
    InvalidTruePeakCeilingDbtp(Double)
    InvalidMeasuredLevels
    UnsafeNormalizationMath
    }

    Validation failures for a non-destructive constant-gain recommendation.