Initial commit. Deleted single pole lowpass header file

This commit is contained in:
Anne de Jong 2020-01-17 20:57:23 +01:00
parent f10e78ff41
commit 31c6fcdc22
4 changed files with 61 additions and 179 deletions

61
lasp/c/lasp_slm.h Normal file
View File

@ -0,0 +1,61 @@
// lasp_slm.h
//
// Author: J.A. de Jong - ASCEE
//
// Description: Implementation of a real time Sound Level Meter, based on
// given slm.
// //////////////////////////////////////////////////////////////////////
#pragma once
#ifndef LASP_slm_H
#define LASP_slm_H
#include "lasp_types.h"
#include "lasp_mat.h"
#include "lasp_sosfilterbank.h"
typedef struct Slm Slm;
/**
* Initializes a Sound level meter.
*
* @param fb: Sosfiterbank handle, used to pre-filter data
* @param T: Single pole low pass filter time constant to use.
*/
slm* slm_create(Sosfilterbank* fb);
/**
* Initialize the filter coeficients in the slm
*
* @param fb: slm handle
* @param filter_no: Filter number in the bank
* @param coefss: Array of filter coefficients. Should have a length of
* nsections x 6, for each of the sections, it contains (b0, b1, b2, a0,
* a1, a2), where a are the numerator coefficients and b are the denominator
* coefficients.
*
*/
void slm_setFilter(slm* fb,const us filter_no,
const vd coefs);
/**
* Filters x using h, returns y
*
* @param x Input time sequence block. Should have at least one sample.
* @return Filtered output in an allocated array. The number of
* columns in this array equals the number of filters in the
* slm. The number of output samples is equal to the number of
* input samples in x.
*/
dmat slm_filter(slm* fb,
const vd* x);
/**
* Cleans up an existing filter bank.
*
* @param f slm handle
*/
void slm_free(slm* f);
#endif // LASP_slm_H
//////////////////////////////////////////////////////////////////////

View File

@ -1,91 +0,0 @@
// lasp_sp_lowpass.c
//
// Author: J.A. de Jong -ASCEE
//
// Description:
// Single pole lowpass IIR filter implementation.
//////////////////////////////////////////////////////////////////////
#include "lasp_sp_lowpass.h"
#include "lasp_alloc.h"
typedef struct SPLowpass_s {
d a;
d b;
d xlast,ylast;
} SPLowpass;
SPLowpass* SPLowpass_create(d fs,d tau) {
fsTRACE(15);
d tau_i = 1/tau;
d T = 1/fs;
if(fs <= 0) {
WARN("Invalid sampling frequency");
return NULL;
}
else if(T >= tau ) {
WARN("Invalid tau, should be (much) larger than sampling"
" time (1/fs)");
return NULL;
}
SPLowpass* lp = a_malloc(sizeof(SPLowpass));
lp->xlast = 0;
lp->ylast = 0;
lp->a = tau_i/(2*fs+tau_i);
lp->b = (2*fs-tau_i)/(2*fs+tau_i);
feTRACE(15);
return lp;
}
vd SPLowpass_filter(SPLowpass* lp,
const vd* input) {
fsTRACE(15);
dbgassert(lp && input,NULLPTRDEREF);
assert_vx(input);
us input_size = input->n_rows;
if(input_size == 0) {
return vd_alloc(0);
}
vd output = vd_alloc(input_size);
const d xlast = lp->xlast;
const d ylast = lp->ylast;
const d a = lp->a;
const d b = lp->b;
*getvdval(&output,0) = a*(xlast + *getvdval(input,0)) +
b*ylast;
for(us i=1;i<input_size;i++) {
*getvdval(&output,i) = a*(*getvdval(input,i-1) +
*getvdval(input,i)) +
b*(*getvdval(&output,i-1));
}
lp->xlast = *getvdval(input ,input_size-1);
lp->ylast = *getvdval(&output,input_size-1);
feTRACE(15);
return output;
}
void SPLowpass_free(SPLowpass* lp) {
fsTRACE(15);
dbgassert(lp,NULLPTRDEREF);
a_free(lp);
feTRACE(15);
}
//////////////////////////////////////////////////////////////////////

View File

@ -1,51 +0,0 @@
// lasp_sp_lowpass.h
//
// Author: J.A. de Jong - ASCEE
//
// Description: Single-pole low pass IIR filter. Used for example for
// fast and fast and slow averaging of the square of the squared
// A-weighted acoustic pressure. This class uses the bilinear
// transform to derive the filter coefficients.
//////////////////////////////////////////////////////////////////////
#pragma once
#ifndef LASP_SP_LOWPASS_H
#define LASP_SP_LOWPASS_H
#include "lasp_types.h"
#include "lasp_mat.h"
typedef struct SPLowpass_s SPLowpass;
/**
* Create a single pole lowpass IIR filter.
*
* @param fs Sampling frequency [Hz]
* @param tau Time constant of the lowpass filter. Should be >0,
* otherwise an error occurs
*
* @return Pointer to dynamically allocated lowpass filter. NULL on
* error.
*/
SPLowpass* SPLowpass_create(d fs,d tau);
/**
* Use the filter to filter input data
*
* @param lp Lowpass filter handlen
* @param input Vector of input samples.
*
* @return Output data. Length is equal to input at all cases.
*/
vd SPLowpass_filter(SPLowpass* lp,
const vd* input);
/**
* Free a single pole lowpass filter
*
* @param lp
*/
void SPLowpass_free(SPLowpass* lp);
#endif // LASP_SP_LOWPASS_H
//////////////////////////////////////////////////////////////////////

View File

@ -485,43 +485,6 @@ cdef class Decimator:
if self.dec != NULL:
Decimator_free(self.dec)
cdef extern from "lasp_sp_lowpass.h":
ctypedef struct c_SPLowpass "SPLowpass"
c_SPLowpass* SPLowpass_create(d fs,d tau)
vd SPLowpass_filter(c_SPLowpass* lp,
const vd* _input)
void SPLowpass_free(c_SPLowpass* lp)
cdef class SPLowpass:
cdef:
c_SPLowpass* lp
def __cinit__(self,d fs,d tau):
self.lp = SPLowpass_create(fs,tau)
if not self.lp:
raise RuntimeError('Error creating lowpass filter')
def __dealloc__(self):
if self.lp:
SPLowpass_free(self.lp)
def filter_(self,d[::1,:] input_):
assert input_.shape[1] == 1
if input_.shape[0] == 0:
return np.array([],dtype=NUMPY_FLOAT_TYPE)
cdef vd input_vd = dmat_foreign_data(input_.shape[0],1,
&input_[0,0],False)
cdef dmat output = SPLowpass_filter(self.lp,&input_vd)
# # Steal the pointer from output
result = dmat_to_ndarray(&output,True)
dmat_free(&output)
vd_free(&input_vd)
return result
cdef extern from "lasp_siggen.h":
ctypedef struct c_Siggen "Siggen"