Dźwięki i problem z nieregularnością przy WaveOutWrite.

  • 8 Odpowiedzi
  • 968 Wyświetleń

0 użytkowników i 1 Gość przegląda ten wątek.

*

Offline Komame

  • 35
  • Płeć: Mężczyzna
  • Sprzęt: SE X1
Napisałem grę, do której próbuję dodać dźwięk, jednak podstawowa funkcja sndPlaySound mi nie wystarczy, ponieważ w grze występuje potrzeba odtwarzania kilku dźwięków jednocześnie.
Rozwiązaniem jest WaveOutOpen, WaveOutWrite itp. no i to działa, ale niestety nie do końca tak jak bym chciał. Np. podczas ruchu postaci powinien się wydobywać cyklicznie ten sam dźwięk (takie tykanie) dopóki postać jest w ruchu. Dźwięk odtwarzam zawsze przed rysowaniem klatki, tak więc jest cyklicznie (regularnie i idealnie) zawsze co 40ms. Pomimo, że klatki rysują się zawsze po tym samym czasie i jest ładna płynna grafika (napewno nie ma żadnych skoków grafiki), to dźwięk (pomimo, że jest odtwarzany przed narysowaniem klatki) jest nieregularny, tzn. są takie skoki nieregularne, tak jakby raz było to co 45ms, raz co 40ms, albo może nawet większe skoki w czasie - trudno do zmierzyć. Pozostałe dźwieki są odtwarzane od czasu do czasu przy pewnych tylko zdarzeniach, więc tam tych opóźnień nie słychać, ale jest to denerwujące przy tych dźwiękach, które powinny się regularnie w miare szybko) powtarzać.
Tak sobie pomyślałem, że może odtwarzanie dźwięków przy WaveOutWrite powinno być realizowane na osobnym wątku. Jednak wydaje mi się, że tu ma coś innego winę.
Dodam jeszcze, że testując to na różnych palmtopach te opóźnienia są różne, tzn. na niektórych jest idealnie tak jakbym chciał - czyli regulanie, a na innych jeszcze gorzej.
Ktoś wie o co tu może chodzić?

*

Offline fp

  • **
  • 113
    • http://pdaclub.pl/forum/index.php?action=search
Dźwięki i problem z nieregularnością przy WaveOutWrite.
« Odpowiedź #1 dnia: Luty 18, 2007, 19:31:28 »
nie tędy droga. waveOutWrite wpisuje sekwencje bajtów do wysłania na głośnik. aby uzyskać stały czas między dźwiękami należałoby wpisywać pusty (same zera) dźwięk pomiędzy nimi o odpowiedniej długości. najlepiej wszystko na osobnym wątku.

*

Offline Komame

  • 35
  • Płeć: Mężczyzna
  • Sprzęt: SE X1
Dźwięki i problem z nieregularnością przy WaveOutWrite.
« Odpowiedź #2 dnia: Luty 18, 2007, 21:13:49 »
Czyli na przykład mogę przez cały czas bez przerwy odtwarzać dźwięk samych zer i do tego miskować dodatkowo jakieś dodatkowe dźwięki? Czy takie rozwiązanie wystarczy? Bo nie za bardzo rozumiem określenie "pomiędzy nimi" skoro odtwarzanych jest kilka dźwięków naraz w tym samym czasie.

*

Offline fp

  • **
  • 113
    • http://pdaclub.pl/forum/index.php?action=search
Dźwięki i problem z nieregularnością przy WaveOutWrite.
« Odpowiedź #3 dnia: Luty 19, 2007, 12:26:06 »
tak właśnie masz zrobić - cały czas odtwarzać zera - do których będziesz domiksowywał swoje dźwięki. pamiętaj, że zanim zrobisz waveOutWrite, musisz się upewnić, że systemowy bufor jest gotowy (najlepiej robić to tworząc event, który się wywoła po tym zdarzeniu).

*

Offline Komame

  • 35
  • Płeć: Mężczyzna
  • Sprzęt: SE X1
Dźwięki i problem z nieregularnością przy WaveOutWrite.
« Odpowiedź #4 dnia: Luty 20, 2007, 06:44:07 »
Odtwarzanie zer w tle poprawiło sprawę o tyle, że wcześniej, gdy była cisza i prówałem odtworzyć od razu np. dwa dźwięki to one nie startowały w tym samym czasie, pomimo że dwa waveouty były wywołane praktycznie linia po linii (opóźnienie malutkie, ale słyszalne). W tej chwili to się poprawiło, ponieważ startują dokładnie w tym samym czasie, ale i tak przy powtarzających się krótkich dźwiękach występuje nadal ta nieregularność. Czy mógłym prosić o jakiś przykład ze sprawdzaniem tego bufora systemowego?

*

Offline Komame

  • 35
  • Płeć: Mężczyzna
  • Sprzęt: SE X1
