Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: C++: MUSA-luokka SDL_Mixerille

Sivun loppuun

Heikki [01.08.2004 22:43:03]

#

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;

}

Metabolix [04.08.2004 14:15:24]

#

Kaikki kunnia hyvälle kommentoinnille! Oli ilo lukea.
Muutenkin varmasti hyvä esimerkki monille aloitteleville SDL:n käyttäjille.

Heikki [04.08.2004 14:43:57]

#

/me kiittää ja kumartaa :D

Gwaur [04.08.2004 18:53:19]

#

Kuinkas montaa kanavaa tällä oikeastaan voi soittaa? ei jaksanut syvällisemmin tutustua edes kommentointiin joten piti kysyä :)

BlueByte [04.08.2004 23:55:48]

#

jep, aivan käyttökelpoiselta näyttää. Harmi vaan, että sdl_mixer on aika rajoittunut eikä sillä saa mitään hienouksia aikaan.

Heikki [05.08.2004 10:24:13]

#

Testieni mukaan vähintään 4 eri kanavaa voidaan toistaa samanaikaisesti. Pitäisi kaivaa SDL_Mixerin manuaalista tarkka arvo...

theman [05.08.2004 12:50:44]

#

lainaus:

Kaikki kunnia hyvälle kommentoinnille! Oli ilo lukea.
Muutenkin varmasti hyvä esimerkki monille aloitteleville SDL:n käyttäjille.

Metabolix [22.11.2009 16:00:44]

#

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.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta