Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Программирование звука > FFT-спектральный анализатор


Автор: gmaxi 10.02.17, 23:01
Доброй ночи .
Как реализовать вывод частоты с максимальной амплитудой на промежутке от 0 до 120Гц. С частотой дискретизации 240 Гц .
Прошу помочь в написании кода на С , потому что в математике 0 .

Автор: MBo 11.02.17, 05:12
Взять входной массив
Выполнить FFT
Вычислить амплитуду комплексного результата как корень из суммы квадратов мнимой и реальной части
Найти максимальный отcчёт амплитуды.

Частота сигнала Fдискр/2 соответствует N/2 отсчёту массива после преобразования (вторая часть - зеркальное отражение).

Автор: gmaxi 11.02.17, 13:12
Прошу помочь написать код так как для меня FFT темный лес

Автор: MBo 11.02.17, 13:27
Этих кодов в инете да и на этом форуме немало

Автор: gmaxi 11.02.17, 14:00
Увы не особо то в интернете не то что надо везде спектр отображают в виде графики , а мне нужно допустим играет музыка , раз максимальная амплитуда 77Гц потом второй пик 35Гц и так далее . Вот эти показания мне и надо в цифрах

Автор: MBo 11.02.17, 14:53
i-й отсчет соответствует частоте Fдискр * i / N

Автор: Mikle 12.02.17, 09:26
Цитата gmaxi @
на промежутке от 0 до 120Гц. С частотой дискретизации 240 Гц .

Что-то здесь не сходится.

Автор: MBo 12.02.17, 14:27
Mikle
Почему?

Автор: Mikle 13.02.17, 06:53
Цитата MBo @
Почему?

Каков уровень будет на 0 Гц?

Автор: MBo 13.02.17, 07:01
Постоянная составляющая

Автор: Mikle 13.02.17, 09:13
Цитата MBo @
Постоянная составляющая

Верно, а FFT её выдаст? За сколько семплов?

Автор: Pavia 13.02.17, 09:28
Mikle
К чему вы клоните? Выдаст, чем больше семплов тем лучше.
Для точного восстановления гармоник нужна частота дискретизации в 2 раза большая.

Автор: MBo 13.02.17, 09:37
>Верно, а FFT её выдаст? За сколько семплов?
Недопонимаю смысл вопроса.
Нулевую выдаст всегда. Какова её интенсивность - зависит от сигнала.
От количества семплов (временного интервала) зависит частотное разрешение.
Слишком мало (нечёткое понятие) семплов - амплитуды неточные.

Автор: Pavia 13.02.17, 10:39
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    function DetectFirstF2(a:TArrayReal; t:Real; dwSamplesPerSec:DWord):Real;
    var
     i,N,NewN:Integer;
     aa,b:TArrayReal;
     z:TArrayComplex;
     r:Real;
     fd:Real;
     v0,v1,v2:Real;
    begin
    fd:=dwSamplesPerSec;
    N:=Length(a);
    NewN:=(1 shl Log2Int(n))*32;
    aa:=copy(a);
    r:=Mean(aa);      // Находим среднее
    sub(aa,r);        // Убираем постоянную составляющую.
    HammingMulWindow(n,@aa[0]);
    SetLength(aa,NewN);
    CopyInRe(z,aa);
     
    FFT(z,False);    // Получаем спектр частот
     
    amp(b,z);        // Вычисляем амплитуду
    for i:=1 to Length(b)-2 do
     b[i]:=0.25*b[i-1]+0.5*b[i]+0.25*b[i+1]; // Убираем небольшие шумы, могут влиять на знак 1 производной.
     
    for i:=6 to Length(b) div 2 do // Отбрасываем первые частоты, которые могут помешать.И отбрасываем отрицательные частоты (div 2).
     begin
     if (b[i]>t*N/NewN) and (b[i]-b[i-1]>0) and (b[i]-b[i+1]>0) then // проверяем порог и условие выпуклости по произволдням(точка больше двух соседних)
       begin
       GetParabola(Point2DReal(i-1,b[i-1]),Point2DReal(i,b[i]),Point2DReal(i+1,b[i+1]),v0,v1,v2); // Вычисляем коэффициенты параболы для уточнения частоты
       Result:=(-v1/2/v0)*Fd/(NewN); // Находим максимум параболы и пересчитываем координату в частоту
       Exit;
       end;
     end;
    end;