Dźwięki i problem z nieregularnością przy WaveOutWrite.
« Odpowiedź #5 dnia: Luty 21, 2007, 09:49:44 »
Ze względu na to, że sample są generowane prostymi algorytmami, a nie wczytywane z pliku i są bardzo małe (największy ma 500 bajtów) to przyszedł mi do głowy jeszcze taki pomysł, aby najpierw zrobić waveOutOpen i waveOutPrepareHeader, a następnie już tylko wielokrotnie używać waveOutWrite, bez wielkorotnego wykonywania po każdym odtworzeniu dźwięu waveOutUnprepareheader i waveOutClose (to ostatnie wykonać tylko w przypadku definitywnego zakończenia - wyłączenia dźwięku lub zamknięcia aplikacji).
Niestety nawet to nie pomogło na te nieregularności. Nie wiem co może być, pewnie gdzieś jakiś niewidoczny błąd.

*

Offline fp

  • **
  • 113
    • http://pdaclub.pl/forum/index.php?action=search
Dźwięki i problem z nieregularnością przy WaveOutWrite.
« Odpowiedź #6 dnia: Luty 21, 2007, 10:00:02 »
podeślę ci na priv kawałek kodu

*

Offline Komame

  • 35
  • Płeć: Mężczyzna
  • Sprzęt: SE X1
Dźwięki i problem z nieregularnością przy WaveOutWrite.
« Odpowiedź #7 dnia: Luty 21, 2007, 12:27:02 »
Wielkie dzięki.
Jednak gdy to zobaczyłem to stwierdzam, że jeszcze raczkuję w dźwięku, albo w ogóle nie znam zasad działania waveOutWrite (albo raczej te tutoriale na www.pocketpcdn.com to źle przedstawiają). Po prostu odtwarzałem ciszę (zera) zapętlone w kółko wywołując raz waveOutWrite na początki (cisza trwała) i do tego próbowałem domiksowywać dodatkowe dźwięki poprzez wywołanie w odpowiednich momentach dodatkowych waveOutWrite, które wcześniej zostały spreparowane. A tutaj widzę szok, nawet nie rozumiem dokładnie o co tu chodzi. Posiedzę trochę nad tym i spróbuję rozpracować, ale przynam, że nie spodziewałem się, że to może być takie złożone (przynajmniej na razie mi się tak wydaje, bo nie rozumiem jeszcze tego kodu).

Mimo wszystko jeszcze raz wielkie dzięki.

*

Offline Komame

  • 35
  • Płeć: Mężczyzna
  • Sprzęt: SE X1
Dźwięki i problem z nieregularnością przy WaveOutWrite.
« Odpowiedź #8 dnia: Luty 25, 2007, 22:45:37 »
Mam jeszcze tylko jedno pytanie. Coś co pozwoli mi nieco bardziej zrozumieć mój problem i zasadę działania waveOutWrite().

Jeśli mam kilka tablic, w których zostały wygenerowane dźwieki. Aby je odtwarzyć musze dla każdej tablicy wykonać waveOutOpen() i potem waveOutPrepareHeader(). Po wykonaniu tej czynności teoretcznie pozostało mi samo odtworzenie dźwięku, czyli wykonanie waveOutWrite(). To ostatnie mogę wykonywać wielkorotnie dla raz już otwartego dźwieku, dla którego został swtorzoy nagłówek. Tak więc żadnych wielokrotnych inicjalizacji nie potrzeba. Wystarczy raz wykonać waveOutOpen() i raz waveOutPrepareHeader() dla każdego dźwięku, który będziemy odtwarzać, a potem każdy z nich można wielokrotnie odtwarzać wywołując tylko funkcję waveOutWrite().
waveOutUnprepareHeader() oraz waveOutClose() trzeba wykonać tylko raz przy zakończeniu aplikacji.
Czy to się zgadza?

Druga część pytania dotyczy tego, czy kiedy już mam otwarty i spreparowany nagłówek dla danego dźwięku, to czy wowołanie waveOutWrite() powoduje natychmiastowe odtworzenie dźwieku czy jest jakaś zwłoka zanim nastąpi odtwarzanie, której się nie da bliżej okreslić (tzn. że może być inna za każdym razem)?

Ogólnie chodzi mi o to czy jesli zrobię coś takiego (symbolicznie opisując) dla jakiegoś dźwięku:


waveOutOpen(cisza_zera);
waveOutPrepareHeader(cisza_zera);
waveOutWrite(cisza_zera); //cisza zostaje odtworzana i nigdy sie nie kończy

waveOutOpen(dźwięk);
waveOutPrepareHeader(dźwięk);
for(int k=0 ; k<100 ; k++)
{
  waveOutWrite(dźwięk); //zakładam, że dźwięki jest b. krótki, np. trwa 20ms
  Sleep(150);
}
waveOutClose(dźwięk);
waveOutUnprepareHeader(dźwięk);
waveOutClose(cisza);
waveOutUnprepareHeader(cisza);


Czy po odpaleniu takiego kodu powinienem usłyszeć 100 odtworzeń dźwieku "dźwięk" w regularnych odstępach czasu (tu ok. 150ms) czy raczej będą nieregularne?
Żadnych powtórych inicjalizacji nie ma, w tele gra już cisza, tylko cyklicznie w pętli wywoływane są waveOutWrite(dźwięk), które zawsze odpalają ten sam dźwięk sto razy.
Jak to powinno być słyszane?
Bo powiem, że u mnie jest nieregulanie.