Allegro - MP3 podruhé (18. díl) - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:



C/C++

Allegro - MP3 podruhé (18. díl)

allegro

20. ledna 2003, 00.00 | V tomto díle se podíváme na knihovnu AllegroMP3 více do hloubky. Ukázkový příklad si rozebereme funkci po funkci. Také si ukážeme jak přehrávat hudbu stále dokola.

Poslední díl, jsme si na konci slíbili, že se podíváme na příklad AllegraMP3 trošku podrobněji a to také uděláme. Také jsme si řekli o tom, jak funguje přehrávání MPTrojek v AllegruMP3.

AllegroMP3 v ukázkovém příkladu k přehrávání hudby používá tzv. STREAMING neboli zvukové proudy. Co to je, to jsme si již ukázali v 9. díle, který je o MIDI a zvukových proudech a malinko jsme to nakousli i již zmiňovaný minulý díl.

Ještě to krátce shrnu. Jedná se o to, že načteme kus souboru (do bufferu), který přehráváme a potom v programu průběžně tento buffer obnovujeme novými daty. Pokud dojde, může se stát, že se hudba na chviličku zastaví, což bychom neměli dopustit. Tedy na obnovování si dávat pozor a dělat to co nejčastěji. Samozřejmě v rámci výpočtů scény. Ideální je dělat to jednou za jeden snímek. Tedy se vrátíme k herní kostře v šestém díle, která vypadala takto:

#include "allegro.h"

int Konec = 0;

int main(void)
{
	GameInit();

	while (!Konec)
	{
		Input();
		Tick();
		Render();
	}

	GameUnInit();

	return 0;
}
END_OF_MAIN();

Tedy inicializace, poté se opakovaly volání funkcí Input, Tick a Render a nakonec odinicializace. Například tedy můžete dát doplňování do funkce Tick, kde probíhá výpočet scény. Ale záleží to jen a jen na Vás a taky záleží co vlastně programujete a jakou máte strukturu Vašeho programu. Pojďme se ale podívat na ukázkový příklad AllegraMP3 více do hloubky.

Example.c více do hloubky

Jedná se o ukázkový příklad, takže zde nejsou žádné vylomeniny a části kódu, které by se nedali pochopit.
Pro náš seriál jsem příklad trošku upravil, který bude přehrávat pouze jednu písničku, abychom se nemuseli zabývat všemi těmi cykly, které tam jsou převážně kvůli tomu, že přehráváme na ráz více zvuků.

Vypustil jsem funkci do_example a nacpal vše do hlavní funkce main, kvůli šetření místem. Zbytek zůstal stejný a proto ho zde již nevypisuji. Můžete se na něj podívat tak, že si otevřete ukázkový soubor na svém počítači. Upravený ukázkový příklad tedy vypadá takto:

int main() { 
  MP3FILE *mp3 = (MP3FILE *)malloc(sizeof(MP3FILE));
  char *s="a.mp3";

  allegro_init();

  install_timer();
  install_keyboard();

  if (set_gfx_mode(GFX_SAFE, 640, 480, 0, 0) < 0) {
    allegro_message("Error setting video mode.\n");
    return 1;
  }
  clear_to_color(screen, makecol(255, 255, 255));

  /* to achieve the max possible volume */
  set_volume_per_voice(0);

  if (install_sound(DIGI_AUTODETECT, MIDI_NONE, 0) < 0) {
    set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
    allegro_message("Error installing sound.\n");
    return 1;
  }

// hlavni cast kodu, ktera prehrava

  putstr(s);

  if (mp3 = open_mp3_file(s))
    play_mp3_file(mp3, BUFSZ, 255, 128);
  else 
    putstr("Error opening.");

  while (!keypressed()) {
    if (poll_mp3_file(mp3) != ALMP3_OK) {
        close_mp3_file(mp3);
        mp3 = NULL;
    }
  }

  close_mp3_file(mp3);

  free(mp3);


// konec hlavni casti kodu, ktery prehrava

  allegro_exit();

  return 0;
}
END_OF_MAIN();

Jaké jsou rozdíly?

První co jsem udělal, bylo, že jsem změnil proměnnou mp3 s pole na pointer na strukturu. Který s deklarací i inicializuji. Pro úplnost bychom měli provést ještě kontrolu. Dále místo argumentů je název souboru zapsán natvrdo do programu. Moje MPTrojka se jmenuje a.mp3. Pokud máte jinou, můžete to samozřejmě přepsat. Respektive musíte, aby se vám program spustil. Dále přeskočte v funkci putstr. Je to přesně to co jsme si říkali již minule. Za ní totiž následuje otevření souboru, spuštění muziky, která je v bufferu, poté doplňování v cyklu a nakonec zavření souboru. Dále uvolnění paměti a konec Allegra.

Jednotlivé funkce

Vraťme se ale k jednotlivým funkcím podrobněji. Vezmeme je popořadě tak jak je voláme za sebou. Jako první přichází tedy open_mp3_file, která v celém znění (resp. její prototyp) vypadá následovně:

MP3FILE *open_mp3_file(char *filename);

