LASP 1.0
Library for Acoustic Signal Processing
Loading...
Searching...
No Matches
lasp_weighcal.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3"""
4Weighting and calibration filter in one
5@author: J.A. de Jong - ASCEE
6"""
7from .lasp_common import FreqWeighting
8from .filter import SPLFilterDesigner
9from lasp.lasp_config import ones, empty
10from .wrappers import FilterBank
11import numpy as np
12
13__all__ = ['WeighCal']
14
15
17 """
18 Frequency weighting and calibration FIR filter
19 """
20
21 def __init__(self, fw=FreqWeighting.default,
22 nchannels=1,
23 fs=48000.,
24 calfile=None):
25 """
26 Initialize the frequency weighting and calibration FIR filters.
27
28 Args:
29 fw: Frequency weighting to apply
30 nchannels: Number of channels for the input data
31 fs: Sampling frequency [Hz]
32 calfile: Calibration file to load.
33 """
34
35 self.nchannels = nchannels
36 self.fs = fs
37 self.fw = fw
38
39 self.calfile = calfile
40
41 # Frequencies used for the filter design
42 freq_design = np.linspace(0, 17e3, 3000)
43 freq_design[-1] = fs/2
44
45 # Objective function for the frequency response
46 frp_obj = self.frpObj(freq_design)
47
48 P = 2048 # Filter length (number of taps)
49
50 self._firs = np.empty((P, self.nchannels))
51 self._fbs = []
52 for chan in range(self.nchannels):
53 fir = arbitrary_fir_design(fs, P, freq_design,
54 frp_obj[:, chan],
55 window='rectangular')
56 self._firs[:, chan] = fir
57
58 self._fbs.append(FilterBank(fir[:, np.newaxis], 2*P))
59
60 self._freq_design = freq_design
61
62 def filter_(self, data):
63 """
64 Filter data using the calibration and frequency weighting filter.
65
66 Args:
67 data: (Weighted) raw time data that needs to be filtered, should
68 have the same number of columns as the number of channels. First
69 axis is assumed to be the time axis
70
71 Retuns:
72 Filtered data for each channel
73
74 """
75 nchan = self.nchannels
76 assert data.ndim == 2
77 assert data.shape[1] == nchan
78 assert data.shape[0] > 0
79
80 filtered = []
81 for chan in range(nchan):
82 filtered.append(self._fbs[chan].filter_(data[:, [chan]])[:, 0])
83 filtered = np.asarray(filtered).transpose()
84 if filtered.ndim == 1:
85 filtered = filtered[:, np.newaxis]
86 return filtered
87
88 def frpCalObj(self, freq_design):
89 """
90 Computes the objective frequency response of the calibration filter
91 """
92 calfile = self.calfile
93 if calfile is not None:
94 cal = np.loadtxt(calfile, skiprows=2)
95 freq = cal[:, 0]
96 cal = cal[:, 1:]
97 if cal.shape[1] != self.nchannels:
98 raise ValueError('Number of channels in calibration file does'
99 ' not equal to given number of channels')
100 calfac = 10**(-cal/20)
101 filter_calfac = empty((freq_design.shape[0], self.nchannels))
102
103 for chan in range(self.nchannels):
104 filter_calfac[:, chan] = np.interp(freq_design, freq,
105 calfac[:, chan])
106
107 else:
108 filter_calfac = ones((freq_design.shape[0], self.nchannels,))
109
110 return filter_calfac
111
112 def frpWeightingObj(self, freq_design):
113 """
114 Computes the objective frequency response of the frequency weighting
115 filter.
116 """
117 fw = self.fw
118 if fw == FreqWeighting.A:
119 return A(freq_design)
120 elif fw == FreqWeighting.C:
121 return C(freq_design)
122 elif fw == FreqWeighting.Z:
123 return ones(freq_design.shape[0])
124 else:
125 raise ValueError('Invalid fw parameter')
126
127 def frpObj(self, freq_design):
128 """
129 Combines the frequency weighting and the calibration filter into
130 one frequency response objective function.
131 """
132 # Objective function for the frequency response
133 frp_objective = self.frpCalObj(freq_design) * \
134 self.frpWeightingObj(freq_design)[:, np.newaxis]
135 frp_objective[-1] = 0.
136
137 return frp_objective
138
139 def freqResponse(self, chan=0, freq=None):
140 """
141 Returns the frequency response of the designed FIR filter
142 """
143 if freq is None:
144 freq = np.logspace(1, np.log10(self.fs/2), 500)
145 return (freq, frp(self.fs, freq, self._firs[chan]),
146 self.frpObj(freq)[:, chan])
Frequency weighting and calibration FIR filter.
__init__(self, fw=FreqWeighting.default, nchannels=1, fs=48000., calfile=None)
Initialize the frequency weighting and calibration FIR filters.
filter_(self, data)
Filter data using the calibration and frequency weighting filter.
frpWeightingObj(self, freq_design)
Computes the objective frequency response of the frequency weighting filter.
frpCalObj(self, freq_design)
Computes the objective frequency response of the calibration filter.
frpObj(self, freq_design)
Combines the frequency weighting and the calibration filter into one frequency response objective fun...
Author: J.A.
Definition lasp_config.py:1