2013-03-18 18 views
5

Pracuję nad aplikacją na iPada i chcę przeanalizować dźwięk z odtwarzanego wideo. Wszystko idzie dobrze, używając MTAudioProcessingTap. Obecnie mam trochę kodu testowego do testowania/pomiaru głośności lewego i prawego kanału. To wszystko będzie całkiem dobrze:Filtr dolnoprzepustowy, obliczanie RMS na iOS

void process(MTAudioProcessingTapRef tap, CMItemCount numberFrames, 
     MTAudioProcessingTapFlags flags, AudioBufferList *bufferListInOut, 
     CMItemCount *numberFramesOut, MTAudioProcessingTapFlags *flagsOut) 
{ 
    OSStatus err = MTAudioProcessingTapGetSourceAudio(tap, numberFrames, bufferListInOut, 
                flagsOut, NULL, numberFramesOut); 

    if (err) 
     NSLog(@"Error from GetSourceAudio: %ld", err); 

    float leftVolume, rightVolume; 

    for (CMItemCount i = 0; i < bufferListInOut->mNumberBuffers; i++) 
    { 
     AudioBuffer *pBuffer = &bufferListInOut->mBuffers[i]; 
     int cSamples = numberFrames * pBuffer->mNumberChannels; 

     float *pData = (float *)pBuffer->mData; 

     float rms = 0.0f; 

     for (int j = 0; j < cSamples; j++) 
     { 
      rms += pData[j] * pData[j]; 

     } 

     if (cSamples > 0) 
     { 
      rms = sqrtf(rms/cSamples); 
     } 

     if (0 == i) 
     { 
      leftVolume = rms; 
     } 

     if (1 == i || (0 == i && 1 == bufferListInOut->mNumberBuffers)) 
     { 
      rightVolume = rms; 
     } 
    } 

    NSLog(@"Left/Right Volume: %f/%f", leftVolume, rightVolume); 
} 

Ale dla celów tej aplikacji, chcę go po prostu zmierzyć RMS („intensywność”) z zakresu 0-80Hz (jako przykład). Dlatego potrzebuję filtra dolnoprzepustowego.

Byłem Googlingiem od dłuższego czasu, ale moim problemem jest to, że nie mogę znaleźć wyraźnego postu, samouczka lub rozwiązania, które jest oczywiste. Prawie każdy problem, który brzmi jak mój, ma pod spodem kawałek kodu z bzdurą lub brakiem komentarzy, więc nie wiem, co tam robią wszystkie magiczne liczby i co one oznaczają ..

Czy ktoś mógłby popchnąć mnie we właściwym kierunku? Zauważ, że w moim przypadku I do chcę zrozumieć kod, a nie tylko uciekać z działającą próbką.

Dzięki

Odpowiedz

16

Jeśli można po prostu uciekł z przykładu roboczego, byłbyś szczęśliwy. :-)

Przetwarzanie sygnału to skomplikowany i głęboki obszar. Jest to skomplikowane, gdy robisz to teoretycznie, a także jest skomplikowane, gdy chcesz to zrobić praktycznie.

Chcesz mieć filtr dolnoprzepustowy. Istnieje wiele opcji z różnymi zaletami i wadami.

najbardziej podstawowych pojęć potrzebnych do czynienia, gdy chcemy zrozumieć, co się dzieje: domeny i Time Domain

przenoszenia: domeny częstotliwości jest, gdy mówimy o przedziałach częstotliwości jak 0..80Hz dla przykład. Domena czasu to normalny czas lub na przykład poszczególne wartości próbek, które posiadasz w buforze do pobierania próbek. Powyższy kod oblicza RMS w dziedzinie czasu.

Zasada podstawowa: domena częstotliwości i dziedzina czasu są całkowicie równoważne.

Można wykonać wiele operacji w obu domenach z tym samym wynikiem. Zawsze możesz przełączać się między domeną częstotliwości a domeną czasu. Ponieważ niektóre operacje są trywialne w określonej domenie, często warto najpierw przejść do pożądanej domeny, wykonać trywialną operację, a następnie przełączyć się z powrotem do oryginalnej domeny (jeśli to konieczne).

Przełączanie między domeną częstotliwości i czasu odbywa się za pomocą FT (Fourier Transformation). Programowo często wykorzystuje się specjalny przypadek buforów, które zawierają potęgę dwóch próbek i algorytm().

Inną interesującą właściwością jest twierdzenie o splotach: FT tłumaczy pomnożenie funkcji w jednej domenie i splot funkcji w innej domenie.

Co to ma wspólnego z filtrem dolnoprzepustowym?

