gaoweidong
2026-01-13 c5eeada2c735b0209a061a233483c5cfc29c2230
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#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);
    /// <summary>
    /// »ùÓÚȺÑÓʱÖÐÐÄÌáÈ¡FIRϵÊý
    /// ÏßÐÔÏàλ FIR£¬ÖÐÐĶԳÆÎ»ÖþÍÊÇȺÑÓ³ÙÖÐÐÄ
    /// </summary>
    void hn_group_delay_center(double* ifft_real, int real_size, double* hn, int tap);
public:
    /// <summary>
    /// ¸ù¾ÝFIRϵÊýÉú³ÉƵÂÊÏìÓ¦
    /// </summary>
    /// <param name="coeffs">fir ÏµÊý</param>
    /// <param name="size">ϵÊý´óС</param>
    /// <param name="smpl">Êä³öµãÊý¸öÊý£¬±ØÐë2µÄÖ¸Êý´Î·½</param>
    /// <param name="fs">²ÉÑùÂÊ</param>
    /// <param name="f">Êä³öƵÂÊ</param>
    /// <param name="gain">Êä³öÔöÒæ</param>
    /// <param name="angle">Êä³öÏàλ-pi~pi</param>
    /// <returns></returns>
    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[]);
 
    /// <summary>
   /// ÏßÐÔ³éÈ¡ 
   /// </summary>
    int extra(double f[], double gain[], double phase[], int num
        , double new_f[], double new_gain[], double new_phase[], int new_num);
 
    /// <summary>
    /// Éú³É·ÇÏßÐÔÆµÂÊ 
    /// </summary>
    int logspace(double f1, double f2, double f[], int num);
 
    /// <summary>
    /// Éú³ÉÏßÐÔÆµÂÊ 
    /// </summary>
    int linearspace(double f1, double f2, double f[], int num);
 
 
    /// <summary>
    /// ×ª»»-pi~piÇø¼äÏàλ»¡¶Èµ½¶È
    /// </summary>
    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;        // È»ºóת¶ÈÊý
        }
    }
    /// <summary>
    /// ½â²øÈƵÄÏàλת»»µ½-pi~pi.
    /// </summary>
    /// <param name="phase"></param>
    /// <returns></returns>
    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;
    }
 
    /// <summary>
    /// Ïàλ½â²øÈÆ
    /// </summary>
    /// <param name="phase">-pi~pi</param>
    /// <param name="num">ÊýÁ¿</param>
    /// <param name="unwrapped_phase">½â²øÈƺóÊä³öÏàλ,Óëphase²»ÄÜÊÇͬһ¸öµØÖ·</param>
    void unwrap_phase(double phase[], int num, double unwrapped_phase[]);
    void unwrap_phase(double* phi, int N);
 
    /// <summary>
    /// ×ª»»¶Èµ½»¡¶È-pi~pi.
    /// </summary>
    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;
        }
    }
 
    /// <summary>
    /// ¸ù¾Ý·ÇÏßÐÔÆµÂÊÔöÒæÏàλÇóÂö³åÏìÓ¦
    /// </summary>
    /// <param name="f">ƵÂÊ</param>
    /// <param name="g">ÔöÒæ</param>
    /// <param name="p">Ïàλ</param>
    /// <param name="num">ÊäÈëÊý¾Ý¸öÊý</param>
    /// <param name="hn">Âö³åÏìÓ¦</param>
    /// <param name="size">Âö³åÏìÓ¦³¤¶È</param>    
    /// <param name="delay_ms">Ö»ÔÚphase_comp=trueµÄʱºòÉúЧ.Ö¸¶¨ÑÓʱʱ³¤</param>                      
    /// <returns></returns>
    int impulse_response(double* f, double* g, double* p,int num, double* hn, int tap, double* wn, double delay_ms, bool phase_comp=false);
 
 
    /// <summary>
    /// °´ÕÕoct¶Ôdata½øÐ묶¯´°¿Úƽ»¬
    /// </summary>
    /// <param name="oct">oct</param>
    /// <param name="f1">ÆðʼƵÂÊ</param>
    /// <param name="f2">½ØÖ¹ÆµÂÊ</param>
    /// <param name="freq">µÈ¼ä¾àƵÂÊ</param> 
    /// <param name="data">Êý¾Ý£¬Èç¹ûÊÇÔöÒæÊÇdb£¬ÏàλÊǽӲøÈƺóÏàλ</param>
    /// <param name="out_data">Êä³öÊý¾Ý</param> 
    /// <param name="num">Êý¾Ý¸öÊý</param>
    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