Здравствуйте! Есть сигнал который подвергается дискретному преобразованию фурье. На выходе ДПФ есть мнимая и действительная части, корень из суммы квадратов которых есть амплитуда определенной частоты в сигнале.
Вот написал небольшую программку, которая генерирует сигнал и проводит над ним прямое преобразование фурье:
Код:
#include "stdafx.h"
#include <stdio.h> #include <math.h> #include <string.h> #define PI 3.141592653589793238462643383279
Вот результат работы программы для сигнала - синус 125Гц + синус 375Гц:
А вот для просто синуса 375Гц:
Для понимания, вот сами сигналы:
Частота дискретизации сигнала - 8000Гц. Теперь вопрос! Как определить реальную амплитуду? В результатах работы программы амплитуда пляшет для двух синусов - по 2048 на частоту, для одного синуса - 4064 единиц. Что это за единицы? Как из привести к нормальному виду? И как из них получить в дб, какое значение принимать за 0Дб?
Цикл 64 раза по 64 раза. Вот и выходит, если частота одна - на ней и выходит максимум (4096, если без ошибок округления), если комбинация частот - суммарная амплитуда тоже будет такой.
Так что надо результат (и действительную часть, и мнимую) на DFT_SIZE разделить, чтобы получить амплитуды в тех же "попугаях", в которых были исходные сигналы.
Добрый вечер! Попробовал реализовать FFT, но возникло несколько вопросов. Вопрос 1: При получении спектра результат напоминает пилу, т.е. переменная am нарастает до 0xFF затем обнуляеться и снова растет, должно ли так быть?
Код:
{ for(i1=0; i1<32; i1++) { A[i1]=read_adc(0x20);
}
re = im = 0x0000; for(i2=0;i2<32;i2++) { for(i4=0;i4<16;i4++) { smim = A[i2]*sin16[i4]; smre = A[i2]*cos16[i4]; im = im + smim; re = re + smre; } }
tempsqr=(re*re)+(im*im); am=iqrt(tempsqr);
Вопрос 2: Если результат преобразования (переменная am) засунуть в шим, банально OCR0A=am, получается что то непонятное, собственно подскажите пожалуйста как обработать результат что бы засунуть его в шим и скажем помигать диодом? Как я понимаю чем частота ближе к искомой тем чаще он должен моргать, правда это при небольшой отстройку по частоте.
Товарищи, правильно ли я понял: если мне при анализе звукового сигнала не интересны частоты выше 15кГц, то я могу снизить частоту дискретизации до 30кГц?
Да. Но перед этим нужно отфильтровать частоты выше 15, чтобы их на входе и не появлялось. Иначе 16кГц будет отображаться в 14кГц, 20кГц будет видно как 10кГц и т.д.
Ааа, ясно, иными словами, частота дискретизации ВСЕГДА должна вычисляться из максимальной частоты сигнала, независимо от потребностей. Спасибо за пояснение! После прочтения темы возникла мысль, что не обязательно получать весь массив амплитуд частот на выходе. То есть: Получили массивы RE и IM, затем только берем только те k , которые соответствую нужным частотам, исходя из примера товарища Jordan`а
jordan писал(а):
Код:
for (int k = 0; k < 1024; k++) { for (int n = 0; n < 1024; n++) { x_real[k] += x_n[n] * Math.Cos( (-2) * Math.PI * k * n / 1024 ); x_imag[k] += x_n[n] * Math.Sin( (-2) * Math.PI * k * n / 1024); }
Если мне нужны амплитуды, например 1кГц и 5кГц, то я выбрасываю верхний цикл и отдельно считаю для k=(fгарм * SIZE) / fдискр. к1=1000*1024/40000= 25 или 26, к2=5000*1024/40000= 128 Верно ли я вывел?
Если мне нужны амплитуды, например 1кГц и 5кГц, то я выбрасываю верхний цикл и отдельно считаю для k=(fгарм * SIZE) / fдискр. к1=1000*1024/40000= 25 или 26, к2=5000*1024/40000= 128 Верно ли я вывел?
Получается верно) Реализовал этот код "в лоб", работает, частоты выделяются. Теперь дело только за оптимизацией. Но хотелось бы еще уточнить по выбору размера массива: понятно, что чем больше массив, тем выше разрешающая способность по частотам, а вот на точность результата влияет ли? Например, есть массивы: 625 Гц, 1250, 1875... и 312 625 937... Одинаковый результат будет для 625 Гц? Будет ли во 2м случае влияние соседних частот меньше?
"Разрешающая способность по частотам" вообще то называется полосой анализа. И эта полоса обратно пропорциональна ВРЕМЕНИ НАКОПЛЕНИЯ. АЧХ фильтра приведенная к полосе анализа всегда одинакова. Поэтому избирательность по соседнему фильтру не зависит от числа фильтров. Причем если бы было иначе, АЧХ анализатора представляла собой волнистую линию. Энергия сигнала попадающего ровно между фильтрами поровну распределится между этими фильтрами.
Энергия сигнала попадающего ровно между фильтрами поровну распределится между этими фильтрами.
Получается при большем массиве результат точнее? 625 1250 1875 312 625 937 1250, если в сигнале есть составляющая 900 Гц, то в первом случае ее присутствие отразится и на 625 и на 1250, а во 2м случае на 625 и 937 не попав в 1250. Верно?
Естественно, чем уже полоса анализа, тем точнее можно определить спектральный максимум сигнала. Но при этом надо понимать, что реальные сигналы имеют достаточно размытый спектр, хотя бы в силу их ограниченности во времени. То есть у короткого во времени сигнала не может быть узкого спектра. А строго монохроматический спектр имеет бесконечная во времени синусоида. Сиречь, НИКАКАЯ реальная синусоида не может быть строго монохроматичной.
Предлагаю еще немного развить тему для полноты картины. Везде упоминаются таблицы sin/cos для ускорения вычислений. Я попробовал так: рассчитал в экселе для K=1, в проект добавил массив, умноженный на 10000:
Код:
const short sin_k1[N] = {10000, 9998 .......}
теперь кусок:
Код:
x_real[k] += x_n[n] * Math.Cos( (-2) * Math.PI * k * n / 1024 );
стал просто:
Код:
x_real[k] += x_n[n] *sin_k1[n]/10000
работает действительно быстрее, но на такой массив уходит куча памяти, а еще и для других К нужны. Как вы обходите этот момент?
Любая таблица, а особенно большая, должна размещаться в программном фдеше. А МК заточенные, в том числе, под применение таблиц должны иметь инструмент быстрой выборки данных из флеша, для чего область флеша так или иначе отражена в адресное пространство ОЗУ. В Си для МК имеются различные виды синтаксиса и квалификаторов данных,чтобы компилятор размещал константы в программном флеше.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 25
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения