program do symulacji obróbki audio ?

Jul 05, 2013 28 Replies

Potrzebuję zrobić następującą rzecz :



Mam plik audio (taki tam sobie sygnał szumowy raczej, ale zróżnicowany w czasie (modulowany AM powiedzmy) , o niewielkim paśmie - mniej więcej



100Hz - 2kHz .

I chciałbym zrobić symulację uśredniania tego sygnału, znaczy właściwie poszczególnych próbek;



bierzemy kolejno 3 sample, uśredniamy - i dajemy jako wynik. i tak dalej.



Przy czym , żeby to działało kołowo , tj;


  1. out = (s1 + s2 + s3 ) /3
  2. out = (s2 + s3 + s4 ) /3
  3. out = (s3 + s4 + s5 ) /3
  4. out = (s4 + s5 + s6 ) /3

itp.



I oczywiście potrzebuję to zrobić dla kilku różnych wartości ilości próbek do uśredniania (2, 5, 10, itp).



Kiedyś robiłem symulacje przetwarzania pliku audio w jakiejś wersji SPICE, no ale tam chodziło o określony układ elektroniczny (analogowy) - jak by zrealizować czysto "matematyczny" proces to nawet nie mam pomysłu. Poza tym dawno to było i już zapomniałem co i jak.



Macie pomysł, jak by to zrobić ? Może jakiś soft jest, gdzie można by przeprowadzić takie operacje matematyczne na przebiegu ?



Wejściowy plik audio to kilkadziesiąt sekund, mono 48kHz chyba.



Potrzebne mi to do celów demonstracyjnych - żeby pokazać, jak działa taka procedura (bo mam ją zaimplementowaną w pewnym urządzeniu, ale nie da się łatwo tego "wyciągnąć" w postaci liczbowej...).



Help ?


no no, ciekawe... Zaraz zobaczę co to za dziwo. Podobnież też matlab by się nadał, ale też nie znam...

W dniu 2013-07-05 19:34, sundayman pisze:

Pure Data?

a cool edit pro coś by nie poradził?

W dniu 2013-07-05 19:49, sundayman pisze:

fajne, ale mało intuicyjne :) No nic, czytam tutorial...

W dniu 2013-07-05 20:05, sundayman pisze:

Zamiast Matlaba możesz użyć Octave - to darmowy odpowiednik Matlaba. Plik wave wczytuje się jedną komendą do zmiennej - wektora. Potem na tym wektorze można operować jak na elementach tablicy w C - podobna składnia, pętle for itd, chociaż środowisko "woli" (ze względu na szybkość) operacje od razu na całych wektorach lub macierzach. W Twoim przypadku to chyba nie ma żadnego znaczenia. Narysowanie najprostszego wykresu to też jedna linijka.

Generalnie - rewelacja. Jako muzyk to stwierdzam dodatkowo :) No, ale opanowanie tego świetnego narzędzia to mi zajmie duuuużo czasu...

A ja potrzebuję szybko machnąć kilka wykresów - więc wielki dzięki, będę się tym bawić ale raczej w celach innych niż ten, o który mi teraz chodzi...

No, zaraz zobaczymy :)

W dniu 2013-07-05 20:29, sundayman pisze:

na próbę: data = [1:1:12] n=3; b = ones(n,1)./n; y = filter(b,1,data)

przetwarzanie wav: [data,fs] = wavread("sample.wav"); n=3; b = ones(n,1)./n; y = filter(b,1,data); wavwrite(y,"wynik.wav");

gdzie n to liczba uśrednianych próbek. Prawidłowe (dla Ciebie) wartości wyjściowe zaczynają się od n-tej próbki, bo tu akurat pasował mi filtr FIR o n współczynnikach, każdy równy 1/n, a filtr ten jest przyczynowy (tzn bieżąca próbka /wyjściowa/ nie ma wiedzy o przyszłości).

Może być? O to chodziło? Wektor można też uciąć o te kilka próbek...

