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.