Skip to content

subnero1/subnerotools.js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

subnerotools.js

A library of commonly used JavaScript tools for Subnero, providing utilities for underwater acoustic modem configuration and digital signal processing.

Features

  • Modem Model Parser - Parse and generate model codes for Subnero Gen4 and Gen4X underwater acoustic modems
  • DSP Functions - Compute power spectral density (PSD) and spectrograms for audio signal analysis

Installation

npm install

Modules

1. Modem Model Parser

Parse and manipulate Subnero underwater acoustic modem model codes (Gen4, Gen4X, and UnetCube).

Quick Start

import { ModemModel } from './src/modem-model.js';

// Parse a Gen4 modem model code
const modem = new ModemModel("WNC-S60HSS4");
console.log(modem.spectrum);          // "HF"
console.log(modem.frequency);         // "60000"
console.log(modem.edition);           // "Silver"
console.log(modem.configuration);     // "Standalone"
console.log(modem.generation);        // "4"
console.log(modem.bulkheadConnector); // "DBH13F"
console.log(modem.hullMaterial);      // "aluminum"
console.log(modem.depthRating);       // 300

// Parse a Gen4X modem model code
const modemX = new ModemModel("WNC-M25MSS4X");
console.log(modemX.generation);       // "4X"
console.log(modemX.channels);         // 1
console.log(modemX.storage);          // 256

Features

  • Parse model codes into structured data (edition, configuration, hardware specs)
  • Generate model codes from configuration objects
  • Support for Gen4, Gen4X, and UnetCube modem generations
  • Decode customization codes (hull rating, storage, transducers, etc.)
  • Handle project codes and prototype variants
  • Validate model code format

Supported Model Ranges

  • HF Band: S60H (60 kHz), S40H (40 kHz)
  • MF Band: M25M (24 kHz)
  • LF Band: L12L (12 kHz), L5L (5 kHz)
  • UnetCube: X (multi-band)

API Reference

Constructor

new ModemModel(modelString)

Static Methods

  • ModemModel.getGeneration(model) - Get generation from model string ("4", "4X", or "5")

Instance Properties

  • productLine - Product line (e.g., "WNC")
  • range - Frequency range (e.g., "S60H", "M25M")
  • spectrum - Frequency band (e.g., "HF", "MF", "LF")
  • frequency - Operating frequency in Hz
  • edition - Edition ("Silver", "Gold", "Platinum", "Research")
  • configuration - Configuration type ("Standalone", "Embedded", "Open")
  • generation - Generation ("4", "4X", "5")
  • bulkheadConnector - Bulkhead connector type
  • transducerType - Transducer model
  • hullMaterial - Hull material ("aluminum", "steel", "titanium")
  • depthRating - Depth rating in meters
  • storage - Storage capacity in GB
  • channels - Number of receiving channels (Gen4X)
  • additionalChannels - Additional channels (Gen4)
  • coprocessor - Coprocessor type
  • projectCode - Project code if any
  • prototype - Boolean indicating prototype status

Instance Methods

  • toString() - Generate model code string from configuration

Examples

Parse model with customization

const modem = new ModemModel("WNC-S60HSS4-00010100");
console.log(modem.bulkheadConnector); // Custom connector
console.log(modem.storage);           // Custom storage

Parse model with project code

const modem = new ModemModel("WNC-M25MSS4X-PABC123");
console.log(modem.projectCode); // "ABC123"

Generate model code

const modem = new ModemModel("WNC-S60HSS4");
modem.storage = 256;
modem.depthRating = 2000;
console.log(modem.toString()); // Updated model code with customization

For complete API documentation and customization options, see the inline JSDoc comments in src/modem-model.js.


2. DSP Functions

Digital signal processing functions for computing power spectral density and spectrograms of real-valued audio signals, optimized for web-based visualization. These APIs accept plain JavaScript arrays and numeric typed arrays such as Float32Array and Float64Array.

Quick Start

import { welch, spectrogram } from './src/dsp.js';

