Przetwarzanie sygnalow akustycznych w oparciu o procesor
Transkrypt
Przetwarzanie sygnalow akustycznych w oparciu o procesor
Seminarium dyplomowe Przetwarzanie sygnałów akustycznych w oparciu o procesor wielordzeniowy Temat pracy: P romotor: dr inż. Krzysztof C zyż P lan prezentacji: ● ● ● ● Dygresja dotycząca układu z filtrowaniem osobnych kanałów Synchronizacja rdzeni – instrukcje oraz ich wykorzystanie Arytmetyka stałoprzecinkowa i jej zastosowanie Identyfikacja odpowiedzi impulsowej Filtrowanie osobnych kanałów L Fl Kanały wejściowe: lewy i prawy R Fr Filtrowanie osobnych kanałów Problem filtracji osobnych kanałów na osobnych rdzeniach w powyższym przypadku nie wprowadza praktycznie żadnych komplikacji (poza synchronizacją w czasie) w stosunku do standardowego filtrowania dźwięku stereo na pojedynczym procesorze. Na dowód tego można przedstawić różnicę z punktu widzenia programistycznego: Filtrowanie osobnych kanałów Zaimplementowana na jednym rdzeniu sekwencja: iChannel1LeftOut = przetw(iChannel1LeftIn); iChannel1RightOut = przetw(iChannel1RightIn); Wymaga jedynie umieszczenia próbek w pamięci do której oba rdzenie mają swobodny dostęp (bądź zadeklarowanie ich jako zmienne globalne) oraz „przeklejenia” instrukcj iChannel1RightOut = przetw(iChannel1RightIn); do kodu dedykowanego dla rdzenia drugiego. Jedynym problemem, który może tu wystąpić jest brak synchronizacji próbek sygnału na wyjściu spowodowany dedykowaniem jednego z rdzeni do obsługi przerwań sprzętowych oraz obsługą przez oba rdzenie mechanizmów wymiany informacji między sobą, o czym w dalszej części prezentacji. Filtrowanie osobnych kanałów Mikrofon L Fl Kanały wejściowe: lewy i prawy R Sprzężenie skrośne Fr Mikrofon Filtrowanie osobnych kanałów Mikrofon L Fl - Frl Flr R Fr - Mikrofon Synchronizacja filtracji Sygnał wejściowy Kanał lewy rdzeń A Może zdarzyć się, że: t≠t Kanał prawy Należy więc zadbać o jakąś wymianę informacji pomiędzy rdzeniami tak, by próbki przetworzone przez nie docierały do odbiorcy z takim samym (możliwie jak najmniejszym) opóźnieniem. rdzeń B t t t Synchronizacja Filtracji Wymiana informacji między rdzeniami możliwa jest w bardzo prosty sposób: wystarczy zadeklarować globalną flagę (lub kilka flag), którą oba rdzenie będą zmieniać w zależności od sytuacji, która aktualnie ma miejsce. Tu pojawia się problem: jak zapewnić obu rdzeniom dostęp do tego samego miejsca w pamięci układu tak, by uniknąć ewentualnych konfliktów? Tutaj z pomocą programiście przychodzi instrukcja „TESTSET” Instrukcja TESTSET TESTSET jest atomiczną instrukcją która ładuje pośrednio zaadresowany bajt pamięci, sprawdza, czy jest on równy “0” a następnie ustawia najbardziej znaczący bit tego bajtu. Jeśli bajt jest pierwotnie niezerowy, TESTSET ustawia bit CC (Condition Code Flag), jeśli był zerem, czyści bit CC. W bibliotekach ADI dla C/C++ instrukcja ta używana jest w 3 funkcjach: adi_acquire_lock, adi_release_lock, adi_try_lock Instrukcja TESTSET Aby skorzystać z tych funkcji należy zadeklarować wskaźnik do obiektu typu testeset_t. Działanie funkcji: ● ● ● adi_acquire_lock(*testset_t) – funkcja ta cyklicznie próbuje uzyskać możliwość zablokowania obszaru pamięci, sprawdzając bajt będący obiektem w/w typu adi_release_lock(*testset_t) – jest to funkcja „odblokowująca” flagę dostępu do danego obszaru adi_try_lock(*testset_t) – funkcja dokonująca jednorazowego sprawdzenia, czy obszar jest dostępny w danej chwili. Jako jedyna z 3 powyższych funkcja ta zwraca wartość (typu bool). Instrukcja TESTSET Przykład wykorzystania praktycznego: iChannel0RightIn = iRxBuffer1[INTERNAL_ADC_R0]; rdzeń B adi_acquire_lock(jt); przyszlo=true; adi_release_lock(jt); if (przyszlo==true) { adi_acquire_lock(jt); rdzeń A przyszlo=false; adi_release_lock(jt); liczba=iChannel0RightIn; ADSP BF-561 Blackfin jest procesorem stałoprzecinkowym, więc wskazane jest przeprowadzanie wszelkich operacji arytmetycznych właśnie na typach stałoprzecinkowych. W tym celu producent wyposażył kompilator w zestaw gotowych funkcji arytmetycznych oraz specjalne typy zmiennych, których wykożystanie zapewnia maksymalną wydajność aplikacji. Typy fract16 oraz fract32 Zakres wartości obu tych typów mieści się w przedziale <-1,1) Tak reprezentowane są liczby obu tych typów w pamięci Typy fract16 oraz fract32 Kompilator C/C++ VisualDSP++ posiada wbudowane funkcje służące do wykonywania operacji matematycznych na tych typach, jak również funkcje służące do konwersji wartości z typu float na typ fract16 lub fract32. Dla języka C należy użyć specjalnych funkcji arytmetycznych aby zapewnić poprawne obliczenia na zmiennych tych typów. Dla C++ zdefiniowane są klasy w których zaimplementowane jest przeładowanie standardowych operatorów arytmetycznych. Typy fract16 oraz fract32 Funkcje arytmetyczne dla typów stałoprzecinkowych na przykładzie fract32: ADI dostarcza dwa zestawy funkcji wbudowanych: − zestaw podstawowy – obejmuje takie funkcje jak: dodawanie, odejmowanie, mnożenie, shiftowanie, negacja bitowa itp. − ETSI Lib – podobnie jak powyżej, z tym, że niektóre funkcje połączone są w jedną całość (np. MAC) i użytkownik sam dba o ewentualne skutki nasycenia lub przeniesienia (rejestr ASTAT) Typy fract16 oraz fract32 Przykład wykorzystania funkcji bibliotecznych dla algorytmu FIR w dziedzinie czasu: wartosc=add_fr1x32(wartosc,(mult_fr1x32(fr16 _tofr32(wspol[ILETEGOi]),probki[ind2]))); add_fr1x32 – dodawanie dwóch liczb fract32 mult_fr1x32 – mnożenie dwóch liczb fract32 fr16_tofr32 – konwersja z fract16 na fract32 Eksperyment Identyfikacyjny Komputer PC Głośnik Mikrofon W późniejszym czasie: rejestrator dźwięku z laboratorium, jako jego źródło wciąż komputer. Eksperyment Identyfikacyjny ● ● Eksperyment na podstawie którego można uzyskać model odpowiedzi impulsowej pomieszczenia składa się z następujących kroków: Wygenerowanie kilku (lub kilkunastu) sekwencji białego szumu jako pobudzenia. (wł. wygenerowanie jednej sekwencji i powielenie jej kilkakrotnie); Odegranie wygenerowanej sekwencji w badanym pomieszczeniu jednocześnie nagrywając ustawionym w pewnej odległości od głośników mikrofonem odpowiedzi; Eksperyment Identyfikacyjny C.D. ● Uśrednienie otrzymanych wyników do długości wejsciowej sekwencji białego szumu ● Obliczenie korelacji wzajemnej sygnału wejściowego oraz wyjściowego, co daje w sumie 2*n-1 próbek (n – długość pojedynczej sekwencji) ● Pierwsza „połowa” próbek jest odbitą w czasie poszukiwaną odpowiedzią impulsową; Eksperyment Identyfikacyjny Ważniejsze fragmenty m-file'a: wavplay(calosc,czestotliwosc,'async'); nagranie=wavrecord(10* dlug,czestotliwosc,1); Niewielkie opóźnienie while i<(dlug+1); wyj(i)=nagranie((2* dlug)+i)+nagranie((3* dlug)+i... Problem czasochłonności obliczeń kor=xcorr(wej,wyj); odimp=kor(1:dlug-1)'; plot(odimp); Eksperyment Identyfikacyjny Przykładowa odpowiedź impulsowa rzeczywistego pomieszczenia: 3000 2000 1000 0 -1 0 0 0 -2 0 0 0 -3 0 0 0 -4 0 0 0 0 0 .2 0 .4 0 .6 0 .8 1 1 .2 1 .4 1 .6 1 .8 2 x 10 5 Kolejne problemy: ● ● ● ● Wydajność obliczeń przy dużym rzędzie filtru i dużej częstotliwości próbkowania Lepsze wyniki identyfikacji odpowiedzi impulsowej (?) Rozlokowanie w pomiędzy dostępnymi pamięciami danych oraz kodu Identyfikacja on-line odwrotnego modelu pomieszczenia + equalizacja C ele na przyszłość ● ● ● Identyfikacja odpowiedzi impulsowych pomieszczeń uzyskanych z pomiarów za pomocą aparatury znajdującej się w laboratorium Implementacja alternatywnych form filtru FIR w celu maksymalnej optymalizacji wydajności obliczeń Próba zaimplementowania identyfikacji odpowiedzi impulsowej „on-line” oraz „equalizacji” pomieszczenia odsłuchowego Dziękuję za uwagę