Jestem w stanie napisać podstawowy generator fal sinusoidalnych dla audio, ale chcę, aby mógł płynnie przechodzić z jednej częstotliwości na drugą. Jeśli po prostu przestanę generować jedną częstotliwość i natychmiast przełączę się na inną, nastąpi nieciągłość w sygnale i usłyszysz „kliknięcie”.
Moje pytanie brzmi: co to jest dobry algorytm do generowania fali, która zaczyna się od, powiedzmy, 250 Hz, a następnie przechodzi do 300 Hz, bez wprowadzania żadnych kliknięć. Jeśli algorytm zawiera opcjonalny czas poślizg / portamento, to tym lepiej.
Mogę wymyślić kilka możliwych podejść, takich jak nadpróbkowanie, po którym następuje filtr dolnoprzepustowy, a może przy użyciu falowodu, ale jestem pewien, że jest to dość powszechny problem, że istnieje standardowy sposób radzenia sobie z nim.
Odpowiedzi:
Jednym z podejść, które stosowałem w przeszłości, jest utrzymywanie akumulatora fazowego, który jest używany jako indeks do tabeli przeglądów przebiegów. Wartość delta fazowa jest dodawana do akumulatora przy każdym okresie próbkowania:
Aby zmienić częstotliwość, należy zmienić deltę fazową dodawaną do akumulatora fazowego przy każdej próbce, np
gdzie:
To gwarantuje, że fala wyjściowa jest ciągła, nawet jeśli zmienisz dynamicznie fazę_delta, np. Przy zmianach częstotliwości, FM itp.
Aby uzyskać płynniejsze zmiany częstotliwości (portamento), możesz zwiększyć wartość Phase_Delta między jej starą a nową wartością w odpowiedniej liczbie przedziałów próbkowania zamiast zmieniać ją natychmiast.
Należy pamiętać, że
phase_index
iphase_delta
obie mają liczbę całkowitą i ułamkową składnik, czyli muszą być ustalony punkt lub zmiennoprzecinkowych. Część całkowitą indeksu fazy (wielkość tabeli modulo) stosuje się jako indeks do kształtu fali LUT, a część ułamkową można opcjonalnie zastosować do interpolacji między sąsiednimi wartościami LUT dla uzyskania wyższej jakości wyjściowej i / lub mniejszego rozmiaru LUT.źródło
Jednym z najlepszych sposobów na utworzenie fali sinusoidalnej jest użycie złożonego fazora z aktualizacją rekurencyjną. To znaczy
gdzie z [n] jest wskaźnikiem, , gdzie jest częstotliwością kątową oscylatora w radianach, a wskaźnikiem próby. Zarówno rzeczywista, jak i wyobrażona część są falami sinusoidalnymi, są o 90 stopni poza fazą. Bardzo wygodne, jeśli potrzebujesz zarówno sinusa, jak i cosinusa. Obliczenie pojedynczej próbki wymaga tylko 4 wielokrotności i 4 dodań i jest DUŻO tańsze niż cokolwiek zawierającego sin () cos () lub tabele odnośników. Potencjalnym problemem jest to, że amplituda może zmieniać się w czasie z powodu problemów z dokładnością numeryczną. Jednak naprawa tego jest dość prosta. Powiedzmy, że . Wiemy, że powinien mieć wielkość jedności, tjΩ=exp(jω) ω n z[n] z[n]=a+jb z[n]
Możemy więc od czasu do czasu sprawdzać, czy nadal tak jest, i odpowiednio korygować. Dokładna korekta byłaby
Jest to niezręczne obliczenie, ale ponieważ jest bardzo zbliżone do jedności, możesz przybliżać warunki z rozszerzeniem Taylora wokół i otrzymujemy1 / √a⋅a+b⋅b x=11/x−−√ x=1
więc korekta upraszcza się
Zastosowanie tej prostej korekty co kilkaset próbek zapewni stabilność oscylatora na zawsze.
Aby ciągle zmieniać częstotliwość, mnożnik W musi zostać odpowiednio zaktualizowany. Nawet nieciągła zmiana mnożnika utrzyma funkcję ciągłego oscylatora. Jeśli wymagane jest zwiększenie częstotliwości, aktualizacja może zostać podzielona na kilka kroków lub można użyć tego samego algorytmu oscylatora, aby zaktualizować sam mnożnik (ponieważ jest to również wskaźnik fazowania zespolonego wzmocnienia jedności).
źródło
Z tej strony :
Wygląda na to, że powinno działać.
(W rzeczywistości, jeśli oba są zsynchronizowane na osi x po przejściu, przypuszczam, że stopniowe przejście nie jest konieczne.)
źródło
Zgadzam się z poprzednimi sugestiami użycia akumulatora fazowego. Zasadniczo wejściem sterującym jest wielkość przesunięcia fazy na krok lub na okres zegara (lub na przerwanie lub cokolwiek innego), tak że zmiana tej wartości zmienia częstotliwość bez nieciągłości w fazie. Amplituda fali jest następnie określana na podstawie skumulowanej wartości fazy albo za pomocą LUT, albo po prostu obliczenia sin (theta) lub cos (theta).
Zasadniczo jest to powszechnie znane jako oscylator sterowany numerycznie (NCO) lub bezpośredni syntezator cyfrowy (DDS). Przeszukanie tych terminów przyniesie prawdopodobnie więcej, niż chcesz wiedzieć na temat teorii i praktyki, aby działały dobrze.
Dodanie dodatkowego akumulatora może umożliwić płynne przejścia między częstotliwościami, jak zasugerowałeś, jeśli jest to również pożądane, poprzez kontrolowanie szybkości zmiany wartości przesunięcia fazowego. Jest to czasami nazywane cyfrowym analizatorem różnicowym lub DDA.
źródło
1. rzędu, należy wyregulować fazę początkową sinusoidy nowej częstotliwości, tak aby była taka sama, jak faza poprzedniej sinusoidy w punkcie pierwszej próby przejścia. Oblicz pierwszą częstotliwość i użyj jej fazy dla drugiej częstotliwości.
Drugą opcją może być zwiększenie fazy d_fazy od częstotliwości jednej częstotliwości do następnej w kilku próbkach. Oczyści to ciągłość pierwszej pochodnej i zapewni poślizg.
Trzecią opcją może być użycie okna wygładzającego, takiego jak podwyższony cosinus, na szybkość narastania fazy d_phase.
źródło