1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Author: BolivarTech
// Version: 1.0.0
// Date: 2026-07-02
//! # `viterbi` — CCSDS convolutional encoder + block Viterbi (MLSE) decoder.
//!
//! This crate is the **inner code** of the classic CCSDS concatenated coding scheme, designed to pair
//! with an outer Reed–Solomon code via an interleaver:
//!
//! ```text
//! TX: data → [RS(255,223)] → [interleaver] → [conv. K=7] → CHANNEL
//! RX: CHANNEL → [Viterbi] → [de-interleaver] → [RS decode] → data
//! └── this crate
//! ```
//!
//! ## Feature set (`v0.2.x`)
//! - **Hard-decision** block encode/decode ([`HardHamming`], [`CcsdsViterbiDecoder::decode_block`]) —
//! the first-class CCSDS `K = 7`, `R = 1/2` path.
//! - **Soft-decision** decoding over quantized `i8` LLRs ([`SoftLlr`], [`CcsdsSoftDecoder`]) for the
//! ≈ 2 dB coding gain, validated by a BER-vs-Eb/N0 sweep (see `examples/ber_curve`).
//! - **Rate-1/3** mother code (`d_free = 14`) via [`CodeParams::ccsds_r1_3`] and the `n`-generic trellis.
//! - **Puncturing** to rates 2/3, 3/4, 5/6, 7/8 as a separable wrapping layer over both mother codes
//! ([`Puncturer`] / [`DePuncturer`], puncture matrix as runtime data).
//! - **Generic constraint length** `K ≤ 9` via the const-generic state count (`K = 7` stays first-class);
//! preconfigured codes are discoverable through [`CodeProfile`].
//!
//! All new capability is **additive**: the released hard-decision `R = 1/2`, `K = 7` public API and
//! behaviour are unchanged. Streaming, concatenation, `no_std`/MCU, and SOVA remain for later minors.
//!
//! ## Design invariants
//! - Pure Rust, no `unsafe` (`forbid`ed crate-wide via `Cargo.toml` lints and here).
//! - Deterministic: same input ⇒ same output, bit-for-bit, on every platform.
//! - No panic in the decode hot path; `Result` only at configuration boundaries.
//!
//! # Examples
//!
//! Encode a payload, then recover it with the Viterbi decoder (clean channel):
//!
//! ```
//! use viterbi::{CcsdsViterbiDecoder, CodeParams, ViterbiEncoder};
//!
//! // Build the encoder and decoder from the first-class CCSDS profile.
//! let encoder = ViterbiEncoder::new(CodeParams::ccsds_r1_2()).unwrap();
//! let mut decoder = CcsdsViterbiDecoder::new(CodeParams::ccsds_r1_2(), 4096).unwrap();
//!
//! let payload = b"hello, viterbi";
//! let coded = encoder.encode(payload).unwrap();
//! let decoded = decoder.decode_block(&coded).unwrap();
//!
//! assert_eq!(&decoded.bytes, payload);
//! ```
/// Constraint length.
pub const K: u8 = 7;
/// Memory (shift-register length) = K - 1.
pub const M: u8 = 6;
/// Trellis states for the CCSDS profile = 2^M.
pub const STATES: usize = 1 << M;
/// Output bits per input bit (rate 1/2).
pub const N: usize = 2;
/// Hard upper bound on `max_info_bits` (R18).
pub const MAX_SUPPORTED_INFO_BITS: usize = 1_000_000;
pub
// Flat public API: re-export the primary types at the crate root.
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;