gpt4 book ai didi

actionscript-3 - 创建频谱图时遇到问题

转载 作者:行者123 更新时间:2023-12-02 23:58:35 25 4
gpt4 key购买 nike

我知道之前被问了一千次,但我仍然找不到解决方案。
搜索SO,我确实找到了它的算法,但缺乏真正理解它所需的数学知识,我无助地迷失了!

首先,我的目标是计算整个频谱图并将其保存到图像中,以便将其用于可视化器。

我尝试使用 Sound.computeSpectrum,但这需要播放声音并等待它结束,我想以比聆听所有歌曲所需的时间更短的方式计算频谱图。我有 2 小时长的 mp3。

我现在正在做的是从 Sound 对象中读取字节,分成两个 Vectors(.);然后使用计时器,每 100 毫秒我调用一个函数(步骤 1),其中我有算法的实现,如下所示:

  • 对于每个向量(每个向量),我将 hann 函数应用于元素;
  • 对于每个向量,我都会取消虚部(我有一个辅助向量)
  • 对于每个向量,我应用 FFT
  • 对于每个向量,我找到前 N/2 个元素的大小
  • 对于每个向量,我将幅度平方转换为 dB 标度
  • 结尾。

  • 但我只得到负值,只有 30% 的结果可能有用(其余部分相同)

    我将只发布一个 channel 的代码,以摆脱“每个矢量”部分。
    private var N:Number = 512;
    private function step1() : void
    {
    var xReLeft:Vector.<Number> = new Vector.<Number>(N);
    var xImLeft:Vector.<Number> = new Vector.<Number>(N);

    var leftA:Vector.<Number> = new Vector.<Number>(N);

    // getting sample range
    leftA = this.channels.left.slice(step * N, step * (N) + (N));

    if (leftA.length < N)
    {
    stepper.removeEventListener(TimerEvent.TIMER, getFreq100ms);
    return;
    }
    else if (leftA.length == 0)
    {
    stepper.removeEventListener(TimerEvent.TIMER, getFreq100ms);
    return;
    }

    var i:int;

    // hann window function init
    m_win = new Vector.<Number>(N);
    for ( var i:int = 0; i < N; i++ )
    m_win[i] = (4.0 / N) * 0.5 * (1 - Math.cos(2 * Math.PI * i / N));

    // applying hann window function
    for ( i = 0; i < N; i++ )
    {
    xReLeft[i] = m_win[i]*leftA[i];
    //xReRight[i] = m_win[i]*rightA[i];
    }

    // nullify the imaginary part
    for ( i = 0; i < N; i++ )
    {
    xImLeft[i] = 0.0;
    //xImRight[i] = 0.0;
    }

    var magnitutel:Vector.<Number> = new Vector.<Number>(N);

    fftl.run( xReLeft, xImLeft );

    current = xReLeft;
    currf = xImLeft;

    for ( i = 0; i < N / 2; i++ )
    {
    var re:Number = xReLeft[i];
    var im:Number = xImLeft[i];
    magnitutel[i] = Math.sqrt(re * re + im * im);
    }

    const SCALE:Number = 20 / Math.LN10;
    var l:uint = this.total.length;
    for ( i = 0; i < N / 2; i++ )
    {
    magnitutel[i] = SCALE * Math.log( magnitutel[i] + Number.MIN_VALUE );
    }

    var bufferl:Vector.<Number> = new Vector.<Number>();

    for (i = 0; i < N / 2 ; i++)
    {
    bufferl[i] = magnitutel[i];
    }

    var complete:Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>();
    complete[0] = bufferl;
    this.total[step] = complete;

    this.step++;
    }

    该函数在定时器(步进器)调度的事件中执行。
    显然我做错了什么,正如我所说的,我只有负值,而且更多的值在 1 到 7000 之间(至少)。

    我要提前感谢您的帮助。

    尊重地,
    保罗

    最佳答案

    负分贝值是可以的。只需添加一个常数(代表您的音量控制),直到您要着色的点数变为正数。保持负数的其余值通常仅在频谱图中显示或着色为黑色。无论多么负(因为它们可能只是 FFT 的数值噪声,可能是一个巨大的负 dB 数,甚至是 NaN 或 log(0) 的 -Inf)。

    关于actionscript-3 - 创建频谱图时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11079600/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com