program do symulacji obróbki audio ?

Jul 05, 2013 28 Replies

i:i+10 to też pętla ;) Ale ukryta - taki zabieg nazywamy w octave/matlabie wektoryzacją zagadnienia.

Modyfikacje Twojego rozwiązania:

1) Polecenia "data3 = []" i "data3 = [data3, data2]" to wygodny zapis dla nieznanej długości data3, ale kosztują: w każym obiegu pętli wykonujesz dodatkowo niepotrzebne operacje: -- utwórz nową tablicę data3 o długości length(data3)+1 -- skopiuj starą do nowej -- skasuj starą Remedium: prealokacja tablicy

L=floor(length(data1)/10); data3=zeros(1,L); for i=1:L data3[i]= max(data1((i-1)*10+(1:10))) endfor

2) Na ogół 10<L, więc lepiej zmienić kolejność jawnej i niejawnej pętli, jawne (czyli niezwektoryzowane) wykonują się wolniej

Remedium poniżej (przy założeniu, że data1 jest wektorem kolumnowym);

ii=1:10:length(data1); data3=data1(ii).'; for i=1:9 data3=max([ data3; data1(i+ii).' ]); endfor

3) Obie pętle można w tym zagadnienu zwektoryzować, ale tu opłacalność pewnie żadna, a czytelność kodu spada:

l=length(data1); i=ones(10,l/10); i(1,:)=1:10:l; i=cumsum(i); data3=max(data1(i)); clear i; ;)

W dniu 2013-07-06 09:13, Michał Lankosz pisze:

fantastycznie, spróbuję toto poskładać. Tylko najpierw niestety muszę odwalić pańszczyznę...

WIFE> CONFIG SUNDAYMAN(VACUUM CLEANER, FAST) WIFE> CALL CLEANING(ALL_ROOMS) WIFE> SETUP SPEED=ULTRAHIGH WIFE> SOUND=OFF ' SILENCE MODE/MORDA_W_KUBEŁ itp...

W dniu 2013-07-06 10:02, Miroslaw Kwasniak pisze:

Wszystko racja lub zapewne racja. Wyszedłem z wprawy, do tego dochodzą naleciałości z C. Myślę, że dla sundymana moje przykłady mogą być bardziej przejrzyste, chociaż zdaję sobie sprawę z kiepskości tej implementacji. Najmocniejszą stroną Matlab/Octave są operacje na macierzach, dlatego na wszelkie obliczenia trzeba odpowiednio popatrzeć... jak w Matrixie ;) Nie jest to bardzo trudne, wymaga tylko pewnej wprawy.

Zrobiłem tak ;

data = [2,6,3,8,4,6,15,20,40,20,25,98,17,34,5,23,5,3,35,44,23,17,19,16,2,3,8,4,7,4]; len = length(data);

data1 = abs(data) data3 = [];

a=3; % ilość próbek do wartości max

for i=1:a:length(data1) data2 = max(data1(i:i+(a-1))); data3 = [data3, data2]; endfor

% uśrednianie

n=2; % ilość próbek uśredniania b = ones(n,1)./n; y = filter(b,1,data3);

t = [1:length(data1)]; %plot(t,data1,"b*-")

t2 = [1:length(data3)]; plot(t,data1,"b*-", t2*a,y, "r*-")

____________________________________________

na razie na danych ręcznie wpisanych, żeby sprawdzić. No i chyba - kuśwa działa ! :)) Jutro spróbuję na wav.

Nie, .' jest transpozycją, a sam apostrof to

formatting link
ężenie_hermitowskie_macierzy Co dla macierzy rzewywistych niczym się nie różni ;)

Tak jest właśnie - jest to dla mnie ciut bardziej zrozumiałe :) Jak napisałem, na ręcznie wprowadzonych danych generalnie jest ok, natomiast przy próbie wygenerowania WAV już jest gorzej.

Mam tak : [data,fs] = wavread("audio.wav");

%data = [2,6,3,8,4,6,15,20,40,20,25,98,17,34,5,23,5,3,35,44,23,17,19,16,2,3,8,4,7,4]; len = length(data);

data1 = abs(data) data3 = [];

a=10; % ilość próbek do wartości max

for i=1:a:length(data1)-a data2 = max(data1(i:i+(a-1))); data3 = [data3, data2]; endfor

% uśrednianie n=2; % ilość próbek uśredniania b = ones(n,1)./n; y = filter(b,1,data3);

wavwrite(y,"wynik.wav");

%t = [1:length(data1)]; %plot(t,data1,"b*-") %t2 = [1:length(data3)]; %plot(t,data1,"b*-", t2*a,y, "r*-") % to odblokować