Średnik na końcu linijki powoduje, że nie wyświetla się w konsoli zawartość zmiennej (wektora, macierzy). Wszystkie linijki zapisz do pliku z rozszerzeniem .m, a następnie w konsoli Octave przejdź do katalogu (komenda cd) i wpisz nazwę tego pliku - skryptu. Nie próbowałem z plikami wav, ale błędu być nie powinno. W razie czego

formatting link
- help w html i pdf.

W dniu 2013-07-05 20:56, Michał Lankosz pisze:

No tak, nie doczytałem, że to ma być symulacja, czyli krok po kroku... Też da się zrobić, tylko wymaga ze 3 razy tyle linijek. Ma być na obrazku, czy same liczby? To teraz.. kto pierwszy?

W dniu 2013-07-05 21:01, Michał Lankosz pisze:

chodzi o obrazek - wygląd przebiegu przed i po uśrednieniem

no patrz, nie wiedziałem, że to ma taką mądrą nazwę :)

Dnia 2013-07-05 19:34, Użytkownik sundayman napisał:

  1. GNU R z jednym z kilku pakietów do czytania/pisania WAV
  2. MATLAB z Signal Processing Toolbox
  3. Może Scilab?
  4. Goły język C z libsndfile

W zasadzie operacja, o której mówisz, jest tożsama z filtrem Savitzky'ego i Golaya o rzędzie równym 1 i długości równej 3 lub więcej. R i Matlab udostępniają do tego gotowe funkcje.

Luke

znaczy oczywiście, mając wygenerowany przetworzony plik audio, to o obrazek nietrudno :)

Ale widzę, że bez pomocy, to niestety nie dam se rady :)

W dniu 05.07.2013 19:34, sundayman pisze:

formatting link

Sam niedawno robiłem coś podobnego. Liczyłem RMS sygnału audio.

Sama przyjemność, jest mnóstwo przykładów i bardzo dobry help.

Pozdrawiam,

Skrypt Octave, krok po kroku:

%[data,fs] = wavread("sample.wav"); data = [1:1:12] len = length(data); n=3; y = []; for i=1:len-3 mean = sum(data(i:i+n-1))./n y = [y, mean] t = [1:length(y)]; plot(t,data(1:i),"*b", t,y,"or") pause endfor

Znak % zamienia linię na komentarz

Jeśli chcesz rysować od razu całość np. tak:

formatting link
to tu masz kod:

%[data,fs] = wavread("sample.wav"); data = [1,2,3,4,4,4,8,7,2,3,4,3,3,3,1]; len = length(data); n=3; b = ones(n,1)./n; y = filter(b,1,data); t = [1:length(y)]; plot(t,data,"b*-", t,y,"ro-") %stem(t,[data', y']);

Odkomentuj pierwszą linię i zakomentuj drugą aby pracować na danych z wav. stem rysuje próbki, może bardziej przypadnie Ci do gustu, bo to w końcu jest sygnał spróbkowany, nie ciągły. Usuwając "-" z funkcji plot pozbędziesz się linii łączących. Oczywiście za długi ten sygnał nie może być, bo wykres stanie się nieczytelny. Można wybrać z wektora jakiś interesujący krótszy zakres. Częściowo pomoże narzędzie lupa. Na wykresie możesz wprowadzać oznaczenia osi, danych, tytuł, siatkę, kolory.

kod wklejasz do pliku tekstowego np sundy.m i wywołujesz wpisując w linii komend Octave: sundy.

no bardzo koledze dziękuję, zaraz spróbuję to użyć, tylko mam obawę, czy to się da zastosować do pliku audio, który ma np 10 sekund ?

No bo właśnie o to chodzi - o efekt "globalny", że tak to powiem. Cała ta procedura istotnie zmienia "obwiednię" takiego sygnału (uśrednia ją bardzo przyjemnie właśnie), no i to chcę pokazać, ale na całym sygnale, a ten ma około 10 sekund...

Ok, próbuję...

W dniu 2013-07-05 23:57, Michał Lankosz pisze:

No żesz kuśwa - rewelka ! Sprawdziłem na pierwszym skrypcie, znaczy :

