Величина в децибелах всегда возвращает NaN в C # - PullRequest
2 голосов
/ 02 января 2012

Итак, мой вопрос изменился с возвращения Бесконечности на возвращение NaN.Если ваш БПФ всегда возвращает бесконечность, это может помочь (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 # (потому что он гораздо более способный), так что возможноЯ упустил что-то простое в своей новизне.Я использую 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]);
}

Предыдущий код печатает:

dB @ 400: NaN

-5.56725062513722E+33

Спасибо !!

Ответы [ 3 ]

1 голос
/ 03 января 2012

Вы определили MIN_VALUE как System.Double.MinValue, что является наименьшим возможным числом с двойной точностью. Добавление чего-либо кроме System.Double.MaxValue или положительной бесконечности даст отрицательный результат. Взяв логарифм отрицательного числа, вы получите NaN.

Полагаю, вы хотите, чтобы MIN_VALUE было наименьшим положительным числом. В C # вы используете System.Double.Epsilon для этого. (Я знаю ... это не должно называться ...)

Любое другое крошечное значение, например 1e-100, также будет работать.

0 голосов
/ 04 января 2012

Я нашел ответ! Получается, что в отличие от C ++, AS3 и некоторых других языков, C # имеет отрицательное минимальное двойное значение.

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

Получение квадратного корня негативов вызывает ошибку NaN. Для получения дополнительной информации см. (http://www.codeproject.com/KB/cs/numprogrammingcs.aspx). У меня проблемы с получением точного значения в дБ, но я исследую и вижу, что могу найти.

0 голосов
/ 02 января 2012

для (int i = 0; i

с умножением всегда будет равно нулю, если только это не то, что вы хотели.

...