Sugerowany filtr dolnoprzepustowy 0-80Hz, jest prostokątną funkcją w dziedzinie częstotliwości. Chcesz pomnożyć to do swojego wejścia w dziedzinie częstotliwości. Oznacza to zezwolenie na wszystkie części o częstotliwości poniżej 80 Hz i ustawienie wszystkich pozostałych na zero.

Teraz możesz zrobić to wszystko w dziedzinie częstotliwości, co byłoby łatwe, ale ze względów wydajnościowych chcesz to zrobić w dziedzinie czasu, aby uniknąć FFT w przód iw tył. (W twoim przypadku po prostu chcesz mieć energię, którą możesz obliczyć w dziedzinie częstotliwości w taki sam sposób, jak robisz to teraz (suma kwadratów).)

Aby wykonać filtr dolnoprzepustowy w dziedzinie czasu , zamiast FT-multiply-FT, możesz także splatać z FT (funkcja prostokątna). FT (funkcja prostokątna) to idealny filtr dolnoprzepustowy: funkcja sinc().

sinc(x) := sin(pi*x)/pi*x 

Ten sinc (x) jest odpowiedź impulsowa swojego prostokątnego FUNKCJI . Ta konkretna odpowiedź impulsowa jest nieskończona, co jest niepraktyczne. Oznaczałoby to, że musisz obliczyć splot wejściowy z nieskończoną liczbą wartości.

Potrzebny jest filtr o skończonej odpowiedzi impulsu : FIR. Spowoduje to błędy w twoim filtrze, konkretnie, że nie zobaczysz wszystkich częstotliwości o tej samej wadze i że zobaczysz również częstotliwości powyżej 80 Hz w twojej energii.

Ten kompromis jest nieunikniony.

BTW: Kiedy stosujesz podejście FFT, w którym możesz zastosować idealną prostokątną funkcję bez żadnego błędu, będziesz również cierpiał z powodu tego błędu pośrednio podczas wyświetlania okna sygnału wejściowego przed wykonaniem FFT. (Okienkowanie oznacza wycinanie elementów (okien) danych wejściowych w celu włączenia FFT.) Będzie to miało te same negatywne skutki dla wyjścia i będzie wymagało takich samych kompromisów jak funkcja filtrowania i wynik.

Prawdopodobnie potrzebujesz filtra FIR jako filtra dolnoprzepustowego. I dziwne liczby, które widzisz w kodzie od innych, najprawdopodobniej będą współczynnikami takiego filtru FIR.

Problem polega na tym, że nie ma "optymalnego" kompromisu, ponieważ kompromis w dużym stopniu zależy od tego, jak zdefiniujesz "błąd" w filtrze. Niektórzy ludzie muszą w jakikolwiek sposób unikać częstotliwości powyżej 82 Hz (w twoim przykładzie) i dlatego potrzebują bardzo stromej krawędzi filtra. Zwykle powoduje to duże artefakty w pobliżu granicy 80 Hz, którą należy wtedy zaakceptować. Inni ludzie mają się dobrze, a część energii pochodzi z częstotliwości do 120 Hz i pozostaje poniżej 10% powyżej 120 Hz, aby zredukować artefakty w pobliżu granicy 80 Hz (bardziej miękki filtr dolnoprzepustowy).

Cały temat jest bardzo dobrze opisane tutaj: https://ccrma.stanford.edu/~jos/sasp/FIR_Digital_Filter_Design.html

Lub jeśli chcesz zacząć na samym początku: https://ccrma.stanford.edu/~jos/sasp/sasp.html

wziąć również spojrzeć na stronach Wikipedii z filtrem FIR i sinc.

Powyższe nie wystarcza do zaprojektowania i wdrożenia własnego filtra, przyznaję. Ale powinno dać ci wystarczająco dużo tła i wskazówek, aby zacząć.

I nie zniechęcaj się czasami dziwną matematyką.

Pomysł: Jednym ze sposobów wizualizacji skuteczności filtra jest wykonanie FFT po zastosowaniu filtru i spojrzeniu na widmo. Byłoby bardzo trudno stwierdzić, czy filtr działa poprawnie, patrząc tylko na wartość RMS. Twój iPad ma więcej mocy obliczeniowej, aby to zrobić.

(Widziałem tylko, że istnieje również http://dsp.stackexchange.com do przetwarzania sygnału.)

+0

woow! Dzięki! Pomaga mi to w świetnym czasie! Chcę "nagrodzić" cię moją "nagrodą", ale powiedziałem, że mogę to zrobić za 20 godzin, więc wkrótce zobaczysz, że nadejdzie Twoja droga :) .. Dzięki za całą pomoc, w ten sposób powinienem być w stanie stworzyć coś :) –

+0

Imponująca, na pewno odpowiedź warta nagrody! –

+0

Dodałem kolejne 50 do tej odpowiedzi, gdybym mógł, to jest niesamowite! –