Простая вспомогательная функция, записанная в Kotlin.
private fun Canvas.drawTopRoundRect(rect: RectF, paint: Paint, radius: Float) {
// Step 1. Draw rect with rounded corners.
drawRoundRect(rect, radius, radius, paint)
// Step 2. Draw simple rect with reduced height,
// so it wont cover top rounded corners.
drawRect(
rect.left,
rect.top + radius,
rect.right,
rect.bottom,
paint
)
}
Использование:
canvas.drawTopRoundRect(rect, paint, radius)
Первый бит в БПФ равен DC (0 Гц), второй бит Fs / N
, где Fs
- частота дискретизации, а N
- размер БПФ. Следующий бит 2 * Fs / N
. Чтобы выразить это в общих терминах, nth bin n * Fs / N
.
Итак, если ваша частота дискретизации, Fs
, скажем, 44,1 кГц и ваш размер FFT, N
- 1024, то выходы БПФ на выходе:
0: 0 * 44100 / 1024 = 0.0 Hz
1: 1 * 44100 / 1024 = 43.1 Hz
2: 2 * 44100 / 1024 = 86.1 Hz
3: 3 * 44100 / 1024 = 129.2 Hz
4: ...
5: ...
...
511: 511 * 44100 / 1024 = 22006.9 Hz
Обратите внимание, что для реального входного сигнала (мнимая часть всего нуля) вторая половина БПФ (бины от N / 2 + 1
до N - 1
) не содержат полезной дополнительной информации (они имеют сложную сопряженную симметрию с первыми N / 2 - 1
бункерами). Последний полезный бит (для практических применений) находится в N / 2 - 1
, что соответствует 22006,9 Гц в приведенном выше примере. Бит в N / 2
представляет энергию на частоте Найквиста, т. Е. Fs / 2
(= 22050 Гц в этом примере), но это, как правило, не имеет никакого практического применения, поскольку фильтры сглаживания обычно будут ослаблять любые сигналы при и выше Fs / 2
.
Взгляните на мой ответ здесь .
Ответ на комментарий:
FFT фактически вычисляет кросс-корреляцию входного сигнала с синусоидальными и косинусоидальными функциями (базовые функции) в диапазоне одинаково разнесенных частот. Для данного выхода FFT имеется соответствующая частота (F), как указано в ответе, который я опубликовал. Реальная часть выходного образца представляет собой кросс-корреляцию входного сигнала с cos(2*pi*F*t)
, а мнимая часть - это взаимная корреляция входного сигнала с sin(2*pi*F*t)
. Причина, по которой входной сигнал коррелирует с функциями sin
и cos
, заключается в учете разностей фаз между входным сигналом и базовыми функциями.
Принимая величину комплексного выхода FFT, вы получаете оценку того, насколько хорошо входной сигнал коррелирует с синусоидами на множестве частот независимо от фазы входного сигнала. Если вы просто анализируете частотный контент сигнала, вы почти всегда берете квадрат величины или величины сложного выхода БПФ.
Коэффициенты выходного сигнала FFT (для комплексного ввода размера N) составляют от 0 до N - 1, сгруппированных как частота [LOW, MID, HI, HI, MID, LOW].
Я считаю, что элемент в точке k имеет ту же частоту, что и элемент в Nk, поскольку для реальных данных FFT [Nk] = комплексно-сопряженный FFT [k].
Порядок сканирования от LOW до HIGH частоты
0,
1,
N-1,
2,
N-2
...
[N/2] - 1,
N - ([N/2] - 1) = [N/2]+1,
[N/2]
Есть [N / 2] +1 группы частот от индекса i = 0 до [N / 2], каждый из которых имеет frequency = i * SamplingFrequency / N
. Таким образом, частота в ячейке FFT [k]:
if k <= [N/2] then k * SamplingFrequency / N
if k >= [N/2] then (N-k) * SamplingFrequency / N
Частота вашего k-го БПФ равна 2 * pi * k / N.
Я использовал следующее:
public static double Index2Freq(int i, double samples, int nFFT) {
return (double) i * (samples / nFFT / 2.);
}
public static int Freq2Index(double freq, double samples, int nFFT) {
return (int) (freq / (samples / nFFT / 2.0));
}
Входы:
i
: Bin для доступа к samples
: Частота дискретизации в герцах (т.е. 8000 Гц, 44100 Гц и т. Д.) nFFT
: размер вектора FFT samples
или nFFT
. Поэтому, пожалуйста, сделайте это более объяснительным.
– mostar
20 August 2012 в 17:16
i * samples / nFFT
. Почему дополнительный 2
там? Я что-то упускаю?
– yati sagade
14 May 2014 в 10:38