Autor Wątek: Synchronizacja efektow z muzyka  (Przeczytany 6709 razy)

Offline slowbro

  • Użytkownik

# Styczeń 28, 2012, 17:02:57
Witam,

W produkcjach demoscenowych mozna zobaczyc ciekawe synchronizacje efektow np. blyski ekranu z muzyka:

http://www.youtube.com/watch?v=KMUugXmectc

W jaki sposob mozna wyznaczyc moment kiedy trzeba wyswietlic bialy blysk na ekranie komputera aby byl zsynchronoziowany z uderzeniem perkusji? Jakie biblioteki muzyczne oraz ich funkcje do tego celu mozna wykorzystac?

Pozdro

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Kos

  • Użytkownik
    • kos.gd

# Styczeń 28, 2012, 17:11:41
Słowo kluczowe: bpm detection. Audacity to chyba potrafi w miarę robić

Offline Karol

  • Użytkownik

# Styczeń 28, 2012, 20:29:15
Możesz jeszcze skorzystać z FFT i reagować na przekroczenie progu w pewnych zakresach, ale to czasem daje fałszywe wyniki. Z innych rzeczy to biblioteka BASS umożliwia synchronizację, jak odtwarzany utwór dojdzie do określonego czasu to wywoływany jest callback.

Offline yarpen

  • Użytkownik

# Styczeń 28, 2012, 20:42:21
Akurat to demo to byly jescze czasy mod/xm/s3m. Wtedy sie po prostu uzywalo jakiegos egzotycznego i nieobslugiwanego efektu i wstawialo go w module w miejscu gdzie mial byc blysk itd. Playery zazwyczaj mialy opcje ustawienia callbacku na dany typ efektu

Offline slowbro

  • Użytkownik

# Styczeń 28, 2012, 21:21:45
Zapoznam sie z BASS. Nie wiem czy jasno opisałem problem. Potrzebna jest mi jakas funkcja np. biblioteki BASS, ktora zwraca jakas informacje, ze w danym momencie nastapilo uderzenie perkusji i nic wiecej.

Offline Reg

  • Administrator
    • Adam Sawicki - Home Page

# Styczeń 28, 2012, 23:05:43
Nie widzę sensu w analizowaniu muzyki w czasie wykonania dema i znajdowaniu w niej beatów. Co innego kiedy piszemy grę w której można podać dowolny plik MP3, np. Audiosurf. Albo po prostu chcemy się pouczyć teorii przetwarzania dźwięku :) Ale jesli utwór który będzie odtwarzany jest z góry znany, tak jak to jest w demach scenowych i normalnych grach, można wszystko wyliczyć offline i wprowadzić do kodu albo danych programu, a nawet wypełnić te dane ręcznie.

Utwory mają raczej stałe tempo. Ile sekund (albo milisekund) trwa jeden beat to można zmierzyć nawet otwierając utwór w programie do edycji WAVE np. Audacity i zaznaczając myszką od jednego do drugiego "peaka", albo zaznaczając 10 i pokazany czas zaznaczenia dzieląc przez 10 (tak będzie dokładniej).

Ja kiedy robiłem demo, wykorzystałem pomysł (który poddał mi Krzysiek K. - pozdrawiam :)) żeby czas w aplikacji - czyli ta liczba typu float czy double - był mierzony nie w milisekundach czy w sekundach od jakiegoś czasu 0 (startu systemu czy roku 1970), tylko w beatach (!!!) i od chwili rozpoczęcia odtwarzania muzyki. Słowem - z każdym beatem utworu zmienna czas zwiększa wartość o 1.0. Potem już można opisać scenariusz dema kodując jakoś np.:

Czas od 0.0 do 4.0: Scena 1.
Czas od 4.0 do 8.0: Scena 2.
Dodatkowo w czasie od 5.9 do 6.1 jest błysk.

Offline slowbro

  • Użytkownik

# Czerwiec 15, 2016, 00:08:39
Reg: W jaki sposób określałeś, że właśnie nastąpił beat, aby zmienną zwiększyć o 1.0?

Offline laggyluk

  • Użytkownik
    • http://laggyluk.com

# Czerwiec 15, 2016, 12:19:23
napisał, mierząc czas jaki minął od początku odtwarzania muzyki. zakładając że znasz bpm utworu

Offline Reg

  • Administrator
    • Adam Sawicki - Home Page

