use super::Extension;
use comnum_channel::multipath::Taps;
use comnum_math::linalg::CMat;
mod fading;
mod mimo;
mod ofdm;
use fading::{CdlBlock, CdlSpec, Rayleigh, RayleighSpec, TdlBlock, TdlSpec};
use mimo::{Detection, DetectorSpec, MimoRx, MimoTx, MimoTxSpec};
use ofdm::{OfdmRx, OfdmRxSpec, OfdmTx, OfdmTxSpec};
#[derive(Clone, Debug)]
pub enum Csi {
Flat {
h: Vec<CMat>,
coherence: usize,
},
Taps(Taps),
}
impl Csi {
fn flat(&self, n: usize) -> Option<&CMat> {
match self {
Csi::Flat { h, coherence } => h.get(n / (*coherence).max(1)).or_else(|| h.last()),
Csi::Taps(_) => None,
}
}
}
pub use comnum_waveform::ofdm::link::OfdmFrame;
pub(super) fn blocks() -> Vec<Extension> {
vec![
builtin!(
"mimo_tx",
"Spread the symbols over n_tx antennas: spatial multiplexing (power 1/n_tx per antenna) or Alamouti's code.",
MimoTxSpec,
needs [Samples],
gives [],
|q, _, _| Ok(Box::new(MimoTx::new(&q)?)),
),
builtin!(
"rayleigh",
"Flat fading y = H x on every antenna; records the channel for a genie-aided receiver.",
RayleighSpec,
needs[Samples],
gives[Csi],
|q, _, _| Ok(Box::new(Rayleigh { p: q })),
),
builtin!(
"tdl",
"Tapped-delay-line multipath fading with Clarke/Jakes Doppler; records the taps for a genie-aided receiver.",
TdlSpec,
needs[Samples],
gives[Csi],
|q, _, _| Ok(Box::new(TdlBlock::new(&q)?)),
),
builtin!(
"cdl",
"Clustered delay line of 3GPP TR 38.901 between uniform linear arrays (one tap per cluster, random ray phases and coupling); records the taps for a genie-aided receiver.",
CdlSpec,
needs[Samples],
gives[Csi],
|q, _, _| Ok(Box::new(CdlBlock::new(&q)?)),
),
builtin!(
"ofdm_tx",
"Map every antenna's symbols on resource grids with pilots and OFDM-modulate them (power K/(LN) per sample).",
OfdmTxSpec,
needs[Samples],
gives[Ofdm],
|q, _, _| Ok(Box::new(OfdmTx::new(&q)?)),
),
builtin!(
"ofdm_rx",
"Demodulate the OFDM grids, estimate the channel and detect every data resource element; output the symbols and their noise variances.",
OfdmRxSpec,
needs [Samples, Constellation, Ofdm],
gives [Noise, Llr],
|q, _, _| Ok(Box::new(OfdmRx::new(&q)?)),
),
builtin!(
"mimo_rx",
"Detect a single-carrier link over flat fading with the known channel; output the symbols and their noise variances.",
DetectorSpec,
needs [Samples, Constellation, Csi],
gives [Noise, Llr],
|q, _, _| Ok(Box::new(MimoRx(Detection::new(&q)?))),
),
]
}
#[cfg(test)]
mod tests;