Source code for mosqito.sound_level_meter.freq_band_synthesis

# -*- coding: utf-8 -*-

# Standard library import
from numpy import (
    array,
    concatenate,
    zeros,
    log10,
    power,
    argmin,
    split,
    arange,
    interp,
    iscomplex,
)


[docs] def freq_band_synthesis(spectrum, freqs, fmin, fmax): """Adapt input spectrum to frequency band levels Convert the input spectrum to frequency band spectrum between "fmin" and "fmax". Parameters ---------- spectrum : numpy.ndarray One-sided spectrum of the signal in [dB], size (nperseg, nseg). freqs : list List of input frequency , size (nperseg) or (nperseg, nseg). fmin : float Min frequency band [Hz]. fmax : float Max frequency band [Hz]. n : int Number of bands pr octave. G : int System for specifying the exact geometric mean frequencies. Can be base 2 or base 10. fr : int Reference frequency. Shall be set to 1 kHz for audible frequency range, to 1 Hz for infrasonic range (f < 20 Hz) and to 1 MHz for ultrasonic range (f > 31.5 kHz). Outputs ------- spec : numpy.ndarray Third octave band spectrum of signal sig [dB re.2e-5 Pa], size (nbands, nseg). fpref : numpy.ndarray Corresponding preferred third octave band center frequencies, size (nbands). """ if iscomplex(spectrum).any(): raise ValueError("Input spectrum must be in dB, no complex value allowed.") if fmin.min() < freqs.min(): print( "[WARNING] Input spectrum minimum frequency if higher than fmin. Empty values will be filled with 0." ) df = freqs[1] - freqs[0] spectrum = interp(arange(fmin.min(), fmax.max() + df, df), freqs, spectrum) freqs = arange(fmin.min(), fmax.max() + df, df) if fmax.max() > freqs.max(): print( "[WARNING] Input spectrum maximum frequency if lower than fmax. Empty values will be filled with 0." ) df = freqs[1] - freqs[0] spectrum = interp(arange(fmin.min(), fmax.max() + df, df), freqs, spectrum) freqs = arange(fmin.min(), fmax.max() + df, df) # Find the lower and upper index of each band idx_low = argmin(abs(freqs[:, None] - fmin), axis=0) idx_up = argmin(abs(freqs[:, None] - fmax), axis=0) idx = concatenate((idx_low, [idx_up[-1]])) # Split the given spectrum in several bands bands = array(split(spectrum, idx), dtype=object)[1:-1] # Compute the bands level band_spectrum = zeros((len(bands))) i = 0 for s in bands: band_spectrum[i] = 10 * log10(sum(power(10, s / 10))) i += 1 return band_spectrum, (fmin + fmax) / 2