Jak jste si již všimli a vyčetli z ukázkového příkladu, tak tato funkce bere jako parametr jméno souboru, který má otevřít a vrací pointer na strukturu MP3FILE.

Jednotlivé funkce nebo spíše jejich vnitřky jsem se rozhodl zde nepopisovat a to ze dvou důvodů. Protože tam jsou pakovací soubory, které jsme ještě nebrali a také by to nebylo jenom na tento díl.

Další funkce je na přehrávání. Má tento prototyp:

int play_mp3_file(MP3FILE *mp3, int buflen, int vol, int pan) {

Jako parametr má mimo jiné samozřejmě naší strukturu na MP3FILE, což je první parametr. Druhý je délka našeho bufferu což je v našem případě 65536 (všimněte si, že je to dělané na int, kde se počítá s tím, že sizeof(int) = 4 byte). Velikost si samozřejmě můžete nastavit podle sebe, záleží na tom, kolik tomu chcete věnovat paměti a na jaký projekt to bude a taky jak velký soubor máte. Velikost se odráží od těchto všech informací. Přesto bych doporučil násobek 2, pro rychlost. Třetí parametr je vol neboli volume. Může být v rozmezí 0-255. Můžete tedy do hry zamontovat i hlasitost. A poslední parametr je pan, což je balanc mezi jednotlivými stranami. Levá/pravá - rozmezí 0-255. 0 znamená, že hraje pouze levý reproduktor a hodnota 255 znamená, že hraje pouze pravý reproduktor. My máme zadanou hodnotu 128, tedy vyvážení mezi oběma stranami.

Tato funkce, respektive funkce uvnitř, která je volána vrací buď ALMP3_OK pokud není žádný problém nebo vrací ALMP3_PLAY_BUFFERTOOSMALL, pokud je velikost bufferu příliš malá. Doporučil jsem Vám, vytvořit buffer násobku 2, ale ještě zmíním, že výrobce AllegraMP3 doporučuje v manuálu hodnotu mezi 16384 a 32768.

Další funkce s našem pořadí je

int poll_mp3_file(MP3FILE *mp3);

která, jak jsme si již říkali doplňuje buffer opakovaným voláním. Jako parametr má naši strukturu MP3FILE, ve které doplní zmiňovaný buffer.

Funkce vrací tyto hodnoty:

ALMP3_OK - jestliže není žádná chyba (to testujeme my)
ALMP3_POLL_PLAYJUSTFINISHED - pokud soubor již skončil
ALMP3_POLL_NOTPLAYING - pokud soubor nehraje
ALMP3_POLL_FRAMECORRUPT - pokud je jeden frame hudby špatný
ALMP3_POLL_INTERNALERROR - pokud je interní chyba AllegraMP3

Pokud jsme četli manuál, tak asi vidíte, že je zde uvedeno všechno co je v manuálu. Ostatně, nevěřím, že byste mohli všechny tyto hodnoty potřebovat a proto se jimi nebudeme zatím nadále zabývat. Jenom podotknu, že nejvíce se nám hodí, a to mimo jiné i my používáme, jestli vše proběhlo bez chyby. Tedy ALMP3_OK. Tato hodnota je shodná ve většině funkcí, pokud nenastala žádná chyba.

Kdybyste chtěli vědět můžete se podívat do souboru almp3.h, kde je definice všech možných chyb AllegraMP3.

Jako poslední funkci tu máme

void close_mp3_file(MP3FILE *mp3);

což jak napovídá, a také jsme si to říkali, je funkce, která uzavře soubor s muzikou a uvolní paměť. Měli byste jí volat pokaždé, když končíte program, nebo lépe, když končíte práci se souborem.

Přehrávání hudby stále do dokola?

Toto můžete udělat jednoduchým způsobem a to tak, že budete testovat konec souboru při každé aktualizaci bufferu. Pokud bude konec, zavřete soubor a znovu jej otevřete.
Tedy místo smyčky

while (!keypressed()) {
  if (poll_mp3_file(mp3) != ALMP3_OK) {
    close_mp3_file(mp3);
    mp3 = NULL;
  }
}

můžete například použít tuto:

while (!keypressed()) {
  if (poll_mp3_file(mp3) != ALMP3_OK) {
    close_mp3_file(mp3);
    mp3 = NULL;

    // znovu otevreni
    if (mp3 = open_mp3_file(s))
      play_mp3_file(mp3, BUFSZ, 255, 128);
    else { 
      putstr("Error opening.");
      break;
    }
  }
}

A hudba bude hrát pořád dokola…

Závěr

Sečteno podtrženo je AllegroMP3 velice dobrá knihovna. Umí přehrávat velice rozšířený a řekl bych i kvalitně dostačující formát a navíc jen s malou námahou a hlavně s malým požadavkem na paměť. Ten si ostatně určujeme sami.

V příštím díle se budeme ještě touto knihovnou zabývat, protože to co jsme se naučili zde, i když si myslím, že je to pro naše použití dostačující, je tak trochu "basic". Tudíž si příští díl povíme ještě o tom, jak pomocí AllegraMP3 načíst do paměti celý blok neboli celý soubor a pak jej jen nechat přehrát.

Upravené zdrojové soubory si můžete stáhnout zde.

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » C/C++  

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: