Hlavní navigace

Knihovna ClanLib (27)

Petr Kavánek 15. 11. 2004

V tomto pokračování seriálu navážeme na povídání o přehrávání zvuků, které jsme začali minule. Povíme si, jak měnit různé parametry zvuku (například hlasitost nebo váhu) přímo během jeho přehrávání. Ukážeme si, jak přehrát .ogg (Vorbis) a .xm (MikMod) soubory a povíme si, jak použít zvukové filtry.

MikMod a Vorbis

Hudební soubory Vorbis nebo MikMod budeme chtít použít zejména v situacích, kdy nám půjde o ušetření místa, jelikož jej oproti wavům zabírají podstatně méně. Osobně mám zkušenost spíše s Oggy a hodně hrubým odhadem bych řekl, že je u nich komprese srovnatelná s mp3. Pokud tedy ke své hře budete chtít pouštět hodinu hudbu, rozhodně vám nedoporučuji používat formát wav.

Abychom mohli zmíněné dva zvukové formáty používat, potřebujeme pro každý z nich inicializovat příslušný modul. Náš program by pak měl, kromě inicializace nezbytných modulů jako SetupCore::init(), obsahovat:

#include <ClanLib/sound.h>

#include <ClanLib/vorbis.h>
#include <ClanLib/mikmod.h>

CL_SetupSound::init();
CL_SetupMikMod::init();
CL_SetupVorbis::init();

CL_SoundOutput output(44100);

Nyní budeme moci přehrávat Oggy a MikMody stejným způsobem, jakým jsme se v minulém dílu naučili přehrávat wavy:

CL_SoundBuffer vorbis("zvuk.ogg");
CL_SoundBuffer mikmod("mikmod.xm");

vorbis.play();
mikmod.play();

Vytvoříme tedy nejprve příslušné instance CL_SoundBuffer a přehrajeme je voláním metody play(). Použít můžeme samozřejmě i konstruktor využívající soubor zdrojů. Příslušná položka tohoto souboru reprezentující sample může mít například následující formát:

<sample
        name="vorbis"
        file="zvuk.ogg"
        format="[wav, ogg, xm...]"
        stream="[no,yes]" >

Význam jména (atribut name) a cesty k souboru (atribut file) je zřejmý. Atribut format je nepovinný a měl by sloužit jako pomoc, pokud knihovna nerozezná formát daného souboru automaticky. Atribut stream říká, zda má být samle celý nahrán do paměti (no), nebo postupně (yes) přehráván z disku (to může být u delších nahrávek nezbytné). Tento atribut je také nepoviný.

CL_SoundBuffer_Ses­sion

Jak jsem již naznačil minule, řeší třída CL_SoundBuffer_Ses­sion naše problémy v situacích, kdy potřebujeme měnit parametry přehrávaného zvuku dynamicky během přehrávání. Je to prostě tak, že přehrávaný zvuk je instancí CL_SoundBuffer_Ses­sion, nikoli instancí CL_SoundBuffer, což vysvětluje, proč změny atributů instancí CL_SounBuffer neovlivňují již hrající zvuky, tyto atributy totiž pouze říkají, jak se mají z dané instance CL_SoundBufferu vytvářet instance CL_SoundBuffer_Ses­sion.

Jak ale můžeme příslušnou CL_SoundBuffer_Ses­sion od CL_SoundBuffer získat? Minule jsem vám zatajil přesnou deklaraci metody play() třídy CL_SoundBuffer. Podívejme se na ni:

CL_SoundBuffer_Session play(bool looping = false, CL_SoundOutput *output = 0); 

Jak je vidět, je námi požadovaná instance CL_SoundBuffer_Ses­sion vrácena přímo metodou play(). Pokud bychom chtěli tuto instanci získat, aniž by to znamenalo, že se v tom okamžiku zvuk začne přehrávat, můžeme místo metody play() použít metodu:

CL_SoundBuffer_Session prepare(bool looping = false, CL_SoundOutput *output = 0); 

Máme-li nyní instanci CL_SoundBuffer_Ses­sion, můžeme volat její metody:

bool is_playing();

Odpoví, zda je tato session právě přehrávána.

void play();
void stop();

První z metod spustí přehrávání, druhá jej zastaví.

float get_volume() const;
void set_volume(float new_volume);

První metoda vrátí relativní hlasitost této session, tj. číslo mezi 0 (ztlumeno) a 1 (maximálně hlasité). Pomocí druhé můžeme hlasitost nastavit (hodnoty opět 0 až 1).

float get_pan() const;
void set_pan(float new_pan);

První metoda vrátí váhu této session jako číslo mezi –1 a 1, přičemž –1 znamená, že je zvuk přehráván pouze v levém reproduktoru a 1 pouze v pravém reproduktoru, nastavením 0 zajistíme vyvážené přehrávání.

Druhá metoda nám umožňuje váhu nastavit.

int get_length() const;

Vrátí celkovou délku přehrávaného zvuku.

int get_position() const;
float get_position_relative() const;

První metoda vrátí pozici, v níž se přehrávání nachází. Druhá metoda tuto pozici vrátí jako poměrnou (relativní) hodnotu, tj. jako číslo mazi 0 a 1, kde nula znamená, že jsme na začátku, a jedna, že jsme na konci přehrávání.

bool set_position(int new_pos);
bool set_position_relative(float new_pos);

