Nano Hash - криптовалюты, майнинг, программирование

Реальный выход БПФ

Я реализовал fft в ucontroller серии at32ucb, используя библиотеку kiss fft, и в настоящее время борюсь с выводом fft. Мое намерение состоит в том, чтобы проанализировать звук, исходящий от пьезодинамика. В настоящее время частота эхолота составляет 420 Гц, которую я успешно получил из выхода fft (перепроверено осциллографом). Однако выходная частота будет вдвое меньше ожидаемой, если я поставлю в систему сигнал функционального генератора. Я подозреваю, что это формула расчета частотного интервала, в которой я ошибся; в настоящее время используется, fft_peak_magnitude_index*частота дискретизации / fft_size. Мой вклад реален и делает настоящий фф. (выходные образцы = N/2), а также выполнять фильтрацию iir и работу с окнами перед fft. Любое предложение было бы большим подспорьем!

            // IIR filter calculation, n = 256 fft points       
        for (ctr=0; ctr<n; ctr++)
        {       
            // filter calculation
            y[ctr] = num_coef[0]*x[ctr];
            y[ctr] += (num_coef[1]*x[ctr-1]) - (den_coef[1]*y[ctr-1]);
            y[ctr] += (num_coef[2]*x[ctr-2]) - (den_coef[2]*y[ctr-2]);
            y1[ctr] = y[ctr] - 510; //eliminate dc offset

            // hamming window
            hamming[ctr] = (0.54-((0.46) * cos(2*M_PI*ctr/n)));
            window[ctr] = hamming[ctr]*y1[ctr];

            fft_input[ctr].r = window[ctr];
            fft_input[ctr].i = 0;
            fft_output[ctr].r = 0;
            fft_output[ctr].i = 0;
        }


        kiss_fftr_cfg fftConfig = kiss_fftr_alloc(n,0,NULL,NULL);
        kiss_fftr(fftConfig, (kiss_fft_scalar * )fft_input, fft_output);

        peak = 0;
        freq_bin = 0;       
        for (ctr=0; ctr<n1; ctr++)
            {   
                fft_mag[ctr] = 10*(sqrt((fft_output[ctr].r * fft_output[ctr].r) + (fft_output[ctr].i * fft_output[ctr].i)))/(0.5*n);

                if(fft_mag[ctr] > peak)
                {
                    peak = fft_mag[ctr];
                    freq_bin = ctr;
                }

            frequency = (freq_bin*(10989/n)); // 10989 is the sampling freq
                //************************************
                //Usart write
                char filtResult[10];
                //sprintf(filtResult, "%04d %04d %04d\n", (int)peak, (int)freq_bin, (int)frequency);
                sprintf(filtResult, "%04d  %04d  %04d\n", (int)x[ctr], (int)fft_mag[ctr], (int)frequency);
                char c;
                char *ptr = &filtResult[0];
                do
                {
                    c = *ptr;
                    ptr++;
                    usart_bw_write_char(&AVR32_USART2, (int)c);
                    // sendByte(c);

                } while (c != '\n');
            }

Ответы:


1

Основная проблема, вероятно, заключается в том, как вы объявили fft_input. Основываясь на вашем предыдущем вопросе, вы выделяете fft_input как массив kiss_fft_cpx. С другой стороны, функция kiss_fftr ожидает массив скалярных значений. Приведя входной массив к kiss_fft_scalar с помощью:

kiss_fftr(fftConfig, (kiss_fft_scalar * )fft_input, fft_output);

KissFFT по сути видит массив данных с действительными значениями, который содержит нули каждую вторую выборку (то, что вы заполнили как мнимые части). По сути, это версия исходного сигнала с повышенной частотой дискретизации (хотя и без интерполяции), то есть сигнал с фактически удвоенной частотой дискретизации (что не учитывается при преобразовании freq_bin в frequency). Чтобы исправить это, я предлагаю вам упаковать ваши данные в массив kiss_fft_scalar:

kiss_fft_scalar fft_input[n];
...
for (ctr=0; ctr<n; ctr++)
{       
    ...
    fft_input[ctr] = window[ctr];
    ...
}
kiss_fftr_cfg fftConfig = kiss_fftr_alloc(n,0,NULL,NULL);
kiss_fftr(fftConfig, fft_input, fft_output);

Также обратите внимание, что при поиске амплитуды пика вас, вероятно, интересует только последний самый большой пик, а не текущий максимум. Таким образом, вы можете ограничить цикл только вычислением пика (при необходимости используя freq_bin вместо ctr в качестве индекса массива в следующих операторах sprintf):

for (ctr=0; ctr<n1; ctr++)
{   
  fft_mag[ctr] = 10*(sqrt((fft_output[ctr].r * fft_output[ctr].r) + (fft_output[ctr].i * fft_output[ctr].i)))/(0.5*n);

  if(fft_mag[ctr] > peak)
  {
    peak = fft_mag[ctr];
    freq_bin = ctr;
  }
} // close the loop here before computing "frequency"

Наконец, при вычислении частоты, связанной с бином с наибольшей величиной, вам необходимо убедиться, что вычисление выполняется с использованием арифметики с плавающей запятой. Если, как я подозреваю, n является целым числом, ваша формула будет выполнять коэффициент 10989/n, используя целочисленную арифметику, что приводит к усечению. Это можно просто исправить с помощью:

frequency = (freq_bin*(10989.0/n)); // 10989 is the sampling freq
03.06.2015
  • Еще раз спасибо за ваш добрый ответ. Я отредактировал в соответствии с вашим предложением, которое имело большой смысл. И вход генератора функций теперь дает мне правильный вывод. Тем не менее, теперь пьезо-выход удваивается... так что постоянно два входных условия отстают в два раза. 04.06.2015
  • Не могу прокомментировать получение пьезоданных, поскольку вы не опубликовали эту часть. Тем не менее, первое, что я бы проверил, это настройки частоты дискретизации и то, обрабатываете ли вы 8- или 16-битные сэмплы. 04.06.2015
  • я только что узнал, что пьезоэлемент просто резонирует на частоте 840 Гц ... с перекрестной проверкой с помощью осциллографа fft у меня есть точно такая же картина для величины fft. Большое спасибо!! 04.06.2015
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..