Rozpoznawanie nut na smartfonie

Z ograniczonymi zasobami, takimi jak wolniejsze Procesory, rozmiar kodu i pamięć RAM, jak najlepiej wykryć wysokość nuty muzycznej, podobną do tego, co zrobiłby tuner elektroniczny lub programowy?

Powinienem użyć:

  • Kiss FFT
  • FFTW
  • Dyskretna Transformata Falowa
  • autokorelacja
  • analiza przejścia zerowego
  • filtry oktawowe

Inne?

W skrócie, staram się rozpoznać jedną nutę muzyczną, dwie oktawy poniżej środka-C do dwóch oktaw powyżej, granych na dowolnym (rozsądnym) instrumencie. Chciałbym być w granicach 20% półtonu - innymi słowy, jeśli użytkownik gra zbyt płasko lub zbyt ostro, muszę to rozróżnić. Nie będę jednak potrzebował dokładności wymaganej do tuningu.

Author: CharlesB, 2009-09-22

5 answers

Jeśli nie potrzebujesz tak dużej dokładności, FFT może być wystarczający. Okno najpierw kawałek dźwięku, aby uzyskać dobrze zdefiniowane szczyty, a następnie znaleźć pierwszy znaczący szczyt.

Szerokość Bin = częstotliwość próbkowania / rozmiar FFT:

Podstawy wahają się od 20 Hz do 7 kHz, więc częstotliwość próbkowania 14 kHz byłaby wystarczająca. Następna "standardowa" częstotliwość próbkowania to 22050 Hz.

Rozmiar FFT jest następnie określany przez żądaną precyzję. Wyjście FFT jest liniowe w częstotliwość, podczas gdy tony muzyczne są logarytmiczne w częstotliwości, więc najgorszy przypadek precyzji będzie przy niskich częstotliwościach. Dla 20% półtonu przy 20 Hz potrzebna jest szerokość 1,2 Hz , co oznacza Długość FFT18545. Następna potęga dwójki to 215 = 32768. Jest to 1,5 sekundy danych i zajmuje procesorowi mojego laptopa 3 ms do obliczenia.

To nie zadziała z sygnałami, które mają " brakujące Podstawowe ", a znalezienie" pierwszego znaczącego " piku jest nieco trudne (ponieważ harmoniczne są często wyższe niż podstawowe), ale możesz znaleźć sposób, który pasuje do twojej sytuacji.

Autokorelacja i spektrum produktów harmonicznych są lepsze w znalezieniu prawdziwej podstawy dla fali zamiast jednej z harmonicznych, ale nie sądzę, aby zajmowały się tak dobrze nieharmonicznością , a większość instrumentów, takich jak fortepian czy gitara, jest nieharmoniczna (harmoniczne są nieco ostre od tego, co powinny być). To naprawdę to zależy od okoliczności.

Można również zapisać jeszcze więcej cykli procesora, obliczając tylko w określonym zakresie częstotliwości, używając transformacjiChirp-z .

Napisałem kilka różnych metod w Pythonie dla celów porównawczych.

 14
Author: endolith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-02 00:25:36

Jeśli chcesz zrobić rozpoznawanie wysokości dźwięku w czasie rzeczywistym (i z dokładnością do 1/100 półtonu), twoją jedyną prawdziwą nadzieją jest podejście zero-crossing. I to słaba nadzieja, przykro mi to mówić. Zero-crossing może oszacować wysokość na podstawie zaledwie kilku długości fal danych i można to zrobić za pomocą mocy obliczeniowej smartfona, ale nie jest to szczególnie dokładne, ponieważ drobne błędy w pomiarze długości fal powodują duże błędy w szacowanej częstotliwości. Urządzeń takich jak syntezatory gitarowe (które wydedukować wysokość struny gitarowej o zaledwie kilku długościach fal) poprzez kwantyzację pomiarów do nut skali. Może to działać dla Twoich celów, ale pamiętaj, że zero-crossing działa świetnie z prostymi kształtami fal, ale ma tendencję do pracy coraz mniej dobrze z bardziej złożonymi dźwiękami instrumentu.

W mojej aplikacji (syntezator programowy, który działa na smartfonach) wykorzystuję nagrania pojedynczych nut instrumentalnych jako surowiec do syntezy Wavetable, a także do produkcji nuty przy określonej wysokości dźwięku, muszę znać podstawową wysokość nagrania, dokładną do 1/1000 półtonu(naprawdę potrzebuję tylko dokładności 1/100, ale jestem o to OCD). Podejście zerowe jest dużo zbyt niedokładne, a podejścia oparte na FFT są albo zbyt niedokładne, albo zbyt wolne (lub czasami oba).

