SDL:n lisäkirjasto SDL_Mixerillä on mahdollista toistaa erimuotoisia äänitiedostoja. Tässä ks. kirjastoa käyttävä luokka, jolla on helppoa toistaa eri äänitiedostoja samanaikaisesti. Mielestäni käyttö on helpompaa kun SDL_Mixerin funktioiden kutsuminen suoraan.
Tuetut tiedostotyypit:
WAV, AIFF, RIFF, OGG, ja VOC
Jonkinlainen manuaali: http://koti.mbnet.fi/heikki_m/musa/readme.txt
Zip: http://koti.mbnet.fi/heikki_m/musa/musa.zip
Huom! Käännetty ohjelma tarvitsee SDL.dll ja SDL_mixer.dll -tiedostot.
musaluokka.h
//********************************************************************* //MUSA-luokan esittely //Versio 1.0 //BY: Heikki Mäntysaari, 2004 //Jos funktio palauttaa arvon, -1 tarkoittaa epäonnistumista (paitsi voimakkuuden säätö) //********************************************************************* class Musa { private: Mix_Chunk *data; int kanava; //Millä kanavalla kyseistä ääntä soitetaan public: Musa(char *polku, int kannu); //Muodostin void Vapauta(); //Tuhoaja int Toista(int maara); //Toistaa maara monta kertaa äänen int ToistaAika(int aika); //Toistaa tietyn ajan (ms) void Haivyta(int ms); //Häivyttää äänen tietyssa ajassa (ms) int Voimakkuus(int voimakkuus); //Vaihtaa soittovoimakkuuden (0-128) void Lopeta(); //Lopettaa äänen toistamisen void Keskeyta(); //Keskeyttää äänen toistamisen void Jatka(); //Jatkaa äänen toistamista int ToistaHaivyttaen(int aika, int kerrat); //Aloittaa äänen toistamisen häivyttämällä }; //********************************************************************* //Muodostin //Lataa äänitiedoston data-tietotyyppiin //********************************************************************* Musa::Musa(char *polku, int kannu) { data=Mix_LoadWAV(polku); if (!data) { //Lataus epäonnistui fprintf(stderr, "Virhe (Mix_LoadWAV @ Musa::Musa): %s ", Mix_GetError()); } //kanava talteen kanava=kannu; } //********************************************************************* //Tuhoaja //Vapauttaa musiikkimuuttujan //********************************************************************* void Musa::Vapauta() { Mix_FreeChunk(data); data=NULL; } //********************************************************************* //Toista //Alkaa toistaa data-tietotyypissä olevaa ääntä //Parametrina toistokertojen lukumäärä. //********************************************************************* int Musa::Toista(int kerrat) { //soitetaan if(Mix_PlayChannel(kanava, data, kerrat)==-1) { fprintf(stderr, "Virhe (Mix_PlayChannel @ Musa::Toista): %s ", Mix_GetError()); //virhe return -1; } return 0; } //********************************************************************* //ToistaAika //Alkaa toistaa data-tietotyypissä olevaa musiikkia //Parametrina toistoaika (ms) //********************************************************************* int Musa::ToistaAika(int aika) { //soitetaan if(Mix_PlayChannelTimed(kanava, data, -1, aika)==-1) { fprintf(stderr, "Virhe (Mix_PlayChannelTimed @ Musa::ToistaAika): %s ", Mix_GetError()); //virhe return -1; } return 0; } //********************************************************************* //Voimakkuuden säätö //Vaihtaa data:ssa olevan äänen voimakkuudeksi parametrina annetun arvon (0-128) //Palauttaa entisen voimakkuuden //********************************************************************* int Musa::Voimakkuus(int voimakkuus) { //onko arvo rajojen sisällä if (voimakkuus > 128) voimakkuus=128; if (voimakkuus < 0) voimakkuus=0; return Mix_VolumeChunk(data, voimakkuus); } //********************************************************************** //Haivyta //Häivyttää äänen, parametrina häivitykseen kuluva aika //********************************************************************** void Musa::Haivyta(int ms) { Mix_FadeOutChannel(kanava, ms); } //********************************************************************* //Lopettaminen //Lopettaa äänen toistamisen //********************************************************************* void Musa::Lopeta() { Mix_HaltChannel(kanava); } //********************************************************************* //Keskeyttäminen //Keskeyttää äänen toistamisen //********************************************************************* void Musa::Keskeyta() { Mix_Pause(kanava); } //********************************************************************* //Jatkaminen //Jatkaa äänen toistamista //********************************************************************* void Musa::Jatka() { Mix_Resume(kanava); } //********************************************************************* //Toisto Häivyttäen //Ottaa parametrina häivytysajan ms:inä ja toistokertojen määrän //********************************************************************* int Musa::ToistaHaivyttaen(int aika, int kerrat) { if(Mix_FadeInChannel(kanava, data, kerrat, aika)==-1) { fprintf(stderr, "Virhe (Mix_FadeInChannel @ Musa::ToistaHaivyttaen): %s ", Mix_GetError()); return -1; } return 0; }
Esimerkki SDL_Mixerin käytöstä MUSA-luokalla
//includet #include <SDL/SDL.h> //SDL #include <SDL/SDL_mixer.h> //SDL_mixer #include "musaluokka.h" //MUSA-luokan sisältö int main( int argc, char* argv[] ) { //Alustetaan SDL, käytettävä SDL_INIT_AUDIO -flagia if( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "SDL:n alustus ei onnistunut: %s ", SDL_GetError()); return 1; } //Alustetaan SDL_Mixer //44,1 khz, perusmuoto, 2 kajaria jne. lisätietoja http://jcatki.no-ip.org/SDL_mixer/SDL_mixer_9.html if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024)==-1) { //error } //ikkuna ruudulle (oikeastaan turhaan) SDL_Surface *naytto; naytto=SDL_SetVideoMode(600, 400, 32, SDL_HWSURFACE); //alustetaan oliot, samalla ladataan kappaleet Musa Tausta("musaa.ogg", 1); Musa Toinen("musaa.ogg", 2); //aloitetaan toistaminen "häivytys"-efektillä Tausta.ToistaHaivyttaen(2000, -1); //pikku tauko ohjelman suorituksessa, musiikki soi taustalla SDL_Delay(3000); //säädetään voimakkuutta Tausta.Voimakkuus(50); //keskeytetään toisto Tausta.Keskeyta(); //aloitetaan toinen toisto (sama tiedosto alusta) Toinen.Toista(2); //jatketaan ensin aloitettua toistoa Tausta.Jatka(); //musa soi 3s SDL_Delay (3000); //häivytetään 4s aikana ensin aloitettu Tausta.Haivyta(4000); //toinen soi vielä 5s SDL_Delay (5000); //vapautetaan muistia Tausta.Vapauta(); Toinen.Vapauta(); //sulkeudutaan Mix_CloseAudio(); SDL_Quit(); return 0; }
Kaikki kunnia hyvälle kommentoinnille! Oli ilo lukea.
Muutenkin varmasti hyvä esimerkki monille aloitteleville SDL:n käyttäjille.
/me kiittää ja kumartaa :D
Kuinkas montaa kanavaa tällä oikeastaan voi soittaa? ei jaksanut syvällisemmin tutustua edes kommentointiin joten piti kysyä :)
jep, aivan käyttökelpoiselta näyttää. Harmi vaan, että sdl_mixer on aika rajoittunut eikä sillä saa mitään hienouksia aikaan.
Testieni mukaan vähintään 4 eri kanavaa voidaan toistaa samanaikaisesti. Pitäisi kaivaa SDL_Mixerin manuaalista tarkka arvo...
lainaus:
Kaikki kunnia hyvälle kommentoinnille! Oli ilo lukea.
Muutenkin varmasti hyvä esimerkki monille aloitteleville SDL:n käyttäjille.
Kriittisempiä kommentteja näin vuosia myöhemmin:
lainaus:
Musa(char *polku, int kannu);
Oikea tyyppi olisi const char*
. Nythän tuota ei voi ollenkaan käyttää esimerkiksi C++:n stringien kanssa eikä virallisesti edes tavallisten tekstivakioiden kanssa.
lainaus:
data=Mix_LoadWAV_RW(SDL_RWFromFile(polku, "rb"), kannu);
Tässä on taas aivan väärä parametri, katsopa manuaalista Mix_LoadWAV_RW:n toiminta. Kannattaisi muutenkin käyttää suoraan Mix_LoadWAV-makroa, niin ei edes olisi mahdollisuutta tuohon virheeseen.
Kun funktiot ovat otsikkotiedostossa, niiden pitäisi olla inline-funktioita, koska muuten tulee törmäys, jos projektissa on useampi tiedosto, joihin tuo otsikko sisällytetään.
Aihe on jo aika vanha, joten et voi enää vastata siihen.