如何将 JANUS 信号记录为 wav 文件?

How do i record JANUS signal as wav file?

我正在测试调制解调器之间的互操作性。我的一个调制解调器确实支持 JANUS,我相信 UnetStack 基础 Subnero 调制解调器 Phy[3] 也支持 JANUS。我如何发送和记录可用于其他调制解调器初步测试的 JANUS 信号?有人可以提供基本片段吗?

UnetStack 确实有一个 JANUS 的实现,默认情况下,配置在 phy[3]

您可以在您的调制解调器上进行检查(此处的示例输出来自 unet audio SDOAM,因此您的调制解调器参数可能会有所不同):

> phy[3]
« PHY »

[org.arl.unet.phy.PhysicalChannelParam]
  fec = 7
  fecList ⤇ [LDPC1, LDPC2, LDPC3, LDPC4, LDPC5, LDPC6, ICONV2]
  frameDuration ⤇ 1.1
  frameLength = 8
  janus = true

[org.arl.yoda.FhbfskParam]
  chiplen = 1
  fmin = 9520.0
  fstep = 160.0
  hops = 13
  scrambler = 0
  sync = true
  tukey = true

[org.arl.yoda.ModemChannelParam]
  modulation = fhbfsk
  preamble = (2400 samples)
  threshold = 0.0

(我删除了一些与此处讨论无关的参数以保持输出简洁)

需要注意的关键参数:

  • modulation = fhbfskjanus = true 为 JANUS
  • 设置调制
  • fmin = 9520.0fstep = 160.0hops = 13 是根据 JANUS
  • 的要求设置 fhbfsk 的调制参数
  • fec = 7 根据 JANUS
  • 的要求从 fecList 中选择 ICONV2
  • threshold = 0.0 表示 JANUS 帧的接收被禁用

注意:如果您的调制解调器是 Subnero M25 系列,则标准 JANUS 频段不在调制解调器的 ~20-30 kHz 工作频段内。在这种情况下,JANUS 方案是 auto-configured 到更高的频率(您将在调制解调器中看到 fmin)。请注意,此频率对于与任何其他可能在更高频段支持 JANUS 的调制解调器进行互操作匹配很重要。

要启用 JANUS 接收,您需要:

phy[3].threshold = 0.3

为了避免来自 CONTROL 和 DATA 数据包的任何其他检测,我们可能希望禁用这些:

phy[1].threshold = 0
phy[2].threshold = 0

此时,您可以通过键入 phy << new TxJanusFrameReq() 进行传输,并将水听器放在调制解调器旁边以将传输的信号记录为 wav 文件。

但是,我假设您更愿意在调制解调器本身上录音,而不是使用外部水听器。为此,您可以在调制解调器上启用环回模式,并设置调制解调器以记录接收到的信号:

phy.loopback = true       # enable loopback
phy.fullduplex = true     # enable full duplex so we can record while transmitting
phy[3].basebandRx = true  # enable capture of received baseband signal
subscribe phy             # show notifications from phy on shell

现在,如果您进行传输,您应该会看到 RxBasebandSignalNtf 和捕获的信号:

> phy << new TxJanusFrameReq()
AGREE
phy >> RxFrameStartNtf:INFORM[type:#3 rxTime:492455709 rxDuration:1100000 detector:0.96]
phy >> TxFrameNtf:INFORM[type:#3 txTime:492456016]
phy >> RxJanusFrameNtf:INFORM[type:#3 classUserID:0 appType:0 appData:0 mobility:false canForward:true txRxFlag:true rxTime:492455708 rssi:-44.2 cfo:0.0]
phy >> RxBasebandSignalNtf:INFORM[adc:1 rxTime:492455708 rssi:-44.2 preamble:3 fc:12000.0 fs:12000.0 (13200 baseband samples)]

该通知包含基带复合格式的信号。您可以将其保存到文件中:

save 'x.txt', ntf.signal, 2

要转换为 wav 文件,您需要加载此信号并转换为通带。下面是一些示例 Python 代码来执行此操作:

import numpy as np
import scipy.io.wavfile as wav
import arlpy.signal as asig

x = np.genfromtxt('x.txt', delimiter=',')
x = x[:,0] + 1j * x[:,1]
x = asig.bb2pb(x, 12000, 12000, 96000)
wav.write('x.wav', 96000, x)

注意:您需要将 12000fdfc 分别替换为您的 fsfc 字段调制解调器 RxBasebandSignalNtf。对于 Unet 音频,两者都是 12000,但对于 Subnero M25 系列调制解调器,它可能是 24000。

现在您的 wav 文件位于 96 kSa/s!

您还可以绘制频谱图来检查您是否想要:

import arlpy.plot as plt
plt.specgram(x, fs=96000)

  • 我在录制信号时遇到问题。调制解调器拒绝发送 JANUS 帧。看起来我这边有些地方设置不正确,特别是 fmin = 12000.0fstep = 160.0hops = 13。实际调制解调器不允许我将 fmin 设置为 9520.0 并自动配置为最低 fmin = 12000。如何计算 fmin=12000.
  • 的相应参数
  • 尽管您的建议对 unet audio 有效。

这是我的调制解调器日志:

> phy[3]
« PHY »

[org.arl.unet.DatagramParam]
  MTU ⤇ 0
  RTU ⤇ 0

[org.arl.unet.phy.PhysicalChannelParam]
  dataRate ⤇ 64.0
  errorDetection ⤇ true
  fec = 7
  fecList ⤇ [LDPC1, LDPC2, LDPC3, LDPC4, LDPC5, LDPC6, ICONV2]
  frameDuration ⤇ 1.0
  frameLength = 8
  janus = true
  llr = false
  maxFrameLength ⤇ 56
  powerLevel = -10.0

[org.arl.yoda.FhbfskParam]
  chiplen = 1
  fmin = 12000.0
  fstep = 160.0
  hops = 13
  scrambler = 0
  sync = true
  tukey = true

[org.arl.yoda.ModemChannelParam]
  basebandExtra = 0
  basebandRx = true
  modulation = fhbfsk
  preamble = (2400 samples)
  test = false
  threshold = 0.3
  valid ⤇ false
> phy << new TxJanusFrameReq()
REFUSE: Frame type not setup correctly
phy >> FAILURE: Timed out