Odtwarzanie muzyki i dźwięków

sf::Sounds vs sf::Music


W SFML istnieją dwie klasy do odtwarzania audio: sf::Music oraz sf::Sound. Nie róźnią się one zbytnio w tym co oferują, ale bardziej sposobem w jaki działają.

sf::Sound jest lżejszym obiektem, który do odtwarzania audio potrzebuje sf::SoundBuffer. Ta klasa jest odtwarzana w całości w pamięci i powinna być używana do odtwarzania krótkich utworów audio (czyli dźwięków), czyli np. do odgłosów strzałów, chodzenia itp.

sf::Music nie jest od razu wczytywana w całości w pamięci, jest wczytywana w „locie” tzn. w trakcie działania programu w miarę potrzeb. Jest obiektem cięższym oraz może odtwarzać dłuższe utwory, które trwają dużo dłużej niż krótkie dźwięki.

 

Wczytywanie i odtwarzanie dźwięków


Tak jak wspomniałem powyżej nie można odtworzyć dźwięków bezpośrednio z sf::Sound tylko trzeba je odpowiednio przygotować, czyli musimy je na początku wczytać przez sf::SoundBuffer.

Oczywiście można także do wczytania skorzystać z loadFromMemory, czy też własnego strumienia danych (loadFromMemory). Pełna lista wspieranych rozszerzeń plików audio jest dostępna w dokumentacji API.

Można także wczytać dźwięk z tzw. sample’i, jednak tego tutaj nie pokażę (zapraszam do oryginalnego poradnika).

Aby odtworzyć audio należy należy użyć klasy Sound.

Co jest fajnego to fakt, że możesz przypisać do jednego bufora wiele dźwięków i odtworzyć je jednocześnie. Co jest ważne dźwięki oraz muzyka są odtwarzane w osobnym wątku, co oznacza że po uruchomieniu play możesz robić co chcesz (nie licząc usunięcia muzyki).

 

Odtwarzanie muzyki


W przeciwieństwie do dźwięków sf::Music nie potrzebuje klasy pomocniczej do odtworzenia audio, tzn otwieranie pliku i jego odtworzenie jest robione przez tą jedną klasę.

Nie bez powodu funkcja nazywa się openFromFile, a nie loadFromFile, jest to dlatego że plik jest wczytywany na bieżąco, a nie kopiowany w całości do pamięci. Można także użyć: openFromMemory oraz openFromStream.

 

Co jeszcze można robić?


Poniżej pokazane funkcje wyglądają tak samo dla Sound jak i Music.

  • play uruchamia lub kontynuuje odtwarzanie audio
  • pause wstrzymuje odtwarzanie muzyki
  • stop zatrzymuje odtwarzanie dźwięku oraz przewija go
  • setPlayingOffset zmienia obecnie odtwarzaną pozycję

getStatus zwraca nam obecny status, czyli mówi nam czy audio jest w trakcie odtwarzania, spauzowane itp. Muzyka oraz dźwięki posiadają kilka artrybutów które można zmieniać w dowolnej chwili:

Można ustawić pitch, które wpływa na ton dźwięku a co za tym idzie na prędkość jego odtwarzania. Ustawiamy tutaj faktor, który gdy jest > 1 to sprawia, że dźwięk jest niższy, < 1 wyższy, == 1 normalny.

Można ustawić także volume, czyli głośność dźwięku w przedziale [0,100].

loop decyduje o tym czy utwór ma być zapętlany, czyli odtwarzany w nieskończoność.

Jest dostępnych także więcej atrybutów, jednak o nich porozmawiamy w poradniku o dźwiękach 3D.

 

Najczęściej spotykane błędy


Zniszczenie bufora

Jest wtedy gdy deklarujesz go w sposób podobny jak poniżej, pamiętaj że musi on być cały czas dostępny w pamięci programu gdy go używasz.

 

Za dużo dźwięków

SFML posiada limit ilości dźwięków, czyli 256, jeżeli chcesz używać ich więcej to musisz pozbyć się z pamięci tych których nie używasz i wczytać jedynie te których potrzebujesz.

 

Usunięcie źródła muzyki z pamięci

Pamiętaj, że podczas odtwarzania muzyki plik cały czas musi być dostępny. Zwykle w przypadku gdy jest na dysku nie ma z tym problemu, al może się zdarzyć, że otworzysz go np  z pamięci, wtedy łatwo przez przypadek go usunąć.

 

sf::Music nie można kopiować

Czyli nie można zrobić czegoś takiego:

Oryginalny artykuł

 


  • Nevea

    Fantastyczny blog! Z niecierpliwością czekam na poradnik o obsłudze sieci.

    • Dzięki, poradnik o sieciach pojawi się dopiero po weekendzie 🙂

  • Arkadiusz Kozioł

    Ale ten limit dźwięków dotyczy tylko pojedynczego bufora i typu Sound, czy niezależnie jak wiele typów Sound i buforów utworze, to i tak maksymalnie zmieści się ich łącznie tylko 256?

    • Jest to maximum absolutne dotyczące całej aplikacji, a nie pojedynczego buforu.

  • Arkadiusz Kozioł

    to jakoś niewiele. Jakby ktoś chciał tworzyć potężny projekt i zrobić sobie własną klasę Audio która by tym wszystkim zarządzała to niestety chyba ciężko będzie usunąć pojedynczy dźwięk z pamięci. Przynajmniej mi się to nigdy nie udawało, bo zawsze wysypywała się cała aplikacja 🙂

    • Raczej sporo, większość gier nie zużywa więcej niż 64 kanały jednocześnie.