Show HN: Rust 语言编写的 SIMD Viterbi 解码器
Show HN: SIMD Viterbi Decoder in Rust

原始链接: https://github.com/brian-armstrong/fec

此 Rust crate 提供高性能的前向纠错(FEC)功能,专为软件定义无线电(SDR)和卫星通信而设计。它实现了两种主要的编码方案: * **卷积码:** 支持多种编码率(1/2 到 1/8)和约束长度(k=4 到 k=16)的维特比(Viterbi)译码(硬判决和软判决)。在 Rust nightly 版本上,它利用 SIMD(SSE/AVX2/AVX512)来获得卓越的性能。 * **里德-所罗门码(Reed-Solomon Codes):** 实现了 GF(2⁸) 错误和删除译码,包括与常规和双基表示下的 CCSDS (255,223) 标准码完全兼容。 作为 `libcorrect` 和 `libfec` 等传统 C 库的现代替代品,此 crate 与 Phil Karn 的 `libfec` 位兼容。它提供了一个 `fec-shim` crate,为现有的代码库提供直接替换的 C ABI。该库遵循已发布的 CCSDS 标准,并以 BSD-3-Clause 许可证发布。未来计划改进的功能包括支持打孔码(punctured codes)、硬判决删除以及扩展里德-所罗门域宽(最高可达 GF(2¹⁶))。

相关文章

原文

Crates.io Docs.rs CI

Forward error correction for SDR, space, and satellite applications.

fec implements two error-correcting codes that show up throughout software-defined radio and spacecraft links:

  • Convolutional codes with a Viterbi decoder (hard and soft decision), including the common rate-1/2 k=7, rate-1/2 k=9, rate-1/3 k=9, and rate-1/6 k=15 codes. Supports any rate from 1/2 to 1/8 and any order from k=4 to k=16. On nightly Rust, the simd feature enables a Viterbi decoder with acceleration on SSE/AVX2/AVX512.
  • Reed–Solomon codes over GF(2⁸) with error and erasure decoding, including the standard CCSDS (255,223) code in both the conventional and the on-the-wire dual-basis (Berlekamp) representations.

fec started as and draws heavy inspiration from the author's own libcorrect, a C library for forward error correction. This crate also credits Phil Karn's libfec C library for offering an original implementation of these codes, although this crate does not borrow any source or have any relationship with that library, and the name is purely coincidental.

Standard parameters (primitive polynomials, the CCSDS dual-basis transform) are derived from the published CCSDS standard (CCSDS 131.0-B, Annex D for the dual basis).

use fec::{ConvEncoder, ConvDecoder};

// Rate-1/2, order-7 NASA code.
let polys = [0o161, 0o127];
let mut enc = ConvEncoder::new(2, 7, &polys);
let mut dec = ConvDecoder::new(2, 7, &polys);

let msg = b"hello, error correction";
let mut encoded = vec![0u8; enc.encode_len(msg.len())];
let num_bits = enc.encode(msg, &mut encoded).unwrap();

// ... encoded is corrupted in transit ...

let mut recovered = vec![0u8; msg.len()];
dec.decode_hard(&encoded, num_bits, &mut recovered).unwrap();

decode_soft takes 8-bit soft symbols instead, which corrects more errors when the demodulator can report its confidence.

use fec::{RsEncoder, RsDecoder};

// Standard CCSDS (255,223) code.
let mut enc = RsEncoder::new_ccsds();
let mut dec = RsDecoder::new_ccsds();

let msg: Vec<u8> = (0..223).collect();
let mut block = vec![0u8; 255];
enc.encode(&msg, &mut block).unwrap();

// ... block is corrupted in transit ...

let mut recovered = vec![0u8; 223];
let corrected = dec.decode(&block, &mut recovered).unwrap();
println!("corrected {corrected} symbol error(s)");

For real spacecraft telemetry (dual-basis symbols on the wire), use encode_ccsds_dual / decode_ccsds_dual.

The codes are bit-compatible with libfec (Phil Karn, KA9Q), so fec can decode data Karn's library produced and vice versa. A companion shim crate, fec-shim, exposes fec under libfec's C ABI (init_rs_char, create_viterbi27, encode_rs_ccsds, etc) as a drop-in for existing C codebases. With the simd feature enabled (requires nightly), this crate is more performant than either libcorrect or libfec on x86.

  • More widths for the Reed-Solomon encoder/decoder (narrower than GF(2⁸) and as wide as GF(2¹⁶))
  • Hard-decision erasures in the convolutional (Viterbi) decoder
  • Punctured codes for the convolutional encoder and decoder

BSD-3-Clause.

联系我们 contact @ memedata.com