How do i record JANUS signal as wav file?

320 views Asked by At

I am testing an interoperability between modems. one of my modem did support JANUS and I believe UnetStack base Subnero Modem Phy[3] also support JANUS. How can i send and record JANUS signal which i can use for preliminary testing for other modem ? Can someone please provide basic snippet ?

2

There are 2 answers

1
Mandar Chitre On BEST ANSWER

UnetStack indeed has an implementation of JANUS that is, by default, configured on phy[3].

You can check this on your modem (the sample outputs here are from unet audio SDOAM, and so your modem parameters might vary somewhat):

> 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

(I have dropped a few parameters that are not relevant to the discussion here to keep the output concise)

The key parameters to take note of:

  • modulation = fhbfsk and janus = true setup the modulation for JANUS
  • fmin = 9520.0, fstep = 160.0 and hops = 13 are the modulation parameters to setup fhbfsk as required by JANUS
  • fec = 7 chooses ICONV2 from the fecList, as required by JANUS
  • threshold = 0.0 indicates that reception of JANUS frames is disabled

NOTE: If your modem is a Subnero M25 series, the standard JANUS band is out of the modem's ~20-30 kHz operating band. In that case, the JANUS scheme is auto-configured to a higher frequency (which you will see as fmin in your modem). Do note that this frequency is important to match for interop with any other modem that might support JANUS at a higher frequency band.

To enable JANUS reception, you need to:

phy[3].threshold = 0.3

To avoid any other detections from CONTROL and DATA packets, we might want to disable those:

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

At this point, you could make a transmission by typing phy << new TxJanusFrameReq() and put a hydrophone next to the modem to record the transmitted signal as a wav file.

However, I'm assuming you would prefer to record on the modem itself, rather than with an external hydrophone. To do that, you can enable the loopback mode on the modem, and set up the modem to record the received signal:

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

Now if you do a transmission, you should see a RxBasebandSignalNtf with the captured signal:

> 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)]

That notification has your signal in baseband complex format. You can save it to a file:

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

To convert to a wav file, you'll need to load this signal and convert to passband. Here's some example Python code to do this:

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)

NOTE: You will need to replace the fd and fc of 12000 respectively, by whatever is the fs and fc fields in your modem's RxBasebandSignalNtf. For Unet audio, it is 12000 for both, but for Subnero M25 series modems it is probably 24000.

Now you have your wav file at 96 kSa/s!

You could also plot a spectrogram to check if you wanted to:

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

JANUS frame spectrogram

1
Jay Patel On
  • I have an issue while recording the signal. Modem refuse to send the JANUS frame. It looks like something is not correctly set on my end, specially fmin = 12000.0 , fstep = 160.0 and hops = 13. The Actual modem won't let me set the fmin to 9520.0 and automatically configured on lowest fmin = 12000. How can i calculate corresponding parameters for fmin=12000.
  • Although your suggestion do work on the unet audio.

Here is my modem logs:

> 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