在 C# 中,以分贝为单位的幅度始终返回 NaN

发布于 2024-12-23 17:13:38 字数 2119 浏览 2 评论 0原文

所以我的问题从返回 Infinity 变为返回 NaN。如果您的 FFT 始终返回无穷大,这可能会有所帮助(http://gerrybeauregard.wordpress.com/2011/04/01/an-fft-in-c/#comment-196)。所以我认为它返回 NaN 因为 C# 试图获取负数的平方根但是,根据下面的代码,该数字不应该为负数,因为我在获取平方根之前对两个数字进行平方(这应该使它们积极的)。然而,返回的数字是负数。我尝试过使用多个变量来获取 re * re 和 im * im 并将两个结果相加在一起的效率低下,但结果也是负数。 Math.Abs​​ 也不好。我已经联系了 FFT 类的创建者(请参阅上面的链接)并正在等待他的下一个回复。我从之前编写的 AS3 版本中获取了下面的一些代码。如果我在此处得到答案之前从课程创建者那里得到答案,那么我会发布该答案。任何见解都是最有帮助的,感谢迄今为止在这方面帮助过我的所有人。我是一名 AS3 程序员,正在转向 C#(因为它的能力更强),所以我可能在新手中错过了一些简单的东西。我正在使用统一。

 private const uint LOGN = 11; // Log2 FFT Length

    private const uint N = 1 << (int)LOGN; // FFT Length

    private const uint BUF_LEN = N; // Audio buffer length

    public FFT2 fft; // FFT Object

    private double[] tempIm = new double[N]; // Temporary Imaginary Number array

    private double[] m_mag = new double[N/2]; // Magnitude array

    private double[] m_win = new double[N]; // Hanning Window 

    private int fftCount = 0; // How many times the FFT has been performed

    private double SCALE = (double)20/System.Math.Log(10); // used to convert magnitude from FFT to usable dB

    private double MIN_VALUE = (double)System.Double.MinValue;

……

    // Hanning analysis window
    for (int i = 0; i < N; i++) // for i < 2048
        m_win[i] = (4.0/N) * 0.5*(1-Mathf.Cos(2*Mathf.PI*i/N)); // Hanning Vector [1] = 1 / 4595889085.750801

前面的

// Perform FFT
fft.run(tempRe, tempIm);

fftCount++;

// Convert from Decibel to Magnitude
for (int i = 0; i < N/2; i++) {

double re = tempRe[i]; // get the Real FFT Number at position i
double im = tempIm[i]; // get the Imaginary FFT Number at position i

m_mag[i] = Math.Sqrt(re * re + im * im); // Convert magnitude to decibels

m_mag[i] = SCALE * Math.Log(m_mag[i] + MIN_VALUE);

if (fftCount == 50 && i == 400) print ("dB @ 399: " + m_mag[399]);
}

代码打印:

dB @ 400: NaN

-5.56725062513722E+33

谢谢!!

So my question has changed from returning Infinity to returning NaN. If your FFT is always returning Infinity this may help (http://gerrybeauregard.wordpress.com/2011/04/01/an-fft-in-c/#comment-196). So I think it is returning NaN because C# is trying to get the Square Root of a negative number HOWEVER, the number should not be negative based on the code below, because I am squaring both numbers before getting the square root (which should make them positive). The number returned is negative, however. I have tried it the inefficient of using multiple variables to get re * re and im * im and the two results added together, but the results are negative as well. Math.Abs was no good either. I have contacted the creator of the FFT Class (see my link above) and am waiting for his next reply. I took some of the code below from an AS3 version of this I did before. If I get the answer from the class creator before I get one here then I will post that. Any insight is most helpful and thank you to everyone who has helped me so far in this. I am an AS3 programmer coming to C# (because it's much more capable), so it's possible I missed something simple in my newbness. I am using Unity.

 private const uint LOGN = 11; // Log2 FFT Length

    private const uint N = 1 << (int)LOGN; // FFT Length

    private const uint BUF_LEN = N; // Audio buffer length

    public FFT2 fft; // FFT Object

    private double[] tempIm = new double[N]; // Temporary Imaginary Number array

    private double[] m_mag = new double[N/2]; // Magnitude array

    private double[] m_win = new double[N]; // Hanning Window 

    private int fftCount = 0; // How many times the FFT has been performed

    private double SCALE = (double)20/System.Math.Log(10); // used to convert magnitude from FFT to usable dB

    private double MIN_VALUE = (double)System.Double.MinValue;

...

    // Hanning analysis window
    for (int i = 0; i < N; i++) // for i < 2048
        m_win[i] = (4.0/N) * 0.5*(1-Mathf.Cos(2*Mathf.PI*i/N)); // Hanning Vector [1] = 1 / 4595889085.750801

// Perform FFT
fft.run(tempRe, tempIm);

fftCount++;

// Convert from Decibel to Magnitude
for (int i = 0; i < N/2; i++) {

double re = tempRe[i]; // get the Real FFT Number at position i
double im = tempIm[i]; // get the Imaginary FFT Number at position i

m_mag[i] = Math.Sqrt(re * re + im * im); // Convert magnitude to decibels

m_mag[i] = SCALE * Math.Log(m_mag[i] + MIN_VALUE);

if (fftCount == 50 && i == 400) print ("dB @ 399: " + m_mag[399]);
}

The prior code prints:

dB @ 400: NaN

-5.56725062513722E+33

Thank you!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

灵芸 2024-12-30 17:13:38

您将 MIN_VALUE 定义为 System.Double.MinValue,它是可能的最小双精度数。添加 System.Double.MaxValue 或正无穷大以外的任何值都会产生负结果。取负数的对数返回NaN

我猜您希望 MIN_VALUE 成为最小的正数。在 C# 中,您可以使用 System.Double.Epsilon 来实现此目的。 (我知道...不应该这样称呼...)

任何其他微小值,例如 1e-100,也可以。

You defined MIN_VALUE to be System.Double.MinValue, which is the smallest possible double precision number. Adding anything other than System.Double.MaxValue or positive infinity will give a negative result. Taking the logarithm of a negative number returns NaN.

I'm guessing you want MIN_VALUE to be the smallest positive number. In C#, you use System.Double.Epsilon for that. (I know... it shouldn't be called that...)

Any other tiny value, like 1e-100, will work as well.

for (int i = 0; i < tempRe.Length; i++) tempRe[i] = m_win[i];

乘法它总是为零,除非那是你想要的。

for (int i = 0; i < tempRe.Length; i++) tempRe[i] = m_win[i];

with the multiplication it will always be zero, unless that is what you wanted.

霞映澄塘 2024-12-30 17:13:38

我找到了答案!事实证明,与 C++、AS3 和其他一些语言不同,C# 具有负的最小双精度值。

System.Double.MIN_VALUE = -1.7976931348623157E+308;

求负数的平方根会导致 NaN 错误。有关详细信息,请参阅 (http://www.codeproject.com/KB/cs/numprogrammingcs.aspx" aspx)。我现在很难获得准确的分贝读数,但我会研究并看看能找到什么。

I found the answer! So it turns out that unlike C++, AS3, and some other languages, C# has negative minimum double value.

System.Double.MIN_VALUE = -1.7976931348623157E+308;

Getting the Square root of negatives causes the NaN error. For more info see (http://www.codeproject.com/KB/cs/numprogrammingcs.aspx). I am having trouble getting an accurate dB reading now but I research and see what I can find.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文