Search code examples
unetstack

How do i record JANUS signal as wav file?


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 ?


Solution

  • 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