• webrtc傅里叶变换实现


    1.实傅里叶变换

    说明

        [definition]
            <case1> RDFT
                R[k] = sum_j=0^n-1 a[j]*cos(2*pi*j*k/n), 0<=k<=n/2
                I[k] = sum_j=0^n-1 a[j]*sin(2*pi*j*k/n), 0<k<n/2
            <case2> IRDFT (excluding scale)
                a[k] = (R[0] + R[n/2]*cos(pi*k))/2 +
                       sum_j=1^n/2-1 R[j]*cos(2*pi*j*k/n) +
                       sum_j=1^n/2-1 I[j]*sin(2*pi*j*k/n), 0<=k<n
        [usage]
            <case1>
                ip[0] = 0; // first time only
                rdft(n, 1, a, ip, w);
            <case2>
                ip[0] = 0; // first time only
                rdft(n, -1, a, ip, w);
        [parameters]
            n              :data length (int)
                            n >= 2, n = power of 2
            a[0...n-1]     :input/output data (float *)
                            <case1>
                                output data
                                    a[2*k] = R[k], 0<=k<n/2
                                    a[2*k+1] = I[k], 0<k<n/2
                                    a[1] = R[n/2]
                            <case2>
                                input data
                                    a[2*j] = R[j], 0<=j<n/2
                                    a[2*j+1] = I[j], 0<j<n/2
                                    a[1] = R[n/2]
            ip[0...*]      :work area for bit reversal (int *)
                            length of ip >= 2+sqrt(n/2)
                            strictly,
                            length of ip >=
                                2+(1<<(int)(log(n/2+0.5)/log(2))/2).
                            ip[0],ip[1] are pointers of the cos/sin table.
            w[0...n/2-1]   :cos/sin table (float *)
                            w[],ip[] are initialized if ip[0] == 0.
        [remark]
            Inverse of
                rdft(n, 1, a, ip, w);
            is
                rdft(n, -1, a, ip, w);
                for (j = 0; j <= n - 1; j++) {
                    a[j] *= 2.0 / n;
                }
            .

    参数说明:

    n:数组长度

    isgn:1:傅里叶变换 -1:反傅里叶变换

    a:傅里叶变换结果生成与传输(isgn决定)

    ip:位反转空间

    w:cos/sin 空间

    ip[0] = 0时进行初始化

    void WebRtc_rdft(int n, int isgn, float *a, int *ip, float *w)
    {
        int nw, nc;
        float xi;
    
        nw = ip[0];
        if (n > (nw << 2)) {
            nw = n >> 2;
            makewt(nw, ip, w);
        }
        nc = ip[1];
        if (n > (nc << 2)) {
            nc = n >> 2;
            makect(nc, ip, w + nw);
        }
        if (isgn >= 0) {
            if (n > 4) {
                bitrv2(n, ip + 2, a);
                cftfsub(n, a, w);
                rftfsub(n, a, nc, w + nw);
            } else if (n == 4) {
                cftfsub(n, a, w);
            }
            xi = a[0] - a[1];
            a[0] += a[1];
            a[1] = xi;
        } else {
            a[1] = 0.5f * (a[0] - a[1]);
            a[0] -= a[1];
            if (n > 4) {
                rftbsub(n, a, nc, w + nw);
                bitrv2(n, ip + 2, a);
                cftbsub(n, a, w);
            } else if (n == 4) {
                cftfsub(n, a, w);
            }
        }
    }
    //计算cos和sin对应值的结果。
    static
    void makewt(int nw, int *ip, float *w) { int j, nwh; float delta, x, y; ip[0] = nw; ip[1] = 1; if (nw > 2) { nwh = nw >> 1;// nw/2 delta = (float)atan(1.0f) / nwh; // w[0] = 1;//2j cos(0) w[1] = 0;//2j+1 sin(0) w[nwh] = (float)cos(delta * nwh); w[nwh + 1] = w[nwh];
    //对称性赋值
    if (nwh > 2) { for (j = 2; j < nwh; j += 2) { x = (float)cos(delta * j); y = (float)sin(delta * j); w[j] = x; w[j + 1] = y; w[nw - j] = y; w[nw - j + 1] = x; } bitrv2(nw, ip + 2, w); } } }
    static void bitrv2(int n, int *ip, float *a)
    {
        int j, j1, k, k1, l, m, m2;
        float xr, xi, yr, yi;
    
        ip[0] = 0;
        l = n;
        m = 1;
        while ((m << 3) < l) {
            l >>= 1;
            for (j = 0; j < m; j++) {
                ip[m + j] = ip[j] + l;
            }
            m <<= 1;
        }
        m2 = 2 * m;
        if ((m << 3) == l) {
            for (k = 0; k < m; k++) {
                for (j = 0; j < k; j++) {
                    j1 = 2 * j + ip[k];
                    k1 = 2 * k + ip[j];
                    xr = a[j1];
                    xi = a[j1 + 1];
                    yr = a[k1];
                    yi = a[k1 + 1];
                    a[j1] = yr;
                    a[j1 + 1] = yi;
                    a[k1] = xr;
                    a[k1 + 1] = xi;
                    j1 += m2;
                    k1 += 2 * m2;
                    xr = a[j1];
                    xi = a[j1 + 1];
                    yr = a[k1];
                    yi = a[k1 + 1];
                    a[j1] = yr;
                    a[j1 + 1] = yi;
                    a[k1] = xr;
                    a[k1 + 1] = xi;
                    j1 += m2;
                    k1 -= m2;
                    xr = a[j1];
                    xi = a[j1 + 1];
                    yr = a[k1];
                    yi = a[k1 + 1];
                    a[j1] = yr;
                    a[j1 + 1] = yi;
                    a[k1] = xr;
                    a[k1 + 1] = xi;
                    j1 += m2;
                    k1 += 2 * m2;
                    xr = a[j1];
                    xi = a[j1 + 1];
                    yr = a[k1];
                    yi = a[k1 + 1];
                    a[j1] = yr;
                    a[j1 + 1] = yi;
                    a[k1] = xr;
                    a[k1 + 1] = xi;
                }
                j1 = 2 * k + m2 + ip[k];
                k1 = j1 + m2;
                xr = a[j1];
                xi = a[j1 + 1];
                yr = a[k1];
                yi = a[k1 + 1];
                a[j1] = yr;
                a[j1 + 1] = yi;
                a[k1] = xr;
                a[k1 + 1] = xi;
            }
        } else {
            for (k = 1; k < m; k++) {
                for (j = 0; j < k; j++) {
                    j1 = 2 * j + ip[k];
                    k1 = 2 * k + ip[j];
                    xr = a[j1];
                    xi = a[j1 + 1];
                    yr = a[k1];
                    yi = a[k1 + 1];
                    a[j1] = yr;
                    a[j1 + 1] = yi;
                    a[k1] = xr;
                    a[k1 + 1] = xi;
                    j1 += m2;
                    k1 += m2;
                    xr = a[j1];
                    xi = a[j1 + 1];
                    yr = a[k1];
                    yi = a[k1 + 1];
                    a[j1] = yr;
                    a[j1 + 1] = yi;
                    a[k1] = xr;
                    a[k1 + 1] = xi;
                }
            }
        }
    }
  • 相关阅读:
    开源 免费 java CMS
    运行shell脚本报错 &#39;357273277&#39;: command not found 解决的方法
    Android学习笔记之Spinner下拉列表使用案例
    HDU 1542 Atlantis (线段树 + 扫描线 + 离散化)
    DrawerLayout
    云计算设计模式(十三)——领导人选举模式
    算法之贪心思想
    [Android]Volley源代码分析(叁)Network
    oracle TABLE ACCESS BY INDEX ROWID 你不知道的索引回表-开发系列(三)
    JavaScript No Overloading 函数无重载之说
  • 原文地址:https://www.cnblogs.com/supermanwx/p/16311571.html
Copyright © 2020-2023  润新知