Efekt Echa

0

Witam mam taki problem z wprowadzeniem efektu echa na ścieżkę dźwiękową.

Sygnał jest postaci tablic bajtów, po 2 na próbkę. Konwertuje do tablicy intów po czym:

for(int i=przesuniecie;i<Dane.Length;i++)
         Dane[i] += (Dane[i-przesuniecie]*0.1);

i nakładają się jakieś traszki zamiast echa.
Jak nałożyć to echo?
Z góry dzięki za odpowiedź.

0
  1. int nie ma 2 bajtów tylko 4 (w większości kompilatorów). int to po prostu najbardziej optymalny typ całkowity.
  2. jaki masz format sampli? Bardzo możliwe, że zero dźwięku nie wypada w zerze tylko dla wartości 2^15, w takim wypadku dodawanie echa będzie wyglądało troszkę inaczej.
  3. echo na poziomie wyciszone o 10 decybeli to troszkę za dużo. spróbuj najpierw mnożyć przez wartość 0.5.
0

to nie jest takie proste. Myślę, że bez analizy szeregu Fouriera się nie obejdzie.
Sprawdź sobie w Audacity, co robi dodanie echa do jakiegoś prostego sygnału (sinusa). W tym programie chyba jest analizator widmowy.

0

echo na poziomie wyciszone o 10 decybeli to troszkę za dużo.

O 20dB :>

Myślę, że bez analizy szeregu Fouriera się nie obejdzie.

Może zamiast robić analizę częstotliwościową niech po prostu sprawdza czy sample nie przekraczają dopuszczalnych wartości.

0
Karolaq napisał(a)

to nie jest takie proste. Myślę, że bez analizy szeregu Fouriera się nie obejdzie.
Mam wrażenie, że chcesz jedynie zabłysnąć wiedzą. Analiza furierowska pasuje tu jak pięść do oka. On chce te echo zrobić w prawidłowy sposób.

Tak z ciekawości, niby jak chciałbyś osiągnąć echo za pomocą TF?

0
  1. Zamień format sampli na wartości ze znakiem (za radą MarkaR22).
  2. Zapisuj wynik do osobnej tablicy. Aktualnie wynikiem jest: Dane[i] = 0.1 * Dane[i - przesunięcie] + 0.01 * Dane[i - przesunięcie * 2] + 0.001 * Dane[i - przesunięcie * 3] + .... Chyba, że o to Ci chodziło.
0
MarekR22 napisał(a)
Karolaq napisał(a)

to nie jest takie proste. Myślę, że bez analizy szeregu Fouriera się nie obejdzie.
Mam wrażenie, że chcesz jedynie zabłysnąć wiedzą. Analiza furierowska pasuje tu jak pięść do oka. On chce te echo zrobić w prawidłowy sposób.

Tak z ciekawości, niby jak chciałbyś osiągnąć echo za pomocą TF?
Nie wiem jak tworzy się efekt echa ale:
Uruchomiłem Audacity, wygenerowałem sinusa, dodałem efekt echa, sprawdziłem charakterystykę widmową - nie wygląda to na zsumowane 2 sygnały. Pomyślałem, że robiąc kilka testów można dojść do jakichś prawidłowości.

samo tworzenie echa trochę trwało, więc to raczej nie jest takie proste jak sumowanie sygnałów. No chyba, że Audacity wykorzystuje jakieś super mega wypasione echo...

0

samo tworzenie echa trochę trwało, więc to raczej nie jest takie proste jak sumowanie sygnałów.

Raczej jest ;) Zwykłe echo jest proste w implementacji, w przeciwieństwie do pogłosu.

0
Karolaq napisał(a)

Uruchomiłem Audacity, wygenerowałem sinusa, dodałem efekt echa, sprawdziłem charakterystykę widmową - nie wygląda to na zsumowane 2 sygnały. Pomyślałem, że robiąc kilka testów można dojść do jakichś prawidłowości.
Ta wypowiedź świadczy, że nie rozumiesz na czym polega echo.
Postawię ci 10 zgrzewek piwa, jeśli na przebiegu sinusoidalnym zrobisz zwykłe echo, które można usłyszeć.
Żeby było echo, dźwięk musi mieć początek i koniec lub przynajmniej charakterystyczne fragmenty czasowe. Nie może być to jeden ciągły dźwięk.
Po co się wymądrzasz skoro po prostu na ślepo walisz głową w ścianę?

@up (0x666) popatrz do wiki co to jest pogłos [glowa]

@moderator: warto by było skasować ostatnie 7 wypowiedzi (łącznie z tą +poniższą), bo zanosi się na flame'a.

0
MarekR22 napisał(a)

@up (0x666) popatrz do wiki co to jest pogłos [glowa]

No i? :>

0

jaka jest różnica w implementacji pomiędzy pogłosem a echem? ŻADNA jedynie parametr(y) opóźnienia jest inny.

0

Czyżby? No to zasymuluj (pojedynczym) echem pogłos typu hall lub church. Dźwiękiem wejściowym niech będzie coś krótkiego, np. werbel. Jak ci się uda to zrobić, przyznam ci rację ;)

0

a co nie ma bardziej skomplikowanych ech? Sam piszesz "pojedynczym echem" czyli już dostrzegasz identyczność. Nie będę tu robił wykładu z fizyki, ale zapewniam cię, że to samo i jedyna różnica to skala czasowa (wielkość pomieszczenia), no jeszcze współczynnik tłumienia jest inny.

0

już dostrzegasz identyczność.

