nearlink_sdr.phy.multitone 源代码

"""多音信号生成器 -- TXS-10002-2025 标准 6.2.1.3

基带多音信号: S(t) = sum_{i=1}^{N} A_i * exp(j * (omega_i * t + phi_i))

标准规定 N = 1, 2, 4, 8, 各音等幅、等间隔、对称分布。
测量信号 2 (6.2.4.2) 引用本模块生成多音波形。
"""

from __future__ import annotations

__all__ = [
    "MultitoneConfig",
    "generate_multitone",
    "multitone_peak_to_avg_ratio",
]


from dataclasses import dataclass

import numpy as np

# ---------------------------------------------------------------------------
# 6.2.4.2 多音信号参数表
# ---------------------------------------------------------------------------

# 初始相位集合 (弧度), 按 N 和 set 索引
# N=2: 固定 phi=[0, 0]
# N=4: Set 1 / Set 2
# N=8: Set 1 / Set 2

MULTITONE_PHASE_SETS: dict[int, dict[int, list[float]]] = {
    2: {
        1: [0.0, 0.0],
    },
    4: {
        1: [1.81, 0.0, 0.0, 1.81],
        2: [4.47, 0.0, 0.0, 4.47],
    },
    8: {
        1: [5.40, 3.84, 0.91, 0.0, 0.0, 0.91, 3.84, 5.40],
        2: [0.88, 2.45, 5.37, 0.0, 0.0, 5.37, 2.45, 0.88],
    },
}

# SLE 带宽 (MHz) -> N -> 相邻音频率间隔 delta_f (MHz)
DELTA_F_TABLE: dict[int, dict[int, float]] = {
    1: {2: 0.5, 4: 0.25, 8: 0.125},
    2: {2: 1.0, 4: 0.5, 8: 0.25},
    4: {2: 2.0, 4: 1.0, 8: 0.5},
}


[文档] @dataclass class MultitoneConfig: """多音信号配置。""" n_tones: int = 1 # 音的个数 (1/2/4/8) sle_bandwidth_mhz: int = 1 # SLE 带宽 (1/2/4 MHz) phase_set: int = 1 # 相位集合 (1 或 2, N>=4 时有效) amplitude: float = 1.0 # 各音等幅 sample_rate_hz: float = 8e6 # 采样率 (Hz) @property def delta_f_hz(self) -> float: """相邻音频率间隔 (Hz)。""" if self.n_tones == 1: return 0.0 return DELTA_F_TABLE[self.sle_bandwidth_mhz][self.n_tones] * 1e6 @property def frequencies_hz(self) -> list[float]: """各音的基带频率列表 (Hz), 中心对称分布。""" if self.n_tones == 1: return [0.0] df = self.delta_f_hz n = self.n_tones # 对称分布: -(N/2-0.5)*df, ..., -0.5*df, +0.5*df, ..., +(N/2-0.5)*df return [(-n / 2 + i + 0.5) * df for i in range(n)] @property def phases_rad(self) -> list[float]: """各音的初始相位 (rad)。""" if self.n_tones == 1: return [0.0] return MULTITONE_PHASE_SETS[self.n_tones][self.phase_set]
[文档] def generate_multitone( config: MultitoneConfig, duration_s: float, ) -> np.ndarray: """生成基带多音信号 (复数采样)。 :param config: 多音信号配置. :param duration_s: 信号持续时间 (秒). :returns: 复数基带采样序列, shape=(num_samples,). """ num_samples = int(config.sample_rate_hz * duration_s) t = np.arange(num_samples) / config.sample_rate_hz freqs = config.frequencies_hz phases = config.phases_rad signal = np.zeros(num_samples, dtype=np.complex128) for i in range(config.n_tones): signal += config.amplitude * np.exp( 1j * (2 * np.pi * freqs[i] * t + phases[i]) ) return signal
[文档] def multitone_peak_to_avg_ratio(config: MultitoneConfig) -> float: """计算多音信号的峰均比 (线性)。 对于等幅多音, 理论最大 PAPR = N (所有音同相叠加时). """ return float(config.n_tones)