[data,fs] = wavread("audio.wav"); n=30; b = ones(n,1)./n; y = filter(b,1,data); wavwrite(y,"wynik.wav");

_____________________________________________________________________

to jest właśnie to, o co chodzi ! Znaczy prawie... :) Ale o tym zaraz. Natomiast - generalnie działa super. Zapodałem sobie pliczek, octave go przerobiło, i wynikowy pliczek mogę sobie już odsłuchać, oglądać itp.

Natomiast muszę jeszcze poprosić o dalszą pomoc :) Bo trochę uprościłem wstępny opis, licząc, że potem sam sobie dam z tym radę. No ale jak widać nie bardzo...

Więc - faktycznie cały proces obróbki wygląda tak ;

Najpierw sygnał audio jest prostowany (analogowo) w dwupołówkowym prostowniku (na OPAMPie).

Następnie - sygnał trafia do przetwornika A/D, gdzie jest próbkowany z częstotliwością 1kHz, a następnie ;

Z każdych kolejnych 10-ciu próbek (1-10, 11-20, 21-30, czyli nie "w kółko", jak podczas uśredniania, tylko zwyczajnie, po kolei każde 10 ) wybierana jest największa próbka.

I dopiero te dane podlegają opisanemu już uśrednieniu.

Efekt samplowania w przetworniku A/D można pominąć , bo to chyba można z przybliżeniem zrobić odpowiednio "resamplując" oryginalny plik audio.

Czyli potrzebne jest ostatecznie :

  1. prostowanie sygnału
  2. wybór największej próbki z kolejnych 10-ciu
  3. uśrednianie wg. wcześniejszej procedury

Da się tak zrobić ??

Żeby nie było, że nie próbuję, ściągnąłem helpa do octave, i popróbuję gdzieś tak do 5 rano :)

Tak czy owak będę musiał się tego nauczyć (choć pewnie zajmie to trochę czasu), bo to bardzo przydatne narzędzie - często muszę przetwarzać sygnały w takie dziwne sposoby, i ten soft jest jak znalazł. PureData też zresztą.

Ech, żeby tak można jak w "matrixie" załadować sobie w 10 sekund umiejętność obsługi :)

Ale wiedziałeś i żartujesz, czy nie wiedziałeś? Bo Savitzky-Golay to jest filtr, który uśrednia próbkę przez dopasowanie wielomianu do kawałka sygnału. Jeśli wielomianem jest prosta, to jest to równoznaczne (poza krańcami sygnału) z uśrednianiem.

A jako że do R i Matlaba masz funkcje gotowe do tego filtru, to np.

Attaching package: ‘signal’

The following object(s) are masked from ‘package:stats’:

filter, poly

Na wykresie masz sygnał losowy na czarno i uśredniony na czerwono :)

Luke

W dniu 2013-07-06 02:08, sundayman pisze:

[...]

Da się, nie ma problemu. Może z dalszą pomocą w postaci kolejnych wersji programu przejdę na priv. Tylko nie teraz Na szybko kilka wskazówek, może sobie sam poradzisz: prostowanie sygnału: data1 = abs(data); największa próbka z 10-ciu kolejnych (pętla for, może da się ją ominąć?): data2 = max(data1(i:i+10)); liczby rozdzielone dwukropkiem oznaczają przedział tylko że trzeba w pętli ten wektor sklejać, tzn za każdym obiegiem pętli doklejać kolejną wartość, coś w rodzaju: data3 = []; for i=1:10:data_length % i inkementuje się co 10! data2 = max(data1(i:i+10)); data3 = [data3, data2]; endfor no i teraz już ten filter.

Dla sprawdzenia możesz w każdym miejscu wpisać plot(data3) na przykład i zobaczyć dany wykres. Dla dużej liczby próbek na wykresie można zrezygnować z kropek danych, zostawić tylko linie plot(t,y,"g-"); t-wektor czasu, a właściwie to numer próbki, y dane, g to kolor, - to rysowanie linią. "g:" narysuje Ci kropkowany wykres, a "g--" linią przerywaną.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required