Nie identyczność, tylko pewne cechy wspólne. I nie "już", bo nigdzie nie twierdziłem, że echo i pogłos to dwa zupełnie różne zjawiska. Mowa o implementacji, i tu zapewniam cię, że zaimplementowanie dobrze brzmiącego pogłosu nie jest takie trywialne* jak w przypadku echa, nawet tego "bardziej skomplikowanego". Więc się pytam, co jest nieprawdą w tym co napisałem?


  • pomijając pogłosy konwolucyjne, bo te w najprostszej formie są stosunkowo proste w implementacji.
0

Powinno być raczej tak:

for(int i=przesuniecie;i<Dane.Length;i++)
         Dane[i] += (Dane[i] *0.9+Dane[i-przesuniecie]*0.1);

A tak potza tym to jak to jest że masz to w WORDach i bez problemu wstawiasz costam*0.1?

0
RFabianski napisał(a)

Powinno być raczej tak: [...]

Raczej nie ;)

Dane[i] += (Dane[i] *0.9 [...]

Jeśli Dane[i] będzie miało maksymalną wartość próbki, wtedy algorytm przekroczy (prawie) dwukrotnie dopuszczalny poziom.

0

Ok więc tak niby da się usłyszeć jakieś echo ale zauważyłem że problem pojaiwa się już przy zmianie amplitudy, nie ważne o ile czyli:

for(int i=0;i<Dane.Length;i++)
      Dane[i] *= 0.9;

Już powoduje trzaski, czy jest jakiś inny sposób na wykonanie tej operacji?

0

na samym początku zwróciłem ci uwagę na co masz uważać:

MarekR22 napisał(a)
  1. int nie ma 2 bajtów tylko 4 (w większości kompilatorów). int to po prostu najbardziej optymalny typ całkowity.
  2. jaki masz format sampli? Bardzo możliwe, że zero dźwięku nie wypada w zerze tylko dla wartości 2^15, w takim wypadku dodawanie echa będzie wyglądało troszkę inaczej.

przez to, że pomieszałeś coś w tym formacie sampli, to mnożenie przynosi ci dziwne efekty. stawiam na to, że powinieneś tego int'a zamienić na short int lub coś podobnego

0
MarekR22 napisał(a)
  1. int nie ma 2 bajtów tylko 4 (w większości kompilatorów). int to po prostu najbardziej optymalny typ całkowity.

Tutaj nie ma różnicy bo i tak zamieniam go z powrotem na tablice po 2 bajty a zakres nie zostaje przekroczony

MarekR22 napisał(a)
  1. jaki masz format sampli? Bardzo możliwe, że zero dźwięku nie wypada w zerze tylko dla wartości 2^15, w takim wypadku dodawanie echa będzie wyglądało troszkę inaczej.

Format zwykły WAV.

0

"Zwykły WAV" to format pliku, który może zawierać sample w najróżniejszych formatach, włącznie z mp3 i innymi metodami kompresji. Z tego co napisałeś wynika, że sample masz 16 bitowe, ale czy na pewno takie są? Podałeś za mało danych, żeby można było coś sensownego napisać. Problem na pewno leży poza pętlą.

Więcej kodu!

0

Bez wątpienia schrzaniłeś, gdzieś tą konwersję do int! Zresztą jak masz dźwięk 16 bitowy to konwersja do 32 bitów nic ci nie daje.
pokaż kod ja właściwie wypełniasz tą tablicę lub jak wczytujesz te sample.

0

Zwykły wav to znaczy zwykły wav czyli brak kompresji format PCM 2 kanały 16 bitów na próbkę 44100 próbek na sekundę czyli zwykły wav :). na pewno nic nie spaprałem z konwersją. Bez tej pętli po konwersji działa ok poza tym przeliczałem sobie kalkulatorem nawet ale ok niech będzie:
Konwersja do intów;

przesuniecie_w_dol = (int)(Math.Pow(2, wielkosc_probki*8)/2);

            MemoryStream S = new MemoryStream(dane);
            //
            byte[] buffer = new byte[4];
            for (int i = 0; i < dlugosc; i++)
            {
                S.Read(buffer, 0, wielkosc_probki);
                this.dane[i] = BitConverter.ToInt32(buffer, 0) -przesuniecie_w_dol;
            }

Dekonwersja:

for (int i = 0; i < dane.Length; i++)
            {
                buffer = BitConverter.GetBytes(dane[i]+przesuniecie_w_dol);
                S.Write(buffer, 0, wielkosc_probki);
            }
            return S.ToArray();

wielkosc_probki jest sczytana bezpośrednio z pliku wav i w tym przypadku wynosi 16 bitów. Ale zależy mi na uniwersalności rozwiązania dla innych wielkości z tad int.

0

źle do tego podchodzisz.

  1. przesuniecie_w_dol = 1 << (wielkosc_probki*8-1);
  2. byte[] buffer = new byte[wielkosc_probki];
  3. tam powinno być chyba ToUInt32 a nie ToInt32!
0
MarekR22 napisał(a)
  1. przesuniecie_w_dol = 1 << (wielkosc_probki*8-1);

Wynik jest taki sam.

MarekR22 napisał(a)
  1. byte[] buffer = new byte[wielkosc_probki];

tablica ma byc 4 bajtowa bo zamieniam na int32 czyli 4 bajty z tym ze w tym wypadku 2 ostatnie są zerami.

MarekR22 napisał(a)
  1. tam powinno być chyba ToUInt32 a nie ToInt32!

Jak do uinta niby miałbym zapisać liczby ujemne??

0

Jak możesz, udostępnij jakąś krótką próbkę ze zniekształceniami.

1 użytkowników online, w tym zalogowanych: 0, gości: 1