9 个版本

0.4.0 2024年2月24日
0.3.0 2023年4月23日
0.2.5 2023年2月26日
0.2.3 2022年9月23日
0.1.0 2021年7月31日

#96 in 硬件支持

Download history 82/week @ 2024-03-09 11/week @ 2024-03-30 5/week @ 2024-05-25 111/week @ 2024-06-01 8/week @ 2024-06-08 2/week @ 2024-06-15

每月 121 次下载
samedec 中使用

MIT/Apache

305KB
4.5K SLoC

sameold: SAME/EAS 解调

为您的桌面或 RPi 提供空中的天气警报。

此包为 特定区域消息编码 (SAME) 提供数字解调器和解码器。它可以检测音频信号中是否存在 SAME 消息,并将它们报告给调用者。

免责声明

此包同时受 MIT 和 Apache 2.0 许可。请仔细阅读这些许可证,因为它们可能会影响您的权利。

此包未经过作为天气收音机接收器或任何其他用途的认证。作者 强烈反对 在任何安全关键应用中使用。始终至少有两种接收天气警报的方法。

示例

完整的示例可以在我们的 samedec 包中找到,该包提供通过管道解码 SAME 的命令行程序。

解调和解码

您首先需要从广播 SAME 信号电台恢复 基带音频。获取您通常会听到的音频信号。您可以使用以下任一方法:

  • 收音机、扫描仪或其他接收器的音频“线路输出”插孔;或者
  • 软件定义的无线电

在任一情况下,获取音频超出了此包的范围。为了采样您的声卡,请尝试 cpal。如果您有立体声信号,首先将其混合为单声道。如果您正在解调宽带 FM,并且您的解调器提供了选择,请选择仅单声道解调。

use sameold::{Message, SameReceiverBuilder};

// Create a SameReceiver with your audio sampling rate
// Sound cards typically run at 44100 Hz or 48000 Hz. Use
// an input rate of at least 8000 Hz.
let mut rx = SameReceiverBuilder::new(48000)
    .with_agc_bandwidth(0.05)        // AGC bandwidth at symbol rate, < 1.0
    .with_agc_gain_limits(1.0/(i16::MAX as f32), 1.0/200.0)  // for i16
    .with_squelch_power(0.10, 0.05)  // squelch open/close power, 0.0 < power < 1.0
    .with_preamble_max_errors(2)     // bit error limit when detecting sync sequence
    .build();

// let audiosrc be an iterator which outputs audio samples,
// such as a BufReader bound to stdin or a file, in f32
// format at the sampling rate (here 48000 Hz)
let audiosrc = some_audio_source_iterator();
for msg in rx.iter_messages(audiosrc) {
    match msg {
        Message::StartOfMessage(hdr) => {
            println!("begin SAME voice message: {}", hdr);
        }
        Message::EndOfMessage => {
            println!("end SAME voice message");
        }
    }
}

通过 构建器 创建数字接收器。

SameReceiver 通过迭代器绑定到任何 f32 PCM 单声道(1通道)音频样本的来源。如果您使用的是 i16 样本(如大多数声卡所做的那样),则需要将它们转换为 f32。只要您正确配置AGC,就不需要缩放,如上所述。

iter_messages() 迭代器消耗尽可能多的样本,直到解码下一个 Message

调制解调器行为

脉冲数 解码策略
1 快速EOM / NNNN
2 错误检测(相等检查)
3 错误校正(比特投票)

SAME消息始终以单独的“脉冲”形式传输三次,以提高冗余。在解码消息 标题ZCZC)时,samedec 将使用所有三个脉冲,以改进解码——如果可能的话。

如果错过一次重传,samedec 将自动回退到只使用两个脉冲进行解码。解码器对所有接收到的标题施加约 1.311秒 的延迟。这种延迟通常不会造成问题,因为大多数SAME消息都带有非信息性的警报音,作为前缀。

消息 尾部 不受标题相同的错误校正过程和延迟的影响。消息结束指示符(NNNN)将在接收到并解码后立即打印。

调制解调器包含重复抑制逻辑。在彼此之间大约 10.86秒 的窗口内到达的相同消息将被抑制并不会发出。

调制解调器分为两部分

  1. 链路层”,将模拟波形转换为帧化的 Burst

  2. 以及“传输层”,将单个 Bursts 组装成 Messages

可以使用 iter_events() 方法捕获来自这两层的所有事件,而不是 iter_messages()。事件迭代器可以用来获取原始的帧化 脉冲,而不会延迟或进行错误校正。事件还可以在消息解码之前和期间报告检测到SAME载波信号。

解释消息

Message 类型标志着SAME消息的开始或结束。SAME消息的“实际消息”部分是音频本身,它应该包含描述事件并给出听众指示的语音消息。

  • 描述事件;
  • 并为听众提供指示。

这个crate解码数字标题和尾部,它们总结了消息。一个示例标题,以ASCII格式接收“off the wire”,如下所示

ZCZC-WXR-RWT-012345-567890-888990+0015-0321115-KLOX/NWS-

如果这是接收到的标题字符串,那么您可以像以下示例那样解码前面的 hdr

use sameold::{Phenomenon, Originator, SignificanceLevel};

// what organization originated the message?
assert_eq!(Originator::NationalWeatherService, hdr.originator());

// parse SAME event code `RWT`
let evt = hdr.event();

//   the Phenomenon describes what is occurring
assert_eq!(Phenomenon::RequiredWeeklyTest, evt.phenomenon());

//   the SignificanceLevel indicates the overall severity and/or
//   how intrusive or noisy the alert should be
assert_eq!(SignificanceLevel::Test, evt.significance());
assert!(SignificanceLevel::Test < SignificanceLevel::Warning);

//   Display to the user
assert_eq!("Required Weekly Test", &format!("{}", evt));

// location codes are accessed by iterator
let first_location = hdr.location_str_iter().next();
assert_eq!(Some("012345"), first_location);

相同的消息总是传输三次以提高冗余。在解码消息头时,sameold 将使用所有三次传输来提高解码。对于所有三个头部传输,只输出一个 Message::StartOfMessage。标记消息结束的尾迹 受此错误纠正过程的影响。对于每个接收到的尾迹,输出一个 Message::EndOfMessage。对于每个完整的 SAME 消息,可能有最多三个 EndOfMessage 输出。

背景

SAME 通常用于在美国和加拿大分发天气警报。最初是为与携带模拟音频信号的广播电台一起使用而开发的,例如

这些电台参与一个称为紧急警报系统的紧急警报网络,该系统向公众传播警报。

SAME 消息作为纯音频消息替换电台的正常节目传输。SAME 消息包括一个数字头,将其与电台的正常节目区分开来。数字头也以带内方式发送——使用模拟调制来保留它。SAME 头部使用双极性频率键控 (FSK) 调制,并以 520.83 Hz 的波特率发送。

箱子功能

  • chrono:使用 chrono 计算消息 发行时间 和其他字段作为真正的 UTC 时间戳。如果启用,chrono 成为此箱子的公共 API 的一部分。

MSRV 政策

最小支持的 Rust 版本 (MSRV) 的增加将被视为小版本升级。

贡献

如果您有一份您认为应该解调但未解调的信号的 录音,请在新 github 问题上打开。要么附加或链接到您的录音。

在打开任何问题或 PR 之前,请阅读我们的 贡献指南

许可:MIT OR Apache-2.0

依赖项

~7–14MB
~169K SLoC