#ifndef _FREQRESPONE_HH_43059743092758305
#define _FREQRESPONE_HH_43059743092758305
typedef struct pulse_a {
bool enable;
char pad[3];
//double hn[KERNEL_SAMPLE_NUM];
double gain[KERNEL_HALF_FFT];
//-pi~piÇø¼äµÄÏàλ
double phase[KERNEL_HALF_FFT];
}pulse_t;
class FreqResponse
{
private:
void iir_freqz(double b[3], double a[3], int N, double* w, double* m);
void iir_anglez(double b[3], double a[3], int N, int fs, double* f, double* p);
/* compute weighted average group delay tau_c */
double estimate_avg_group_delay(const double* Hre, const double* Him, int N);
///
/// »ùÓÚȺÑÓʱÖÐÐÄÌáÈ¡FIRϵÊý
/// ÏßÐÔÏàλ FIR£¬ÖÐÐĶԳÆÎ»ÖþÍÊÇȺÑÓ³ÙÖÐÐÄ
///
void hn_group_delay_center(double* ifft_real, int real_size, double* hn, int tap);
public:
///
/// ¸ù¾ÝFIRϵÊýÉú³ÉƵÂÊÏìÓ¦
///
/// fir ϵÊý
/// ϵÊý´óС
/// Êä³öµãÊý¸öÊý£¬±ØÐë2µÄÖ¸Êý´Î·½
/// ²ÉÑùÂÊ
/// Êä³öƵÂÊ
/// Êä³öÔöÒæ
/// Êä³öÏàλ-pi~pi
///
int freqz(double coeffs[], int size, int smpl, int fs, double f[], double gain[], double angle[]);
int freqz(double (*sos)[6], int section , int smpl, int fs, double f[], double gain[]);
///
/// ÏßÐÔ³éÈ¡
///
int extra(double f[], double gain[], double phase[], int num
, double new_f[], double new_gain[], double new_phase[], int new_num);
///
/// Éú³É·ÇÏßÐÔÆµÂÊ
///
int logspace(double f1, double f2, double f[], int num);
///
/// Éú³ÉÏßÐÔÆµÂÊ
///
int linearspace(double f1, double f2, double f[], int num);
///
/// ת»»-pi~piÇø¼äÏàλ»¡¶Èµ½¶È
///
inline void rad2deg(double angle[], int num)
{
const double rad_to_deg = 180.0 / pi;
for (int i = 0; i < num; i++) {
angle[i] = angle[i] * rad_to_deg; // È»ºóת¶ÈÊý
}
}
///
/// ½â²øÈƵÄÏàλת»»µ½-pi~pi.
///
///
///
inline double wrap_phase(double phase)
{
// ·½·¨1£ºÊ¹ÓÃfmod
phase = fmod(phase + pi, 2.0 * pi);
if (phase < 0) {
phase += 2.0 * pi;
}
return phase - pi;
}
///
/// Ïàλ½â²øÈÆ
///
/// -pi~pi
/// ÊýÁ¿
/// ½â²øÈƺóÊä³öÏàλ,Óëphase²»ÄÜÊÇͬһ¸öµØÖ·
void unwrap_phase(double phase[], int num, double unwrapped_phase[]);
void unwrap_phase(double* phi, int N);
///
/// ת»»¶Èµ½»¡¶È-pi~pi.
///
inline void deg2rad(double angle[], int num)
{
const double deg_to_rad = pi / 180.0;
for (int i = 0; i < num; i++) {
angle[i] = fmod(angle[i], 360.0);
if (angle[i] > 180.0) angle[i] -= 360.0;
if (angle[i] < -180.0) angle[i] += 360.0;
angle[i] = angle[i] * deg_to_rad;
}
}
///
/// ¸ù¾Ý·ÇÏßÐÔÆµÂÊÔöÒæÏàλÇóÂö³åÏìÓ¦
///
/// ƵÂÊ
/// ÔöÒæ
/// Ïàλ
/// ÊäÈëÊý¾Ý¸öÊý
/// Âö³åÏìÓ¦
/// Âö³åÏìÓ¦³¤¶È
/// Ö»ÔÚphase_comp=trueµÄʱºòÉúЧ.Ö¸¶¨ÑÓʱʱ³¤
///
int impulse_response(double* f, double* g, double* p,int num, double* hn, int tap, double* wn, double delay_ms, bool phase_comp=false);
///
/// °´ÕÕoct¶Ôdata½øÐ묶¯´°¿Úƽ»¬
///
/// oct
/// ÆðʼƵÂÊ
/// ½ØÖ¹ÆµÂÊ
/// µÈ¼ä¾àƵÂÊ
/// Êý¾Ý£¬Èç¹ûÊÇÔöÒæÊÇdb£¬ÏàλÊǽӲøÈƺóÏàλ
/// Êä³öÊý¾Ý
/// Êý¾Ý¸öÊý
void sw_smooth(double oct, double f1, double f2, double* freq , double* data, double* out_data, int num);
void mulimpulse(pulse_t* pulse, int pulse_num, int pulse_start =0);
};
#endif