moonwavkit

    MoonBit-native WAV parser, PCM decoder, waveform analysis, validation, and audio utility toolkit.

    wav
    audio
    pcm
    riff
    moonbit
    Download zip
    Author
    Version
    0.1.3
    License
    MIT
    Last updated
    last month
    Downloads
    20

    #MoonWavKit

    CI

    MoonWavKit 是一个 MoonBit 原生 WAV 音频解析与 PCM 工具库,面向游戏资源检查、音频可视化、教学实验、WebAssembly 音频应用和自动化素材流水线。

    它不是播放器,也不依赖外部音频库;v0.1.3 聚焦 RIFF/WAVE 结构解析、PCM/Float 解码、音频统计、波形摘要、区段分析、质量检查、内置 fixture 验收矩阵和可复现示例。

    #发布与质量

    • MoonBit 源码规模:核心库约 4260 行;连同测试、CLI 和示例共约 5170 行。
    • 测试:72 个测试,覆盖解析、解码、统计、处理、校验、元数据、区段分析、质量检查和 fixture 矩阵。
    • 示例:cmd/mainexamples/basic 均可运行。
    • CI:覆盖格式检查、全目标检查/构建/测试、覆盖率摘要、公开接口一致性和示例运行。
    • 发布:Mooncakes 包 Ridge-Lab/moonwavkit@0.1.3
    • 许可证:MIT,属于 OSI 认可开源许可证。

    #支持范围

    已支持:

    • RIFF/WAVE header 与 chunk 遍历。
    • fmt datafactLIST/INFOcue ,未知 chunk 会跳过并保留元数据。
    • PCM 8-bit unsigned、16/24/32-bit signed 解码。
    • IEEE Float 32-bit 解码。
    • 音频统计:时长、帧数、peak、RMS、静音样本、削波样本、DC offset。
    • PCM 工具:增益、归一化、静音裁剪、反转、线性重采样、混音、拼接、padding、PCM 编码、从 FloatBuffer 构造 WAV。
    • 波形工具:bucket 摘要、直方图、文本波形、通道拆分、downmix。
    • 区段分析:静音段、普通信号段、响亮段、削波段、覆盖率和文本/CSV 报告。
    • 质量检查:削波、静音、过低音量、DC offset、crest factor、zero crossing。
    • 可运行 fixture catalog,用于回归验证支持矩阵。

    暂不支持:

    • MP3、AAC、FLAC、OGG 等压缩格式解码。
    • WAV 播放器、实时音频设备、复杂 DSP 合成引擎。
    • WAVE_FORMAT_EXTENSIBLE 的完整 channel mask/subformat 解析。

    解码始终生成归一化 FloatBufferDecodeOptions.target_channels 只接受 0(保留源声道)或与源文件相同的声道数;声道转换请显式调用 downmix_to_mono 等处理 API,不会被静默执行。

    #兼容性

    • 已验证工具链:MoonBit 0.10.8 / moon 0.1.20260814
    • 默认目标:wasm-gc;核心包通过 wasmwasm-gcjsnative 全目标检查。
    • 不依赖浏览器音频 API、系统音频设备或第三方音频库。
    • 输入由调用方以 Array[Int] 提供,库不负责文件系统读取或流式解码。

    #生态差异

    MoonBit 生态已有的相近包主要覆盖 WAV/OGG 编码、原生音频播放或设备绑定、DSP 引擎和音乐中间表示。MoonWavKit 不重复这些职责,专注可跨 Wasm/JavaScript/Native 使用的 RIFF/WAVE 输入链路:结构解析、PCM 解码、元数据、格式校验、波形与区段分析、质量报告及可复现 fixture。它既可以独立用于资源 CI,也可以作为播放器、游戏引擎和可视化工具的前置处理层。

    #安装

    通过 Mooncakes 安装:

    moon add Ridge-Lab/moonwavkit@0.1.3

    本地开发:

    moon check moon test moon run cmd/main moon run examples/basic

    #最小示例

    test "parse decode analyze wav" {
    let bytes = @moonwavkit.fixture_pcm16_mono()
    let parsed = @moonwavkit.parse_wav(bytes)
    assert_true(parsed.ok)
    let decoded = @moonwavkit.decode_pcm(bytes, parsed.wav)
    assert_true(decoded.ok)
    let stats = @moonwavkit.analyze_audio(decoded.float_buffer)
    assert_true(stats.peak >= 0.999)
    }

    #CLI 示例

    默认输出 text 报告:

    moon run cmd/main

    输出 JSON smoke report:

    moon run cmd/main -- --json

    最小示例:

    moon run examples/basic

    #API 摘要

    分类API
    解析parse_wav(bytes), validate_wav(bytes), validate_wav_detailed(bytes)
    解码decode_pcm(bytes, wav), parse_and_decode(bytes)
    统计analyze_audio(buffer), summarize_waveform(buffer, buckets), channel_stats(buffer)
    PCM 工具apply_gain, normalize_peak, trim_silence, resample_linear, encode_float_to_pcm_bytes, build_wav_from_float
    元数据collect_info_catalog, collect_cue_timeline, describe_wav, chunk_table_to_text
    区段分析segment_audio, silence_regions, clipping_regions, audio_segmentation_to_text
    质量inspect_audio_quality, quality_profile_to_text, recommended_quality_action
    验收fixture_catalog, run_fixture_catalog, fixture_catalog_passed, support_matrix_to_text
    报告build_report, validation_report_to_text, quality_profile_to_text, region_summary_csv

    完整接口说明见 docs/API.md,架构与扩展约束见 docs/ARCHITECTURE.md

    #项目定位

    MoonWavKit 的目标是补齐 MoonBit 生态中“原生音频文件解析与 PCM 基础处理”能力。它可以作为游戏资源检查器、可视化工具、教学 demo、WASM 音频应用和自动化测试 fixture 的底层库。

    本项目为原创 MoonBit 开源库;自带 WAV fixture 均由代码生成,不包含第三方音频素材。

    安全边界和漏洞报告方式见 SECURITY.md,参与开发规范见 CONTRIBUTING.md

    AmplitudeBin

    pub(all) struct AmplitudeBin {
    index : Int
    lower : Double
    upper : Double
    count : Int
    } derive(Eq,
    Debug
    )

    AmplitudeBin::empty

    fn AmplitudeBin::empty(index : Int) -> AmplitudeBin

    AmplitudeHistogram

    pub(all) struct AmplitudeHistogram {
    bins : Array[AmplitudeBin]
    sample_count : Int
    bin_count : Int
    } derive(Eq,
    Debug
    )

    AmplitudeHistogram::empty

    AmplitudeHistogram::is_valid

    fn AmplitudeHistogram::is_valid(self : AmplitudeHistogram) -> Bool

    AudioFingerprint

    pub(all) struct AudioFingerprint {
    frame_count : Int
    sample_rate : Int
    channels : Int
    peak_milli : Int
    rms_milli : Int
    zero_crossings : Int
    checksum : Int
    } derive(Eq,
    Debug
    )

    AudioFingerprint::empty

    AudioRegion

    pub(all) struct AudioRegion {
    kind : AudioRegionKind
    start_frame : Int
    frame_count : Int
    channels : Int
    sample_rate : Int
    peak : Double
    rms : Double
    } derive(Eq,
    Debug
    )

    AudioRegion::contains_frame

    fn AudioRegion::contains_frame(self : AudioRegion, frame : Int) -> Bool

    AudioRegion::duration_seconds

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

    AudioRegion::empty

    AudioRegion::end_frame

    fn AudioRegion::end_frame(self : AudioRegion) -> Int

    AudioRegion::is_valid

    fn AudioRegion::is_valid(self : AudioRegion) -> Bool

    AudioRegionKind

    pub(all) enum AudioRegionKind {
    RegionSilence
    RegionQuiet
    RegionSignal
    RegionLoud
    RegionClipping
    } derive(Eq,
    Debug
    )

    AudioRegionKind::is_problem

    fn AudioRegionKind::is_problem(self : AudioRegionKind) -> Bool

    AudioRegionKind::label

    fn AudioRegionKind::label(self : AudioRegionKind) -> String

    AudioSegmentOptions

    pub(all) struct AudioSegmentOptions {
    silence_threshold : Double
    quiet_threshold : Double
    loud_threshold : Double
    clipping_threshold : Double
    min_region_frames : Int
    } derive(Eq,
    Debug
    )

    AudioSegmentOptions::default

    AudioSegmentOptions::game_asset

    AudioSegmentOptions::with_min_region_frames

    fn AudioSegmentOptions::with_min_region_frames(self : AudioSegmentOptions, min_region_frames : Int) -> AudioSegmentOptions

    AudioSegmentation

    pub(all) struct AudioSegmentation {
    ok : Bool
    regions : Array[AudioRegion]
    source_frames : Int
    channels : Int
    sample_rate : Int
    } derive(Eq,
    Debug
    )

    AudioSegmentation::coverage_ratio

    fn AudioSegmentation::coverage_ratio(self : AudioSegmentation, kind : AudioRegionKind) -> Double

    AudioSegmentation::empty

    AudioSegmentation::frames_for_kind

    fn AudioSegmentation::frames_for_kind(self : AudioSegmentation, kind : AudioRegionKind) -> Int

    AudioSegmentation::longest_region

    fn AudioSegmentation::longest_region(self : AudioSegmentation) -> AudioRegion

    AudioSegmentation::longest_region_of_kind

    fn AudioSegmentation::longest_region_of_kind(self : AudioSegmentation, kind : AudioRegionKind) -> AudioRegion

    AudioSegmentation::problem_count

    fn AudioSegmentation::problem_count(self : AudioSegmentation) -> Int

    AudioSegmentation::region_count

    fn AudioSegmentation::region_count(self : AudioSegmentation) -> Int

    AudioStats

    pub(all) struct AudioStats {
    duration_seconds : Double
    frame_count : Int
    sample_count : Int
    peak : Double
    rms : Double
    silent_samples : Int
    clipped_samples : Int
    dc_offset : Double
    } derive(Eq,
    Debug
    )

    AudioStats::empty

    fn AudioStats::empty() -> AudioStats

    AudioStats::has_clipping

    fn AudioStats::has_clipping(self : AudioStats) -> Bool

    AudioStats::silence_ratio

    fn AudioStats::silence_ratio(self : AudioStats) -> Double

    BufferComparison

    pub(all) struct BufferComparison {
    comparable : Bool
    sample_count : Int
    max_abs_error : Double
    mean_abs_error : Double
    equal_with_tolerance : Bool
    error : WavError
    } derive(Eq,
    Debug
    )

    BufferComparison::failure

    BufferComparison::success

    fn BufferComparison::success(sample_count : Int, max_abs_error : Double, mean_abs_error : Double, equal_with_tolerance : Bool) -> BufferComparison

    BufferMixResult

    pub(all) struct BufferMixResult {
    ok : Bool
    mixed_frames : Int
    buffer : FloatBuffer
    error : WavError
    } derive(Eq,
    Debug
    )

    BufferMixResult::failure

    fn BufferMixResult::failure(error : WavError) -> BufferMixResult

    BufferMixResult::success

    ByteEncodeResult

    pub(all) struct ByteEncodeResult {
    ok : Bool
    encoding : PcmEncoding
    bytes : Array[Int]
    error : WavError
    } derive(Eq,
    Debug
    )

    ByteEncodeResult::failure

    fn ByteEncodeResult::failure(encoding : PcmEncoding, error : WavError) -> ByteEncodeResult

    ByteEncodeResult::success

    fn ByteEncodeResult::success(encoding : PcmEncoding, bytes : Array[Int]) -> ByteEncodeResult

    ByteReader

    pub(all) struct ByteReader {
    bytes : Array[Int]
    offset : Int
    } derive(Eq,
    Debug
    )

    Non-owning reader over an integer byte array. Values outside 0..255 are masked.

    ByteReader::at

    fn ByteReader::at(bytes : Array[Int], offset : Int) -> ByteReader

    ByteReader::byte_at

    fn ByteReader::byte_at(self : ByteReader, offset : Int) -> Int

    ByteReader::can_read

    fn ByteReader::can_read(self : ByteReader, count : Int) -> Bool

    ByteReader::fourcc_at

    fn ByteReader::fourcc_at(self : ByteReader, offset : Int) -> String

    ByteReader::i16_le_at

    fn ByteReader::i16_le_at(self : ByteReader, offset : Int) -> Int

    ByteReader::i24_le_at

    fn ByteReader::i24_le_at(self : ByteReader, offset : Int) -> Int

    ByteReader::i32_le_at

    fn ByteReader::i32_le_at(self : ByteReader, offset : Int) -> Int

    ByteReader::length

    fn ByteReader::length(self : ByteReader) -> Int

    ByteReader::matches_ascii

    fn ByteReader::matches_ascii(self : ByteReader, offset : Int, a : Int, b : Int, c : Int, d : Int) -> Bool

    ByteReader::new

    fn ByteReader::new(bytes : Array[Int]) -> ByteReader

    ByteReader::remaining

    fn ByteReader::remaining(self : ByteReader) -> Int

    ByteReader::slice_can_read

    fn ByteReader::slice_can_read(self : ByteReader, offset : Int, count : Int) -> Bool

    ByteReader::u16_le_at

    fn ByteReader::u16_le_at(self : ByteReader, offset : Int) -> Int

    ByteReader::u24_le_at

    fn ByteReader::u24_le_at(self : ByteReader, offset : Int) -> Int

    ByteReader::u32_le_at

    fn ByteReader::u32_le_at(self : ByteReader, offset : Int) -> Int

    ChannelStats

    pub(all) struct ChannelStats {
    channel : Int
    peak : Double
    rms : Double
    average : Double
    silent_samples : Int
    clipped_samples : Int
    } derive(Eq,
    Debug
    )

    ChannelStats::empty

    fn ChannelStats::empty(channel : Int) -> ChannelStats

    ChunkSummary

    pub(all) struct ChunkSummary {
    id : String
    offset : Int
    data_offset : Int
    size : Int
    known : Bool
    } derive(Eq,
    Debug
    )

    ChunkSummary::from_chunk

    fn ChunkSummary::from_chunk(chunk : WaveChunk) -> ChunkSummary

    CuePoint

    pub(all) struct CuePoint {
    id : Int
    position : Int
    sample_offset : Int
    } derive(Eq,
    Debug
    )

    CuePoint::empty

    fn CuePoint::empty() -> CuePoint

    CuePoint::is_valid

    fn CuePoint::is_valid(self : CuePoint) -> Bool

    CuePoint::new

    fn CuePoint::new(id : Int, position : Int, sample_offset : Int) -> CuePoint

    CueTimeline

    pub(all) struct CueTimeline {
    count : Int
    first_sample : Int
    last_sample : Int
    sample_rate : Int
    duration_seconds : Double
    cue_points : Array[CuePoint]
    } derive(Eq,
    Debug
    )

    CueTimeline::empty

    fn CueTimeline::empty() -> CueTimeline

    CueTimeline::is_empty

    fn CueTimeline::is_empty(self : CueTimeline) -> Bool

    DecodeOptions

    pub(all) struct DecodeOptions {
    normalize : Bool
    clamp : Bool
    target_channels : Int
    } derive(Eq,
    Debug
    )

    DecodeOptions::is_valid

    fn DecodeOptions::is_valid(self : DecodeOptions) -> Bool

    DecodeOptions::new

    fn DecodeOptions::new(normalize? : Bool, clamp? : Bool, target_channels? : Int) -> DecodeOptions

    DecodeResult

    pub(all) struct DecodeResult {
    ok : Bool
    pcm : PcmBuffer
    float_buffer : FloatBuffer
    error : WavError
    } derive(Eq,
    Debug
    )

    DecodeResult::failure

    fn DecodeResult::failure(error : WavError) -> DecodeResult

    DecodeResult::success

    fn DecodeResult::success(pcm : PcmBuffer, float_buffer : FloatBuffer) -> DecodeResult

    FixtureCase

    pub(all) struct FixtureCase {
    name : String
    bytes : Array[Int]
    expectation : FixtureExpectation
    expected_error : String
    } derive(Eq,
    Debug
    )

    FixtureCase::new

    fn FixtureCase::new(name : String, bytes : Array[Int], expectation : FixtureExpectation, expected_error? : String) -> FixtureCase

    FixtureCaseResult

    pub(all) struct FixtureCaseResult {
    name : String
    passed : Bool
    expectation : String
    actual_error : String
    frames : Int
    channels : Int
    sample_rate : Int
    } derive(Eq,
    Debug
    )

    FixtureCaseResult::new

    fn FixtureCaseResult::new(name : String, passed : Bool, expectation : String, actual_error : String, frames : Int, channels : Int, sample_rate : Int) -> FixtureCaseResult

    FixtureExpectation

    pub(all) enum FixtureExpectation {
    FixtureShouldPass
    FixtureShouldFailValidation
    FixtureShouldFailDecode
    } derive(Eq,
    Debug
    )

    FixtureExpectation::label

    fn FixtureExpectation::label(self : FixtureExpectation) -> String

    FloatBuffer

    pub(all) struct FloatBuffer {
    channels : Int
    sample_rate : Int
    samples : Array[Double]
    } derive(Eq,
    Debug
    )

    FloatBuffer::duration_seconds

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

    FloatBuffer::empty

    fn FloatBuffer::empty() -> FloatBuffer

    FloatBuffer::frame_count

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

    FloatBuffer::is_valid

    fn FloatBuffer::is_valid(self : FloatBuffer) -> Bool

    FloatBuffer::new

    fn FloatBuffer::new(channels : Int, sample_rate : Int, samples : Array[Double]) -> FloatBuffer

    FormatSummary

    pub(all) struct FormatSummary {
    encoding : String
    channels : Int
    sample_rate : Int
    bits_per_sample : Int
    frame_count : Int
    duration_seconds : Double
    byte_rate : Int
    data_bytes : Int
    } derive(Eq,
    Debug
    )

    FormatSummary::empty

    FrameRange

    pub(all) struct FrameRange {
    start_frame : Int
    frame_count : Int
    } derive(Eq,
    Debug
    )

    FrameRange::end_frame

    fn FrameRange::end_frame(self : FrameRange) -> Int

    FrameRange::is_valid

    fn FrameRange::is_valid(self : FrameRange) -> Bool

    FrameRange::new

    fn FrameRange::new(start_frame : Int, frame_count : Int) -> FrameRange

    InfoCatalog

    pub(all) struct InfoCatalog {
    title : String
    artist : String
    comment : String
    software : String
    raw_tags : Array[InfoTag]
    } derive(Eq,
    Debug
    )

    InfoCatalog::display_title

    fn InfoCatalog::display_title(self : InfoCatalog) -> String

    InfoCatalog::empty

    fn InfoCatalog::empty() -> InfoCatalog

    InfoCatalog::has_metadata

    fn InfoCatalog::has_metadata(self : InfoCatalog) -> Bool

    InfoTag

    pub(all) struct InfoTag {
    key : String
    value : String
    } derive(Eq,
    Debug
    )

    InfoTag::empty

    fn InfoTag::empty() -> InfoTag

    InfoTag::is_valid

    fn InfoTag::is_valid(self : InfoTag) -> Bool

    InfoTag::new

    fn InfoTag::new(key : String, value : String) -> InfoTag

    LoopResult

    pub(all) struct LoopResult {
    ok : Bool
    repeats : Int
    source_range : FrameRange
    buffer : FloatBuffer
    error : WavError
    } derive(Eq,
    Debug
    )

    LoopResult::failure

    fn LoopResult::failure(error : WavError) -> LoopResult

    LoopResult::success

    fn LoopResult::success(repeats : Int, source_range : FrameRange, buffer : FloatBuffer) -> LoopResult

    NormalizeReport

    pub(all) struct NormalizeReport {
    ok : Bool
    gain : Double
    target_peak : Double
    before_peak : Double
    after_peak : Double
    buffer : FloatBuffer
    error : WavError
    } derive(Eq,
    Debug
    )

    NormalizeReport::failure

    fn NormalizeReport::failure(error : WavError) -> NormalizeReport

    NormalizeReport::success

    fn NormalizeReport::success(gain : Double, target_peak : Double, before_peak : Double, buffer : FloatBuffer) -> NormalizeReport

    ParsedWav

    pub(all) struct ParsedWav {
    header : RiffHeader
    format : WaveFormat
    chunks : Array[WaveChunk]
    info_tags : Array[InfoTag]
    cue_points : Array[CuePoint]
    fact_sample_count : Int
    data_offset : Int
    data_size : Int
    source_length : Int
    } derive(Eq,
    Debug
    )

    ParsedWav::empty

    fn ParsedWav::empty() -> ParsedWav

    ParsedWav::has_chunk

    fn ParsedWav::has_chunk(self : ParsedWav, id : String) -> Bool

    ParsedWav::info

    fn ParsedWav::info(self : ParsedWav) -> WaveInfo

    ParsedWav::is_complete

    fn ParsedWav::is_complete(self : ParsedWav) -> Bool

    PcmBuffer

    pub(all) struct PcmBuffer {
    channels : Int
    sample_rate : Int
    bits_per_sample : Int
    samples : Array[Int]
    } derive(Eq,
    Debug
    )

    PcmBuffer::duration_seconds

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

    PcmBuffer::empty

    fn PcmBuffer::empty() -> PcmBuffer

    PcmBuffer::frame_count

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

    PcmBuffer::is_valid

    fn PcmBuffer::is_valid(self : PcmBuffer) -> Bool

    PcmBuffer::new

    fn PcmBuffer::new(channels : Int, sample_rate : Int, bits_per_sample : Int, samples : Array[Int]) -> PcmBuffer

    PcmEncoding

    pub(all) enum PcmEncoding {
    PcmU8
    PcmS16
    PcmS24
    PcmS32
    } derive(Eq,
    Debug
    )

    PcmEncoding::bits_per_sample

    fn PcmEncoding::bits_per_sample(self : PcmEncoding) -> Int

    PcmEncoding::label

    fn PcmEncoding::label(self : PcmEncoding) -> String

    QualityFinding

    pub(all) struct QualityFinding {
    kind : QualityFindingKind
    severity : ValidationSeverity
    message : String
    value : Double
    } derive(Eq,
    Debug
    )

    QualityFinding::new

    fn QualityFinding::new(kind : QualityFindingKind, severity : ValidationSeverity, message : String, value? : Double) -> QualityFinding

    QualityFindingKind

    pub(all) enum QualityFindingKind {
    QualityOk
    QualityClipping
    QualityMostlySilent
    QualityVeryQuiet
    QualityDcOffset
    QualityHighCrest
    QualityHighZeroCrossing
    } derive(Eq,
    Debug
    )

    QualityFindingKind::label

    fn QualityFindingKind::label(self : QualityFindingKind) -> String

    QualityProfile

    pub(all) struct QualityProfile {
    ok : Bool
    score : Int
    stats : AudioStats
    crest_factor : Double
    zero_crossing_rate : Double
    findings : Array[QualityFinding]
    } derive(Eq,
    Debug
    )

    QualityProfile::empty

    QualityProfile::has_warnings

    fn QualityProfile::has_warnings(self : QualityProfile) -> Bool

    ReportFormat

    pub(all) enum ReportFormat {
    ReportText
    ReportJson
    } derive(Eq,
    Debug
    )

    ReportFormat::label

    fn ReportFormat::label(self : ReportFormat) -> String

    ResampleResult

    pub(all) struct ResampleResult {
    ok : Bool
    source_sample_rate : Int
    target_sample_rate : Int
    source_frames : Int
    target_frames : Int
    buffer : FloatBuffer
    error : WavError
    } derive(Eq,
    Debug
    )

    ResampleResult::failure

    fn ResampleResult::failure(error : WavError) -> ResampleResult

    ResampleResult::success

    fn ResampleResult::success(source_sample_rate : Int, target_sample_rate : Int, source_frames : Int, buffer : FloatBuffer) -> ResampleResult

    RiffHeader

    pub(all) struct RiffHeader {
    riff_id : String
    file_size_minus_8 : Int
    wave_id : String
    } derive(Eq,
    Debug
    )

    RiffHeader::empty

    fn RiffHeader::empty() -> RiffHeader

    RiffHeader::is_valid

    fn RiffHeader::is_valid(self : RiffHeader) -> Bool

    SampleRegion

    pub(all) struct SampleRegion {
    start : Int
    length : Int
    threshold : Double
    } derive(Eq,
    Debug
    )

    SampleRegion::end_exclusive

    fn SampleRegion::end_exclusive(self : SampleRegion) -> Int

    SampleRegion::is_valid

    fn SampleRegion::is_valid(self : SampleRegion) -> Bool

    SampleRegion::new

    fn SampleRegion::new(start : Int, length : Int, threshold? : Double) -> SampleRegion

    SupportEntry

    pub(all) struct SupportEntry {
    encoding : String
    bits_per_sample : Int
    can_parse : Bool
    can_decode : Bool
    can_encode : Bool
    notes : String
    } derive(Eq,
    Debug
    )

    SupportEntry::new

    fn SupportEntry::new(encoding : String, bits_per_sample : Int, can_parse : Bool, can_decode : Bool, can_encode : Bool, notes : String) -> SupportEntry

    SupportEntry::status

    fn SupportEntry::status(self : SupportEntry) -> String

    TrimResult

    pub(all) struct TrimResult {
    ok : Bool
    start_frame : Int
    end_frame : Int
    removed_start_frames : Int
    removed_end_frames : Int
    buffer : FloatBuffer
    error : WavError
    } derive(Eq,
    Debug
    )

    TrimResult::failure

    fn TrimResult::failure(error : WavError) -> TrimResult

    TrimResult::success

    fn TrimResult::success(start_frame : Int, end_frame : Int, source_frames : Int, buffer : FloatBuffer) -> TrimResult

    ValidationIssue

    pub(all) struct ValidationIssue {
    severity : ValidationSeverity
    code : String
    message : String
    offset : Int
    } derive(Eq,
    Debug
    )

    ValidationIssue::is_error

    fn ValidationIssue::is_error(self : ValidationIssue) -> Bool

    ValidationIssue::new

    fn ValidationIssue::new(severity : ValidationSeverity, code : String, message : String, offset? : Int) -> ValidationIssue

    ValidationReport

    pub(all) struct ValidationReport {
    ok : Bool
    error_count : Int
    warning_count : Int
    info_count : Int
    format : WaveFormat
    info : WaveInfo
    issues : Array[ValidationIssue]
    chunks : Array[ChunkSummary]
    } derive(Eq,
    Debug
    )

    ValidationReport::empty

    ValidationReport::has_errors

    fn ValidationReport::has_errors(self : ValidationReport) -> Bool

    ValidationReport::has_warnings

    fn ValidationReport::has_warnings(self : ValidationReport) -> Bool

    ValidationSeverity

    pub(all) enum ValidationSeverity {
    SeverityInfo
    SeverityWarning
    SeverityError
    } derive(Eq,
    Debug
    )

    ValidationSeverity::label

    fn ValidationSeverity::label(self : ValidationSeverity) -> String

    WavError

    pub(all) struct WavError {
    kind : WavErrorKind
    offset : Int
    message : String
    } derive(Eq,
    Debug
    )

    WavError::code

    fn WavError::code(self : WavError) -> String

    WavError::is_error

    fn WavError::is_error(self : WavError) -> Bool

    WavError::new

    fn WavError::new(kind : WavErrorKind, message : String, offset? : Int) -> WavError

    WavError::none

    fn WavError::none() -> WavError

    WavErrorKind

    pub(all) enum WavErrorKind {
    ErrorNone
    ErrorTooShort
    ErrorNotRiff
    ErrorNotWave
    ErrorChunkOutOfBounds
    ErrorMissingFormat
    ErrorMissingData
    ErrorUnsupportedFormat
    ErrorInvalidFormat
    ErrorTruncatedData
    ErrorInvalidArgument
    } derive(Eq,
    Debug
    )

    Error categories returned by the parser, decoder, validator, and CLI model.

    WavErrorKind::code

    fn WavErrorKind::code(self : WavErrorKind) -> String

    WavParseResult

    pub(all) struct WavParseResult {
    ok : Bool
    wav : ParsedWav
    error : WavError
    } derive(Eq,
    Debug
    )

    WavParseResult::failure

    fn WavParseResult::failure(error : WavError) -> WavParseResult

    WavParseResult::is_ok

    fn WavParseResult::is_ok(self : WavParseResult) -> Bool

    WavParseResult::success

    WavReport

    pub(all) struct WavReport {
    ok : Bool
    title : String
    encoding : String
    channels : Int
    sample_rate : Int
    bits_per_sample : Int
    duration_seconds : Double
    frame_count : Int
    chunk_count : Int
    peak : Double
    rms : Double
    quality : String
    error_code : String
    } derive(Eq,
    Debug
    )

    WavReport::empty

    fn WavReport::empty() -> WavReport

    WavReport::failure

    fn WavReport::failure(error_code : String) -> WavReport

    WavReport::render

    fn WavReport::render(self : WavReport, format : ReportFormat) -> String

    WavReport::to_json

    fn WavReport::to_json(self : WavReport) -> String

    WavReport::to_text

    fn WavReport::to_text(self : WavReport) -> String

    WaveChunk

    pub(all) struct WaveChunk {
    id : String
    offset : Int
    data_offset : Int
    size : Int
    padded_size : Int
    } derive(Eq,
    Debug
    )

    WaveChunk::contains

    fn WaveChunk::contains(self : WaveChunk, offset : Int) -> Bool

    WaveChunk::empty

    fn WaveChunk::empty() -> WaveChunk

    WaveChunk::end_offset

    fn WaveChunk::end_offset(self : WaveChunk) -> Int

    WaveChunk::is_known

    fn WaveChunk::is_known(self : WaveChunk) -> Bool

    WaveChunk::new

    fn WaveChunk::new(id : String, offset : Int, data_offset : Int, size : Int) -> WaveChunk

    WaveEncoding

    pub(all) enum WaveEncoding {
    EncodingUnknown
    EncodingPcm
    EncodingIeeeFloat
    EncodingALaw
    EncodingMuLaw
    EncodingExtensible
    } derive(Eq,
    Debug
    )

    WaveEncoding::label

    fn WaveEncoding::label(self : WaveEncoding) -> String

    WaveFormat

    pub(all) struct WaveFormat {
    audio_format : Int
    encoding : WaveEncoding
    channels : Int
    sample_rate : Int
    byte_rate : Int
    block_align : Int
    bits_per_sample : Int
    extra_size : Int
    } derive(Eq,
    Debug
    )

    WaveFormat::bytes_per_sample

    fn WaveFormat::bytes_per_sample(self : WaveFormat) -> Int

    WaveFormat::empty

    fn WaveFormat::empty() -> WaveFormat

    WaveFormat::expected_block_align

    fn WaveFormat::expected_block_align(self : WaveFormat) -> Int

    WaveFormat::expected_byte_rate

    fn WaveFormat::expected_byte_rate(self : WaveFormat) -> Int

    WaveFormat::is_float

    fn WaveFormat::is_float(self : WaveFormat) -> Bool

    WaveFormat::is_pcm

    fn WaveFormat::is_pcm(self : WaveFormat) -> Bool

    WaveFormat::is_supported

    fn WaveFormat::is_supported(self : WaveFormat) -> Bool

    WaveFormat::is_valid

    fn WaveFormat::is_valid(self : WaveFormat) -> Bool

    WaveFormat::new

    fn WaveFormat::new(audio_format : Int, channels : Int, sample_rate : Int, byte_rate : Int, block_align : Int, bits_per_sample : Int, extra_size? : Int) -> WaveFormat

    WaveInfo

    pub(all) struct WaveInfo {
    duration_seconds : Double
    frame_count : Int
    sample_count : Int
    data_bytes : Int
    } derive(Eq,
    Debug
    )

    WaveInfo::empty

    fn WaveInfo::empty() -> WaveInfo

    WaveInfo::is_valid

    fn WaveInfo::is_valid(self : WaveInfo) -> Bool

    WaveformBucket

    pub(all) struct WaveformBucket {
    index : Int
    min : Double
    max : Double
    average_abs : Double
    } derive(Eq,
    Debug
    )

    WaveformBucket::empty

    fn WaveformBucket::empty(index : Int) -> WaveformBucket

    WaveformPoint

    pub(all) struct WaveformPoint {
    index : Int
    start_frame : Int
    end_frame : Int
    min : Double
    max : Double
    rms : Double
    } derive(Eq,
    Debug
    )

    WaveformPoint::empty

    fn WaveformPoint::empty(index : Int) -> WaveformPoint

    WaveformSummary

    pub(all) struct WaveformSummary {
    buckets : Array[WaveformBucket]
    bucket_count : Int
    source_samples : Int
    } derive(Eq,
    Debug
    )

    WaveformSummary::empty

    WaveformSummary::is_valid

    fn WaveformSummary::is_valid(self : WaveformSummary) -> Bool

    amplitude_histogram

    fn amplitude_histogram(buffer : FloatBuffer, bins : Int) -> AmplitudeHistogram

    analyze_audio

    fn analyze_audio(buffer : FloatBuffer) -> AudioStats

    append_buffers

    fn append_buffers(a : FloatBuffer, b : FloatBuffer) -> BufferMixResult

    apply_gain

    fn apply_gain(buffer : FloatBuffer, gain : Double) -> FloatBuffer

    audio_fingerprint

    fn audio_fingerprint(buffer : FloatBuffer) -> AudioFingerprint

    audio_segmentation_to_text

    fn audio_segmentation_to_text(report : AudioSegmentation) -> String

    buffers_are_close

    fn buffers_are_close(expected : FloatBuffer, actual : FloatBuffer, tolerance? : Double) -> Bool

    build_report

    fn build_report(bytes : Array[Int]) -> WavReport

    build_wav_from_float

    fn build_wav_from_float(buffer : FloatBuffer, encoding? : PcmEncoding) -> ByteEncodeResult

    channel_stats

    fn channel_stats(buffer : FloatBuffer, silence_threshold? : Double, clip_threshold? : Double) -> Array[ChannelStats]

    chunk_table_to_text

    fn chunk_table_to_text(wav : ParsedWav) -> String

    clamp_buffer

    fn clamp_buffer(buffer : FloatBuffer) -> FloatBuffer

    clipping_regions

    fn clipping_regions(buffer : FloatBuffer, min_region_frames? : Int, threshold? : Double) -> Array[AudioRegion]

    collect_cue_timeline

    fn collect_cue_timeline(wav : ParsedWav) -> CueTimeline

    collect_info_catalog

    fn collect_info_catalog(wav : ParsedWav) -> InfoCatalog

    compare_buffers

    fn compare_buffers(expected : FloatBuffer, actual : FloatBuffer, tolerance? : Double) -> BufferComparison

    comparison_to_text

    fn comparison_to_text(comparison : BufferComparison) -> String

    crest_factor

    fn crest_factor(buffer : FloatBuffer) -> Double

    cue_sample_offsets

    fn cue_sample_offsets(wav : ParsedWav) -> Array[Int]

    cue_timeline_to_text

    fn cue_timeline_to_text(timeline : CueTimeline) -> String

    cue_times_seconds

    fn cue_times_seconds(wav : ParsedWav) -> Array[Double]

    decode_pcm

    fn decode_pcm(bytes : Array[Int], wav : ParsedWav, options? : DecodeOptions) -> DecodeResult

    describe_wav

    fn describe_wav(wav : ParsedWav) -> String

    detect_silence_regions

    fn detect_silence_regions(buffer : FloatBuffer, min_run : Int, threshold? : Double) -> Array[WaveChunk]

    detect_silence_sample_regions

    fn detect_silence_sample_regions(buffer : FloatBuffer, min_run : Int, threshold? : Double) -> Array[SampleRegion]

    downmix_to_mono

    fn downmix_to_mono(buffer : FloatBuffer) -> FloatBuffer

    encode_float_to_pcm_bytes

    fn encode_float_to_pcm_bytes(buffer : FloatBuffer, encoding : PcmEncoding) -> ByteEncodeResult

    encoding_from_code

    fn encoding_from_code(code : Int) -> WaveEncoding

    find_clipping_regions

    fn find_clipping_regions(buffer : FloatBuffer, min_run? : Int, threshold? : Double) -> Array[SampleRegion]

    fixture_catalog

    fn fixture_catalog() -> Array[FixtureCase]

    fixture_catalog_passed

    fn fixture_catalog_passed() -> Bool

    fixture_catalog_report

    fn fixture_catalog_report() -> String

    fixture_float32_mono

    fn fixture_float32_mono() -> Array[Int]

    fixture_low_sample_rate

    fn fixture_low_sample_rate() -> Array[Int]

    fixture_missing_data

    fn fixture_missing_data() -> Array[Int]

    fixture_not_riff

    fn fixture_not_riff() -> Array[Int]

    fixture_pcm16_mono

    fn fixture_pcm16_mono() -> Array[Int]

    fixture_pcm24_mono

    fn fixture_pcm24_mono() -> Array[Int]

    fixture_pcm32_mono

    fn fixture_pcm32_mono() -> Array[Int]

    fixture_pcm8_stereo

    fn fixture_pcm8_stereo() -> Array[Int]

    fixture_quality_clipped

    fn fixture_quality_clipped() -> Array[Int]

    fixture_riff_size_mismatch

    fn fixture_riff_size_mismatch() -> Array[Int]

    fixture_stereo_phase_test

    fn fixture_stereo_phase_test() -> Array[Int]

    fixture_tiny_silence

    fn fixture_tiny_silence() -> Array[Int]

    fixture_truncated_data

    fn fixture_truncated_data() -> Array[Int]

    fixture_unsupported_alaw

    fn fixture_unsupported_alaw() -> Array[Int]

    fixture_with_info_and_cue

    fn fixture_with_info_and_cue() -> Array[Int]

    fixture_with_unknown_chunk

    fn fixture_with_unknown_chunk() -> Array[Int]

    frame_slice

    fn frame_slice(buffer : FloatBuffer, start_frame : Int, frame_count : Int) -> FloatBuffer

    has_info_tag

    fn has_info_tag(wav : ParsedWav, key : String) -> Bool

    info_tag_value

    fn info_tag_value(wav : ParsedWav, key : String) -> String?

    inspect_audio_quality

    fn inspect_audio_quality(buffer : FloatBuffer) -> QualityProfile

    loop_region

    fn loop_region(buffer : FloatBuffer, start_frame : Int, frame_count : Int, repeats : Int) -> LoopResult

    make_silence

    fn make_silence(channels : Int, sample_rate : Int, frames : Int) -> FloatBuffer

    mix_buffers

    fn mix_buffers(a : FloatBuffer, b : FloatBuffer, gain_a? : Double, gain_b? : Double) -> BufferMixResult

    normalize_peak

    fn normalize_peak(buffer : FloatBuffer, target_peak? : Double) -> NormalizeReport

    pad_buffer

    fn pad_buffer(buffer : FloatBuffer, left_frames? : Int, right_frames? : Int) -> FloatBuffer

    parse_and_decode

    fn parse_and_decode(bytes : Array[Int], options? : DecodeOptions) -> DecodeResult

    parse_and_describe

    fn parse_and_describe(bytes : Array[Int]) -> String

    parse_wav

    fn parse_wav(bytes : Array[Int]) -> WavParseResult

    Parse a RIFF/WAVE byte array into structural metadata. The parser skips unknown chunks while preserving their id and bounds.

    quality_profile_to_text

    fn quality_profile_to_text(profile : QualityProfile) -> String

    fn recommended_quality_action(profile : QualityProfile) -> String

    region_summary_csv

    fn region_summary_csv(report : AudioSegmentation) -> String

    render_waveform_text

    fn render_waveform_text(buffer : FloatBuffer, points? : Int, width? : Int) -> String

    resample_linear

    fn resample_linear(buffer : FloatBuffer, target_sample_rate : Int) -> ResampleResult

    reverse_audio

    fn reverse_audio(buffer : FloatBuffer) -> FloatBuffer

    run_fixture_case

    fn run_fixture_case(case : FixtureCase) -> FixtureCaseResult

    run_fixture_catalog

    fn run_fixture_catalog() -> Array[FixtureCaseResult]

    segment_audio

    fn segment_audio(buffer : FloatBuffer, options? : AudioSegmentOptions) -> AudioSegmentation

    silence_regions

    fn silence_regions(buffer : FloatBuffer, min_region_frames? : Int, threshold? : Double) -> Array[AudioRegion]

    slice_seconds

    fn slice_seconds(buffer : FloatBuffer, start_seconds : Double, duration_seconds : Double) -> FloatBuffer

    split_channel

    fn split_channel(buffer : FloatBuffer, channel : Int) -> Array[Double]

    stats_quality_label

    fn stats_quality_label(stats : AudioStats) -> String

    summarize_format

    fn summarize_format(wav : ParsedWav) -> FormatSummary

    summarize_waveform

    fn summarize_waveform(buffer : FloatBuffer, buckets : Int) -> WaveformSummary

    support_matrix_to_text

    fn support_matrix_to_text() -> String

    supported_format_matrix

    fn supported_format_matrix() -> Array[SupportEntry]

    trim_silence

    fn trim_silence(buffer : FloatBuffer, threshold? : Double, keep_frames? : Int) -> TrimResult

    validate_wav

    fn validate_wav(bytes : Array[Int]) -> WavError

    validate_wav_detailed

    fn validate_wav_detailed(bytes : Array[Int]) -> ValidationReport

    validation_report_to_text

    fn validation_report_to_text(report : ValidationReport) -> String

    waveform_points

    fn waveform_points(buffer : FloatBuffer, points : Int) -> Array[WaveformPoint]

    wavinfo_fixture_report

    fn wavinfo_fixture_report(format? : ReportFormat) -> String

    zero_crossing_count

    fn zero_crossing_count(buffer : FloatBuffer) -> Int

    zero_crossing_rate

    fn zero_crossing_rate(buffer : FloatBuffer) -> Double