Имам проба, съхранявана в буфер от DirectX. Това е образец на нота, изсвирена и уловена от инструмент. Как да анализирам честотата на семпла (както прави тунер за китара)? Вярвам, че са включени FFT, но нямам указания към HOWTO.
Как анализирате основната честота на PCM или WAV проба? [затворено]
Отговори (7)
FFT може да ви помогне да разберете къде е честотата, но не може да ви каже точно каква е честотата. Всяка точка в FFT е група от честоти, така че ако има пик във вашата FFT, всичко, което знаете е, че честотата, която искате, е някъде в тази група или диапазон от честоти.
Ако искате да е наистина точен, имате нужда от дълъг FFT с висока разделителна способност и много контейнери (= много памет и много изчисления). Можете също така да познаете истинския пик от FFT с ниска разделителна способност, като използвате квадратична интерполация на логаритмично мащабирания спектър, който работи изненадващо добре.
Ако изчислителните разходи са най-важни, можете да опитате да приведете сигнала във форма, в която можете да преброите пресичания на нулата и след това колкото повече броите, толкова по-точно е вашето измерване.
Нито едно от тях обаче няма да работи, ако фундаменталното липсва. :)
Очертах няколко различни алгоритъма тук и интерполираното FFT обикновено е най-точното ( въпреки че това работи само когато фундаментът е най-силният хармоник - в противен случай трябва да сте по-умни за намирането му), с пресичане на нулата за една секунда (въпреки че това работи само за вълнови форми с едно пресичане на цикъл). Нито едно от тези състояния не е типично.
Имайте предвид, че частичните части над основната честота не са перфектни хармоници в много инструменти, като пиано или китара. Всяка част е всъщност малко ненастроена или нехармоничен. Така че пиковете с по-висока честота в FFT няма да бъдат точно на целите числа, кратни на фундамента, и формата на вълната ще се променя леко от един цикъл към следващия, което отхвърля автокорелацията.
За да получите наистина точно отчитане на честотата, бих казал да използвате автокорелацията, за да отгатнете фундамента, след това да намерите истинския пик, като използвате квадратична интерполация. (Можете да направите автокорелацията в честотната област, за да спестите цикли на процесора.) Има много проблеми и правилният метод за използване наистина зависи от вашето приложение.
Има и други алгоритми, които са базирани на времето, а не на честотата. Автокорелацията е сравнително прост алгоритъм за откриване на височина. Справка: http://cnx.org/content/m11714/latest/
Написал съм C# реализации на автокорелация и други алгоритми, които са четими. Вижте http://code.google.com/p/yaalp/.
http://code.google.com/p/yaalp/source/browse/#svn/trunk/csaudio/WaveAudio/WaveAudio Изброява файловете и PitchDetection.cs е този, който искате.
(Проектът е GPL; така че разберете условията, ако използвате кода).
Тунерите за китара не използват FFT или DFT. Обикновено те просто отчитат преминаването през нулата. Може да не получите основната честота, тъй като някои вълнови форми имат повече преминавания през нула от други, но обикновено можете да получите кратно на основната честота по този начин. Това е достатъчно, за да получите нотата, въпреки че може да сте с една или повече октави.
Нискочестотното филтриране преди преброяване на пресичанията на нулата обикновено може да се отърве от излишните пресичания на нулата. Настройката на нискочестотния филтър обаче изисква известно познаване на честотния диапазон, който искате да откриете
FFTs (бързи трансформации на Фурие) наистина ще бъдат включени. FFT ви позволяват да апроксимирате всеки аналогов сигнал със сбор от прости синусоиди с фиксирани честоти и различни амплитуди. Това, което по същество ще правите, е да вземете проба и да я разложите на двойки амплитуда->честота и след това да вземете честотата, която съответства на най-високата амплитуда.
Надяваме се, че друг SO читател може да запълни празнините, които оставям между теорията и кода!
Малко по конкретно:
Ако започнете с необработен PCM във входен масив, това, което основно имате, е графика на амплитудата на вълната спрямо времето. Извършването на FFT ще трансформира това в честотна хистограма за честоти от 0 до 1/2 от входната честота на дискретизация. Стойността на всеки запис в масива с резултати ще бъде „силата“ на съответната подчестота.
Така че, за да намерите основната честота, дадена входен масив с размер N, взет от S проби/секунда:
FFT(N, input, output);
max = max_i = 0;
for(i=0;i<N;i++)
if (output[i]>max) max_i = i;
root = S/2.0 * max_i/N ;
Извличането на основни честоти в PCM аудио сигнал е трудна задача и ще има много да се говори за нея...
Както и да е, обикновено методът, базиран на времето, не е подходящ за полифонични сигнали, тъй като сложна вълна, дадена от сумата от различни хармонични компоненти поради множество основни честоти, има скорост на преминаване през нулата, която зависи само от най-нискочестотния компонент... Също в честотната област FFT не е най-подходящият метод, тъй като честотното разстояние между нотите следва експоненциална скала, а не линейна. Това означава, че разделителната способност с постоянна честота, използвана в метода FFT, може да е недостатъчна за разрешаване на бележки с по-ниска честота, ако размерът на прозореца за анализ във времевата област не е достатъчно голям.
По-подходящ метод би бил постоянна Q трансформация, която се прилага чрез DFT след процес на нискочестотно филтриране и децимация с 2 (т.е. намаляване наполовина всяка стъпка на честотата на вземане на проби) на сигнала, за да се получат различни поддиапазони с различна честота резолюция. По този начин изчисляването на DFT се оптимизира. Проблемът е, че и времевата разделителна способност е променлива и се увеличава за по-ниските подленти...
И накрая, ако се опитваме да оценим основната честота на една нота, FFT/DFT методите са ок. Нещата се променят за полифоничен контекст, в който части от различни звуци се припокриват и сумират/анулират амплитудата им в зависимост от тяхната фазова разлика, и така един спектрален пик може да принадлежи към различни хармонични съдържания (принадлежащи към различни ноти). Корелацията в този случай не дава добри резултати...
Приложете DFT и след това извлечете основната честота от резултатите. Търсенето в гугъл за DFT информация ще ви даде информацията, от която се нуждаете - бих ви свързал с някои, но те се различават значително в очакванията за знания по математика.
Късмет.