Najlepsze podejście, jakie znalazłem w tym przypadku, to użycie autokorelacji. Z autokorelacją w zasadzie odgadniesz rzut, a następnie zmierz autokorelację próbki przy odpowiedniej długości fali. Skanując zakres prawdopodobnych wysokości (powiedzmy A = 55 Hz do A = 880 Hz) przez półtony, lokalizuję najbardziej skorelowaną wysokość, a następnie wykonuję bardziej drobnoziarnisty skan w sąsiedztwie tej wysokości, aby uzyskać dokładniejszą wartość.

Najlepsze dla Ciebie podejście zależy wyłącznie od tego, do czego próbujesz tego użyć.

 13
Author: MusiGenesis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-22 03:34:38

Nie znam wszystkich metod, które wymieniasz, ale to, co wybierzesz, powinno zależeć przede wszystkim od charakteru danych wejściowych. Analizujesz czyste tony, czy twoje źródło sygnału ma wiele nut? Czy mowa jest cechą twojego wkładu? Czy są jakieś ograniczenia co do długości czasu, jaki musisz wypróbować dane wejściowe? Czy jesteś w stanie wymienić trochę celności na szybkość?

W pewnym stopniu to, co wybierzesz, zależy również od tego, czy chcesz wykonać swoje obliczenia w Czas lub w przestrzeń częstotliwości . Konwersja szeregów czasowych na reprezentację częstotliwości wymaga czasu, ale z mojego doświadczenia wynika, że daje lepsze wyniki.

Autokorelacja porównuje dwa sygnały w dziedzinie czasu. Naiwna implementacja jest prosta, ale stosunkowo kosztowna w obliczeniu, ponieważ wymaga różnicowania między wszystkimi punktami w oryginalnych i przesuniętych w czasie sygnałach, a następnie różnicowania w celu identyfikacji punktów zwrotnych w funkcja autokorelacji, a następnie wybór minimum odpowiadającego częstotliwości podstawowej. Istnieją alternatywne metody. Na przykład, średnia różnica wielkości jest bardzo tanią formą autokorelacji, ale dokładność cierpi. Wszystkie techniki autokorelacji narażone są na błędy oktawowe, ponieważ w funkcji występują piki inne niż podstawowe.

Pomiar punktów zerowych jest prosty i prosty, ale napotkasz problemy, jeśli mają wiele przebiegów obecnych w sygnale.

W przestrzeni częstotliwości, techniki oparte na FFT mogą być wystarczająco skuteczne dla Twoich celów. Jednym z przykładów jest technika spektrum produktów harmonicznych, która porównuje widmo mocy sygnału z próbkowanymi w dół wersjami dla każdej harmonicznej i identyfikuje wysokość przez pomnożenie widma razem w celu uzyskania wyraźnego piku.

Jak zawsze, nie ma substytutu testowania i profilowania kilku technik, aby empirycznie określ, co będzie najlepsze dla Twojego problemu i ograniczeń.

Taka odpowiedź może tylko zarysować powierzchnię tego tematu. A także wcześniejsze linki, oto kilka istotnych odniesień do dalszej lektury.

 6
Author: ire_and_curses,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-22 00:11:02

W moim projekcie danstuner wziąłem kod z Audacity . Zasadniczo zajęło FFT, a następnie znalazł moc szczytową poprzez umieszczenie krzywej sześciennej na FFT i znalezienie piku tej krzywej. Działa całkiem nieźle, chociaż musiałem się bronić przed skokami oktawowymi.

Zobacz Widmo.cpp .

 5
Author: dfrankow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-21 23:17:29

Zero crossing nie zadziała, ponieważ typowy dźwięk ma harmoniczne i zero-crossings znacznie więcej niż częstotliwość podstawowa.

Coś, z czym eksperymentowałem (jako projekt strony domowej) było takie:

  1. Próbkuj dźwięk za pomocą ADC z dowolną częstotliwością próbkowania.
  2. Wykryj poziomy krótkoterminowych dodatnich i ujemnych pików kształtu fali(okno przesuwne lub podobne). Tj. detektor obwiedni.
  3. Stwórz kwadratową falę, która idzie wysoko, gdy kształt fali idzie wewnątrz 90% (lub tak) pozytywnej koperty i schodzi nisko, gdy kształt fali przechodzi w 90% negatywnej koperty. Tj. śledzenie fali kwadratowej z histerezą.
  4. Zmierz częstotliwość tej fali kwadratowej za pomocą prostych obliczeń liczenia/czasu, używając tylu próbek, ile potrzebujesz, aby uzyskać wymaganą dokładność.

Odkryłem jednak, że przy wejściach z mojej elektronicznej klawiatury, dla niektórych dźwięków instrumentu udało się podnieść 2× Częstotliwość bazową (Następna oktawa). To był projekt poboczny i nigdy nie doszedłem do wdrożenia rozwiązania, zanim przejdę do innych rzeczy. Ale myślałem, że miał obietnicę jako znacznie mniejsze obciążenie procesora niż FFT.

 5
Author: Craig McQueen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-22 00:03:43