Pomocí první z metod můžeme nastavit pozici přehrávání absolutně, pomocí druhé nastavujeme pozici relativně, tj. číslo 0 až 1, jak již bylo popsáno. Metody vracejí příznak, zda se operaci podařilo úspěšně provést.

int get_frequency() const;
bool set_frequency(int new_freq);

První z metod vrátí frekvenci, jež je použita při přehrávání, druhá metoda nám tuto frekvenci umožňuje měnit a vrací příznak, zda se změnu podařilo úspěšně provést. Frekvence v podstatě odpovídá rychlosti přehrávání.

Zvukové filtry

Někdy se můžeme dostat do situace, kdy bychom chtěli přehrávaný zvuk například plynule zesilovat. Jedna možnost je dělat to ručně pomocí nějakého časovače a metody set_volume(). To by ale nebylo zrovna příjemné, zvláště, když existuje pohodlnější alternativa, kterou je CL_FadeFilter. Jedná se o zvukový filtr, který slouží k plynulé změně hlasitosti.

Třída CL_SoundBuferr_Ses­sion obsahuje kromě výše popsaných metod ještě následující dvě metody, které nám umožní aplikovat na příslušnou session zvolený zvukový filtr:

void add_filter(CL_SoundFilter *filter, bool delete_filter = false);
void remove_filter(CL_SoundFilter *filter); 

První metoda nastaví filtr a také nastaví, zda má být tento po skončení přehrávání uvolněn. Druhá metoda umožňuje filtr vyjmout.

Filtry, které chceme takto použít, musí být potomci CL_SoundFilter. ClanLib v současnosti nabízí CL_FadeFilter, CL_EchoFilter (ozvěna) a CL_InverseEcho­Filter. Podívejme se na příklad použití prvního z nich:

CL_SoundBuffer vorbis("zvuk.ogg");

CL_SoundBuffer_Session session = vorbis.prepare();

CL_FadeFilter fade(0.0f);

session.add_filter(&fade);
session.play();

fade.fade_to_volume(0.7f, 5000);

Konstruktoru předáme jako parametr počáteční hlasitost. Metoda fade_to_volume() dostává jako první parametr hlasitost, na niž se chceme dostat, a jako druhý parametr dobu v milisekundách, během níž se tato změna má provést.

Závěr

Toť vše k přehrávání zvuků.

Ještě nejsem zcela rozhodnut o tématu příštího dílu, takže se nechte překvapit.

Našli jste v článku chybu?

16. 11. 2004 13:24

Tomas (neregistrovaný)

Akorat koukam, ze v debianu jsou standartne knihovny libclan-lua a libclan-ttf, ktery kdyz sosnu zdrojaky z clanlib.org, tak je tam nevidim - jestli to v novejsich verzich zrusili ci co, v README.update taky ani zminka ze by to presunuli nekam jinam ....

Skriptovani i TTF by se docela hodilo ...

Taky sem nikde nenasel pristup na CVS, jestli to nemaji nahodou tam v nejakou vyvojivou verzi...

A taky by se hodila nejaka vektorova grafika - idealne zobrazovani SVG, ale nic takovyho asi zat…





Podnikatel.cz: Dárky v podnikání. Jak je uplatnit v daních?

Dárky v podnikání. Jak je uplatnit v daních?

Vitalia.cz: Žloutenka v Brně: Nakaženo bylo 400 lidí

Žloutenka v Brně: Nakaženo bylo 400 lidí

Podnikatel.cz: Platební brány a EET? Stále s otazníkem

Platební brány a EET? Stále s otazníkem

Vitalia.cz: Jak koupit Mikuláše a nenaletět

Jak koupit Mikuláše a nenaletět

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

Lupa.cz: Proč firmy málo chrání data? Chovají se logicky

Proč firmy málo chrání data? Chovají se logicky

DigiZone.cz: Flix TV má set-top box s HEVC

Flix TV má set-top box s HEVC

120na80.cz: Pánové, pečujte o svoje přirození a prostatu

Pánové, pečujte o svoje přirození a prostatu

Vitalia.cz: „Připluly“ z Německa a možná obsahují jed

„Připluly“ z Německa a možná obsahují jed

Vitalia.cz: Tesco: Chudá rodina si koupí levné polské kuře

Tesco: Chudá rodina si koupí levné polské kuře

DigiZone.cz: Další dva kanály nabídnou HbbTV

Další dva kanály nabídnou HbbTV

Měšec.cz: Finančním poradcům hrozí vracení provizí

Finančním poradcům hrozí vracení provizí

120na80.cz: Rakovina oka. Jak ji poznáte?

Rakovina oka. Jak ji poznáte?

Vitalia.cz: Chtějí si léčit kvasinky. Lék je jen v Německu

Chtějí si léčit kvasinky. Lék je jen v Německu

Vitalia.cz: Jsou čajové sáčky toxické?

Jsou čajové sáčky toxické?

Podnikatel.cz: Víme první výsledky doby odezvy #EET

Víme první výsledky doby odezvy #EET

Lupa.cz: Google měl výpadek, nejel Gmail ani YouTube

Google měl výpadek, nejel Gmail ani YouTube

Měšec.cz: Zdravotní a sociální pojištění 2017: Připlatíte

Zdravotní a sociální pojištění 2017: Připlatíte

Měšec.cz: U levneELEKTRO.cz už reklamaci nevyřídíte

U levneELEKTRO.cz už reklamaci nevyřídíte

Podnikatel.cz: 1. den EET? Problémy s pokladnami

1. den EET? Problémy s pokladnami