Source code for mosqito.sound_level_meter.comp_spectrum
# -*- coding: utf-8 -*-
from numpy import tile, hanning, blackman, concatenate, arange, abs
from numpy.fft import fft
# local function import
from mosqito.utils import amp2db
[docs]
def comp_spectrum(signal,fs, nfft='default', window='hanning', one_sided=True, db=True):
"""
Compute one-sided spectrum from a time signal in Pa.
Parameters
----------
signal : array
A time signal (nperseg x nseg).
fs : integer
Sampling frequency.
db : boolean, optional
Indicates if the spectrum is in dB values. Default is True.
Returns
-------
spectrum : array
Spectrum (freq_axis x nseg).
freq_axis : array
Frequency axis.
See also
--------
.noct_synthesis : Conversion of a spectrum to n-th octave band levels
.noct_spectrum : N-th octave band spectrum computation from a time signal
.spectrum2dBA : Conversion of a spectrum from dB to dBA
Examples
--------
.. plot::
:include-source:
>>> from mosqito.sound_level_meter import comp_spectrum
>>> import matplotlib.pyplot as plt
>>> import numpy as np
>>> fs=48000
>>> d=0.2
>>> dB=60
>>> time = np.arange(0, d, 1/fs)
>>> f = 1000
>>> stimulus = 1 + 0.5*np.sin(2 * np.pi * f * time) + 0.1*np.sin(20 * np.pi * f * time)
>>> rms = np.sqrt(np.mean(np.power(stimulus, 2)))
>>> ampl = 0.00002 * np.power(10, dB / 20) / rms
>>> stimulus = stimulus * ampl
>>> spec_db, freq_axis = comp_spectrum(stimulus, fs, db=True)
>>> plt.step(freq_axis, spec_db)
>>> plt.xlabel("Center frequency [Hz]")
>>> plt.ylabel("Amplitude [dB]")
"""
if len(signal.shape)>1:
nseg = signal.shape[1]
else:
nseg = 1
# Number of points for the fft
if nfft == 'default':
if len(signal.shape) == 1:
nfft = len(signal)
else :
nfft = signal.shape[0]
# Window definition
if window == 'hanning':
window = hanning(nfft)
elif window == 'blackman':
window = blackman(nfft)
# Amplitude correction
window = window / sum(window)
if len(signal.shape)>1:
window = tile(window,(nseg,1)).T
# Creation of the spectrum by FFT
if one_sided == True:
spectrum = fft(signal * window, n=nfft, axis=0)[0:nfft//2] * 1.42
freq_axis = arange(1, nfft//2+1, 1) * (fs / nfft)
else:
spectrum = fft(signal * window, n=nfft, axis=0) * 1.42
freq_axis = concatenate((arange(1, nfft//2+1, 1) * (fs / nfft), arange(nfft//2+1, 1, -1) * (fs / nfft)))
if db == True:
# Conversion into dB level
module = abs(spectrum)
spectrum = amp2db(module, ref=0.00002)
return spectrum, freq_axis