Автор: Mikle 13.02.17, 11:38
Теоретически точность определения амплитуды гармоники растёт с ростом отношения длительности выборки к периоду. Когда выборка короче половины периода, определять нечего вообще - период при нуле равен бесконечности.
Для определения постоянной составляющий нужно иметь историю сигнала на бесконечность назад.
Могу на примере объяснить, лень писать, но, вроде бы, и так понятно. Если надо будет - распишу подробнее.

Автор: Pavia 13.02.17, 12:22
Mikle
Цитата Mikle @
период при нуле равен бесконечности.Для определения постоянной составляющий нужно иметь историю сигнала на бесконечность назад.Могу на примере объяснить, лень писать, но, вроде бы, и так понятно. Если надо будет - распишу подробнее.

И что с того?
Lim_{W->0}{A_0*Sin(W*t)}=>A_0*Sin(0)=A_0*1=A_0
Lim_{W->0}{W=1/T}=>T=бесконечность

Когда бы выполняем дискретное преобразование Фурье мы выполняем его не над бесконечным сигналом, а над конечным.
Это тоже допускается если у нас сигнал периодический и вычисления идут над периодом. (Мы считаем ряд Фурье вместо преобразования Фурье)
Считается что сигнал повторяется бесконечное число раз с периодом равному K-семплов.
Какой период у константы A_0? Ответ: произвольный.

Но вообще постоянный сигнал. Он постоянный не только на 0 частоте, но на всех частотах.
Тут дело другое, что есть такое явление как эффект Гиббса. Если в двух словах, то так как сигнал хотя и постоянный когда мы берём К семплов то мы как-бы выполняем П-образную фильтрацию, которая корёжит гармоники которые не кратны данному периоду K-семплов.
Из-за этого постоянный сигнал приобретает форму SinC(W).

Но это полбеды переменный сигнал, тоже растекается подобным образом. С этим уже борются оконные функции. Они корректируют частоты и фазу.

Автор: MBo 13.02.17, 13:55
Это справедливо, но не особо страшно по сравнению с другими "прелестями" ПФ.
Например, если задана функция Sin(x)+1, то после ПФ на большом интервале (N значений) амплитуда нулевого отсчёта будет порядка N. Однако на интервале, захватывающем полпериода с нулевой начальной фазой, амплитуда будет в полтора раза больше положенного. Вряд ли можно сказать, что это в корне неправильно, ведь по такому кусочку нельзя достоверно судить о функции

Автор: gmaxi 25.02.17, 20:13
Нужно похожее сделать только для микроконтроллера есть и библиотека только ничего не понятно кто может помочь ?
t.JPG (, : 647)
FFT.rar (, : 220)

Автор: Alexei 01.03.17, 08:38
Цитата gmaxi @
сделать только для микроконтроллера

А что, это разве не для микроконтроллера? ;)
AVR невооруженным глазом. :rolleyes:
Где вы это отрыли?

Автор: gmaxi 01.03.17, 17:30
Отрыл в интернете , да для avr .
Нужно реализовать вывод частоты с максимальной амплитудой на промежутке от 0 до 120Гц. С частотой дискретизации 240 Гц .
Допустим берем авр на вход ацп цепляем микрофон , дальше отслеживаем пик на частоте от 0 до 120Гц и выводим его на lcd допустим пик был 50Гц вот это значение и выводим .
Увы высшей математике :'( темный лес вот и прошу помощи в написании кода .

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)