# Czerwiec 20, 2016, 12:48:38
Zmienna zwiększa się płynnie, nie w pewnym momencie o całe 1.0. To jest tylko kwestia skalowania - mnożenia przez inną stałą, żeby była wyrażona w innych jednostkach. Tak jak systemowy GetTickCount() zwraca w milisekundach, a QueryPerformanceCounter() w jakiś "cyklach" i mnożąc przez ileśtam można to przeliczyć na sekundy, tak samo można przeliczyć na beaty muzyki mnożąc przez odpowiednią, inną wartość. Mam tu na myśli mnożenie czasu, jaki upłynął od poprzedniej klatki.

Offline slowbro

  • Użytkownik

# Wczoraj o 22:48:53
Odświeżam wątek. Jest jeszcze kwestia wyświetlania efektów z jednakowym tempem na szybszych i wolniejszych komputerach. Aby to uzyskać można w jakiś sposób wykorzystać dane muzyki: czas trwania, tempo czy lepiej oprzeć to na pomiarach czasu za pomocą GetTickCount() i wyliczać współczynnik?

Offline MDW

  • Użytkownik
    • www.encore-games.com

# Wczoraj o 23:37:17
Ja jeżeli coś takiego robię to przyjmuję założenie, że produkcja ma działać nawet z wyłączoną muzyką. Wobec tego żadne pobieranie danych z muzyki nie wchodzi w grę. Zrobiłem sobie jakiś tam timer do którego wrzucam "punkty" zawierające czas wystąpienia, klasę/metodę listenera (który zostanie wywołany gdy czas osiągnie ten punkt) i jakiś tag do dokładniejszej identyfikacji tego punktu (często ta sama metoda jest podana jako listener wielu punktów i trzeba te punkty jakoś rozróżnić). Dodatkowo tak wywołany listener w parametrze ma informację o tym jak bardzo dokładnie został wywołany. Zdarza się, że zostanie wywołany np. 35 millisekund za późno. Mając taką informację mogę w listenerze mogę wziąć tę informację pod uwagę, np. startując scenkę nie od pozycji 0 tylko 35 millisekund. To są detale ale nie zasnąłbym gdybym wiedział, że gdzieś tam się to odrobinę może rozjeżdżać (tak, to jest psychiczne:)).

Wszystko o czym tu piszę jest tylko i wyłącznie moją radosną twórczością. Żadnych bibliotek, wspomagaczy, ułatwiaczy. Bardzo proste C++ bez problemu kompilujące się pod: MorphOS, AmigaOS4, iOS, macOS, Windows, Linux, Android. Takie mam założenie. :) Chociaż to, że jest proste, nie oznacza, że zostało to szybko napisane. Wręcz przeciwnie - klepię to już 11 lat (tak, cierpliwość jest jedną z nielicznych moich mocnych stron). :D
« Ostatnia zmiana: Wczoraj o 23:49:43 wysłana przez MDW »

Offline MDW

  • Użytkownik
    • www.encore-games.com

# Wczoraj o 23:43:36
Odświeżam wątek. Jest jeszcze kwestia wyświetlania efektów z jednakowym tempem na szybszych i wolniejszych komputerach. Aby to uzyskać można w jakiś sposób wykorzystać dane muzyki: czas trwania, tempo czy lepiej oprzeć to na pomiarach czasu za pomocą GetTickCount() i wyliczać współczynnik?
Muzyka odtwarza się zawsze w tym samym tempie. Jeżeli demo będzie działało też w stałym tempie niezależne od maszyny to wszystko będzie zsynchronizowane.

Wszystko co w demie zmienia się w czasie musi być przemnożone przez czas jaki upłynął od ostatniej aktualizacji.

Zamiast:
posX += speedrób coś  w stylu:
posX += (speed * deltaTime)
Ta deltaTime to jest czas jaki upłynął od ostatniego przeliczania sceny:
deltaTime = currentTick - lastTick
Generalnie ja bym unikał "pobierania" czasu w różnych miejscach programu. Robiłbym to w jedym miejscu i wyliczoną deltę podawał dalej do całego silnika. Wtedy w jedym miejscu masz władzę nad całym czasem upływającym w produkcji. Jeżeli to jest gra to podając deltaTime==0 robisz idealną pauzę. Zatrzymuje się absolutnie wszystko, z particlami włącznie. :) Tylko trzeba być konsekwentym i wszędzie używać tej jednej obliczonej wartości deltaTime - żadnych wyjątków. :)
« Ostatnia zmiana: Wczoraj o 23:47:22 wysłana przez MDW »