您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

从潜在谐波中确定基频的算法

从潜在谐波中确定基频的算法

我找到了一个相当简单的解决方案,它的计算能力很低。

它涉及给每个间隙一个接近度分数。

要计算间隙i的接近度得分,我只需对所有j!= i求和1 / {dist(gap_i,gap_j)+1}

我设置+1以避免被零除。这样,如果两个值几乎相等,则它们将获得1分,并且随着差距的增加,该得分将变为0

但是,如果间隙j几乎恰好是间隙i的两倍,则也应将其视为非常接近。所以我首先获得最接近gap_j / gap_i的整数(可能需要交换以使gap_j更大),然后将gap_j除以该整数,然后考虑dist(gap_i,fiddled_gap_j)

如果例如gap_j?= 2 * gap_i,那么我要小心提高Gap_i的得分,而不是gap_j

这样可以很好地获得合理准确的候选人。再经过两次处理应该可以很容易地改进该值。我想的第一件事是根据成功的候选人对价值进行平均。然后大概一秒钟创建一个泛函(f)函数,并使用从先前计算的点开始的某种Newton-Raphson过程来隔离局部最大值。

无论如何,下面是代码

    float ascertain_f0(PEAK * peaks, POTENTIAL_HARMONIC * pH, int phCount)
{
    int gaps = phCount;

    // enumerate GAPS
    GAP gap [ MAX_POTENTIAL_HARMONICS ];

    gap[0].len = peaks[pH[0].peakQ].freq;
    for (int i=1; i < gaps; i++)
    {
        int a = pH[i-1].peakQ, 
            b = pH[i].peakQ;

        gap[i].len = peaks[b].freq - peaks[a].freq;
    }

    for (int i=0; i < gaps; i++)
        gap[i].score = 0.;

    // find best scoring gap
    for (int i=0; i < gaps; i++)
        for (int j=0; j < gaps; j++)
        {
            if (i == j)
                continue;

            float a = gap[i].len;
            float B_ = gap[j].len;

            if (a > B_)
                continue;

            // a < B_
            int multiplier = closestInt(B_ / a);
            float b = B_ / multiplier;

            float dist = fabs(b - a);           
            float sc = 1. / (dist + 1.);

            gap[i].score += sc;
            if (multiplier == 1)
                gap[j].score += sc;
        }

    int best = 0;
    for (int i=1; i < gaps; i++)
        if (gap[i].score > gap[best].score)
            best = i;

    return gap[best].len;
}
其他 2022/1/1 18:14:34 有610人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