// Generate a test signal
const fs = 1000; // 1 kHz sampling rate
const signal = Float32Array.from({ length: 2000 }, (_, i) =>
  Math.sin(2 * Math.PI * 100 * i / fs)
);

// Compute power spectral density
const psd = welch(signal, { fs, nperseg: 512 });
console.log(psd.frequencies); // Frequency bins
console.log(psd.psd);         // Power values

// Compute spectrogram
const spec = spectrogram(signal, { fs, nperseg: 256, mode: 'magnitude' });
console.log(spec.frequencies);  // Frequency bins
console.log(spec.times);        // Time bins
console.log(spec.spectrogram);  // 2D array [freq][time]

Functions

welch(signal, options)

Estimates power spectral density using Welch's method with overlapping segments.

Parameters:

  • signal (number[] | TypedArray): Input signal (real-valued)
  • options (Object):
    • fs (number, default: 1.0): Sampling frequency in Hz
    • window (string | number[] | TypedArray, default: 'hann'): Window type or custom array
    • nperseg (number, default: 256): Segment length (must be power of 2)
    • noverlap (number, default: nperseg/2): Overlap between segments
    • nfft (number, default: nperseg): FFT length (power of 2, >= nperseg)
    • detrend (string | boolean, default: 'constant'): Detrend type
    • scaling (string, default: 'density'): 'density' or 'spectrum'

Returns: {frequencies: number[], psd: number[]}

spectrogram(signal, options)

Computes time-frequency representation using short-time Fourier transform (STFT).

Parameters:

  • Same as welch(), plus:
    • noverlap (default: nperseg/8 for spectrograms)
    • mode (string, default: 'psd'): Output mode ('psd' or 'magnitude')

Returns: {frequencies: number[], times: number[], spectrogram: number[][]}

The spectrogram is a 2D array where spectrogram[f][t] gives the value at frequency index f and time index t.

Examples

Detect peak frequency

const { frequencies, psd } = welch(signal, { fs: 1000, nperseg: 1024 });
const peakIdx = psd.indexOf(Math.max(...psd));
console.log(`Peak at ${frequencies[peakIdx].toFixed(2)} Hz`);

Custom Hamming window

const nperseg = 512;
const window = new Array(nperseg).fill(0).map((_, n) =>
  0.54 - 0.46 * Math.cos(2 * Math.PI * n / (nperseg - 1))
);

const result = welch(signal, { fs: 1000, window, nperseg });

Typed-array inputs are processed directly. When the source signal is a typed array, segment extraction uses typed-array views instead of first converting the full signal into a plain array.

Time-frequency chirp analysis

// Generate chirp: frequency increases over time
const signal = new Array(2000).fill(0).map((_, i) => {
  const t = i / 1000;
  return Math.sin(2 * Math.PI * (50 + 200 * t) * t);
});

const { frequencies, times, spectrogram: spec } = spectrogram(signal, {
  fs: 1000,
  nperseg: 256,
  mode: 'magnitude'
});

// spec[f][t] shows energy distribution over time and frequency

Important Notes

  • Power-of-2 requirement: nperseg and nfft must be powers of 2 (2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, etc.) due to FFT.js requirements
  • Overlap recommendations:
    • Welch: 50% overlap (nperseg/2) optimal for Hann window
    • Spectrogram: 12.5% overlap (nperseg/8) for statistical independence
  • Scaling: 'density' returns V²/Hz, 'spectrum' returns V²
  • One-sided spectrum: Always returned for real-valued inputs (DC to Nyquist)

For complete documentation, see docs/DSP.md.

Testing

Run all tests:

deno test

Run specific module tests:

deno test src/modem-model_test.js
deno test src/dsp_test.js

Examples

Run the DSP demo:

deno run examples/dsp_demo.js

API Documentation

Dependencies

  • fft.js - Fast Fourier Transform implementation

License

MIT

Author

Chinmay Pendharkar (chinmay@subnero.com)

About

Commonly used Javascript tools for Subnero

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors