2013-03-01 3 views
0

Я только что написал реализацию dft. Вот мой код:получить результат из массива дискретного форвардного преобразования

 int T = 2205; 

     float[] sign = new float[T]; 
     for (int i = 0, j = 0; i < T; i++, j++) 
      sign[i] = (float)Math.Sin(2.0f * Math.PI * 120.0f * i/ 44100.0f); 

     float[] re = new float[T]; 
     float[] im = new float[T]; 
     float[] dft = new float[T]; 

     for (int k = 0; k < T; k++) 
     { 
      for (int n = 0; n < T; n++) 
      { 
       re[k] += sign[n] * (float)Math.Cos(2.0f* Math.PI * k * n/T); 
       im[k] += sign[n] * (float)Math.Sin(2.0f* Math.PI * k * n/T);; 
      } 
      dft[k] = (float)Math.Sqrt(re[k] * re[k] + im[k] * im[k]); 
     } 

Так выборки-частотных 44100 Гц и у меня есть 50ms сегмент 120Hz синусового волны. Согласно результату, у меня есть пик функции dft на pont 7 и 2200. Я сделал что-то неправильно, а если нет, как интерпретировать результаты?


Я пробовал метод FFT AFORGE. Heres - мой код.

 int T = 2048; 

     float[] sign = new float[T]; 
     AForge.Math.Complex[] input = new AForge.Math.Complex[T]; 
     for (int i = 0; i < T; i++) 
     { 
      sign[i] = (float)Math.Sin(2.0f * Math.PI * 125.0f * i/44100.0f); 
      input[i].Re = sign[i]; 
      input[i].Im = 0.0; 
     } 

     AForge.Math.FourierTransform.FFT(input, AForge.Math.FourierTransform.Direction.Forward); 
     AForge.Math.FourierTransform.FFT(input, AForge.Math.FourierTransform.Direction.Backward); 

я ожидал получить оригинальный знак, но я получил что-то другое (функция только с положительными значениями). Это нормально? Спасибо заранее!

ответ

1

Ваш код выглядит правильно, но он может быть более эффективным, DFT часто решается с помощью алгоритма FFT (преобразование с быстрым преобразованием, это не новое преобразование, это просто алгоритм для более эффективного решения DFT).

Даже если вы не хотите внедрять FFT (что немного сложнее понять, и труднее заставить его работать с данными, которые не находятся в форме 2^n) или использовать какой-либо открытый код, вы можете сделать свою реализацию бит быстро, например, видя, что 2.0f * Math.PI * K/T является константой вне внутреннего цикла, поэтому вы можете вычислить его один раз для каждого k (переместить его за пределы внутреннего цикла), а затем просто умножить его на n в своих cos/sin.

Что касается положения и интерпретации, вы изменили свой домен, теперь ваша ось X, которая является индексом данных в таблице, соответствует не времени, а частоте. У вас есть выборка 44100Hz, и у вас есть выборки 2205, что означает, что каждый 1 образец представляет величину вашего входного сигнала с частотой, равной 44100Hz/2205 = 20Hz. У вас есть пик амплитуды на 7-й точке (индекс 6), потому что ваш сигнал составляет 120 Гц, поэтому 6 * 20Hz = 120Hz - это то, что вы ожидаете.

секунд пик может показаться, что представляет собой некоторую высокую частоту, но это просто ложный сигнал, потому что ваша частота дискретизации 44100Hz вы не можете измерить частоты выше 44100Hz/2 (закона Найквист), который, если вы отсечение точки, после этой частоты Данные DFT недопустимы. Вот почему вторая половина таблицы недействительна, и в основном ваша первая половина, но зеркальная, и вы можете ее игнорировать.

Редактировать // Из ваших вопросов, которые я могу видеть, что вы заинтересованы в обработке звука, вы можете захотеть Google NForge.Net библиотека, которая является большой библиотека с открытым исходным кодом для аудио и визуальной обработки и его автором, многие хорошие статьи на codeproject.com относительно много из его возможностей.

+0

Спасибо за ответ! Да, мне нужно сделать приложение, которое может вычислять основную частоту голоса в реальном времени. Сначала я попробовал DFT, но после того, как мне нужно реализовать БПФ. Не могли бы вы дать мне хороший источник, как понять/реализовать его? Другое дело, если одно устройство 20 Гц, тогда я могу получить частоты только, которые можно разделить на 20? Просто, если я установил частоту, например 127 Гц, результат будет таким же, если он равен 120 Гц. – user1707045

+0

@ user1707045 Возможно, это не то же самое, посмотрите поближе или, по крайней мере, не следует, я немного сыграл с вашим кодом, и если вы это сделаете. установите частоту до 130 Гц, вы должны получить 2 магнитных шипа на 120 Гц и 140 Гц соответствующие индексы, но оба будут иметь меньшую величину, поэтому у вас есть 2 пика, говорящих вам: «у вас синусоида где-то между 120 и 140 Гц.Это означает, что вы можете «поймать» все частоты, но чем больше образцов у вас будет, тем точнее результат. Проверьте мои изменения и ссылки, если вы google «aforge fft», вы можете найти много полезных материалов, и это только начало! –

Смежные вопросы