%stem(t,[data', y']);

***************************

i teraz, dla a=10 jak powyżej, wywala mi błąd, że

"Y has more than 32767 columns, too many for WAV-file"

tego akurat nie rozumiem. Znaczy chodzi o to, że wartość wykracza poza dopuszczalne 16 bitów ? Ale jakim cudem, bo przecież nie powinno być więcej niż jest maksymalnie w audio.wav ?

Jak zwiększę a=100 to wtedy niby generwuje ten WAV, ale nie daje się on otworzyć. Wieczorem spróbuję powalczyć, bo w sumie to chciałbym zrobić tak, żeby niezależnie od wyboru "a" i "n" WAV wygenerowany był takiej samej długości jak źródłowy.

Czyli trzeba by powielać dane wyjściowe i posklejać je w jeden wav. Próbki będą znaczy się powtarzać, ale dzięki temu będzie można ładnie porównać obie "fale" i posłuchać także..

W dniu 2013-07-07 15:40, sundayman pisze:

Kolejne próbki mają być w kolejnych wierszach, dwie kolumny to sygnał stereo. Czyli wpisz: wavwrite(y.',"wynik.wav");

Poczytaj o wavwrite, bo domyślnie wstawia w nagłówku częstotliwość próbkowania 8kHz, a można wymusić inną.

Ostatecznie mam takie coś :

[data,fs] = wavread("audio.wav");

%data = [2,6,3,8,4,6,15,20,40,20,25,98,17,34,5,23,5,3,35,44,23,17,19,16,2,3,8,4,7,4]; len = length(data);

data1 = abs(data) data3 = [];

a=44; % ilość próbek do wartości max for i=1:a:length(data1)-a data2 = max(data1(i:i+(a-1))); data3 = [data3, data2]; endfor

% uśrednianie n=30; % ilość próbek uśredniania b = ones(n,1)./n; y = filter(b,1,data3);

% składanie WAV data4 = []; for i=1:length(y) probka = y(i:i); for j=1:a data4 = [data4,probka]; endfor endfor

wavwrite(data4.', 44100 , "wynik_n30.wav");

*************************************

No muszę powiedzieć - działa :) Nawet chyba udało mi się zrobić, żeby wynikowy wav miał tą samą długość,co wejściowy (rozciągnąłem po prostu z tym samym współczynnikiem, o który się skraca w wyniku znajdowania wartości maksymalnej).

Teraz mogę sobie testować w te i wefte na różnych parametrach - no coś pięknego. I z tego co widzę, to się nawet chyba zgadza z empirią :)

Panie Michale, jest pan wielki ! Zazdroszczę znajomości tego narzędzia - coś mi cholerycznie ciężko nad tym zapanować, ale warto się pomęczyć. Tak że - słów podziękowań brak mi po prostu :)

Oczywiście pozostałym kolegom także dziękuję bardzo.

*************************************

Na wszelki wypadek zapytam jeszcze na koniec ; jak widać zmieniłem tą linię :

data2 = max(data1(i:i+a))); * gdzie oczywiście "a" to przedział szukania maximum (zastąpiłem "10" z przykładu kolegi zmienną "a" , żeby mieć łatwiej w razie zmian wartości)

na następującą wersję :

data2 = max(data1(i:i+(a-1)));

bo wydaje mi się, że w wersji "źródłowej" robi się zakres o 1 za duży (np. dla przedziału 10 zakres byłby 10:20 zamiast wymaganego 10:19). Wygląda mi to na po prostu drobną pomyłkę kolegi, ale wolę się upewnić - czy wszak dobrze zrobiłem ?

W dniu 2013-07-08 03:29, sundayman pisze:

Ja już bardzo dużo zapomniałem. Matlab to wielkie narzędzie! Fajnie, że ma darmowy odpowiednik, a przynajmniej namiastkę.

Tak, błąd. Zawsze możesz sprawdzić na danych testowych. W linii poleceń wpisujesz nazwę zmiennej i wyświetla Ci jej wartość (skalar, wektor, macierz). Size(x) podaje rozmiar. A widzisz, gdybyś miał plik wave stereofoniczny do wavread do data1 wpisze macierz, dwie chyba kolumny kanałów. Żeby wyciągnąć jedną kolumnę piszesz: chan1 = data1(:,1) gdzie 1 wybiera pierwszą kolumnę.

Świetnie! Widzę, że dalej już sam sobie poradzisz :)

Join the Discussion

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

Didn't find your answer?

Ask the community — no account required