PDA

Voir la version complète : [PSP][Tutorial] OSlib - Jour 5 : Chhhhut!


Yodajr
10/04/2006, 02h43
Jour 5 : Jouer musiques et sons

On met en pause le graphisme quelques instants afin de se consacrer à une partie bien sympa : le son ;)


1) Les sons et musiques
Nous avons besoin pour ce tuto de 2 fichiers.
Un fichier qui nous servira de son (très très court donc) au format WAV et un autre qui nous servira de musique, lui aussi au format WAV.

Le fichier son est à mettre tel quel sur la MS dans le répertoire du jeu.

Le fichier musique lui, doit etre converti en BGM, le format compressé d'oslib.
Prennez donc votre WAV cadencé soit à 44KHz, soit à 22KHz, soit à 11KHz. Tout autre format ne fonctionnera pas.
Il doit etre également en mono, oslib ne gère pas encore la stéréo.
Dans l'archive d'oslib, se trouve un dossier "Tools" copiez-y votre fichier wav et en considérant qu'il s'appele "music.wav", tappez en command dos :
wav2bgm music.wav music.bgm
Vous obtiendrez donc un fichier "music.bgm" qu'il faudra copier sur la MS dans le répertoire du jeu.

Vous pouvez aussi également utiliser ceux du tuto (dans l'archive en bas de page)


2) Le code

//La librairie principale OSLib
#include <oslib/oslib.h>

//les callbacks
PSP_MODULE_INFO("OSLib Sample", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);

//definition des pointeurs vers nos sons
OSL_SOUND *music, *son;

int main()
{
//Initialisation de la librairie
oslInit(0);

//Initialisation du mode graphique
oslInitGfx(OSL_PF_8888, 1);

//Initialisation de la console texte
oslInitConsole();

//Initialiser l'audio
oslInitAudio();

//chargement des sons. Loading encore ? pas forcement...
music = oslLoadSoundFile("diredocks.bgm", OSL_FMT_STREAM);
son = oslLoadSoundFile("injury.wav", OSL_FMT_NONE);

//vérification
if (!music || !son)
oslDebug("Verifiez que tous les fichiers sont bien copiés dans le répertoire du jeu.");

//boucle principale
while (!osl_quit)
{
//Permet de dessiner
oslStartDrawing();

//Lit les touches
oslReadKeys();

//commandes du son
if (osl_keys->pressed.triangle) oslPlaySound(music, 0);
if (osl_keys->pressed.square) oslPauseSound(music, -1);
if (osl_keys->pressed.circle) oslStopSound(music);
if (osl_keys->pressed.cross) oslPlaySound(son, 1);

//affichage des consignes
oslPrintf_xy(0,0,"Pressez Triangle pour lancer la musique.");
oslPrintf_xy(0,10,"Pressez Quarre pour mettre en pause/relancer la musique.");
oslPrintf_xy(0,20,"Pressez Rond pour stopper la musique.");
oslPrintf_xy(0,30,"Pressez Croix pour jouer le son.");

//Fin du dessin
oslEndDrawing();

//Synchronise l'écran
oslSyncFrame();

//pour la mise en veille
oslAudioVSync();
}

//on quitte l'application
oslEndGfx();
oslQuit();
return 0;
}


3) Explications

OSL_SOUND *music, *son;
On definit les pointeurs vers nos sons et musiques. Creez en un pour chaque son et bien sûr au tout début :)

oslInitAudio();
Initialise le système audio, comme d'hab au tout début ;)

music = oslLoadSoundFile("diredocks.bgm", OSL_FMT_STREAM);
Ici on charge un bgm, donc une musique. 2 types de chargement sont alors possibles :
OSL_FMT_STREAM : le fichier ne sera pas chargé dans la mémoire de la PSP mais streamé depuis la MS. Avantage : on gagne du temps lors du chargement et on économise de la place en ram (20Mo de dispo). Inconvénients : le stream demande un peu plus de CPU, surtout si l'echantillonage est élevé.
OSL_FMT_NONE : ben là pas de stream, le fichier est chargé, donc c'est tout l'inverse de l'explication du stream :P

son = oslLoadSoundFile("injury.wav", OSL_FMT_NONE);
Ici on charge un son (wav). Il est conseillé de charger les sons en mémoire, ou streamer ceux qui sont joués vraiment très rarement.

oslPlaySound(music, 0);
oslPlaySound(son, 1);
Joue le son ou lance la musique. Le chiffre est le canal sur lequel sera joué le son ou la musique, la PSP en proposant 8 (de 0 à 7).

oslPauseSound(music, -1);
Pause la musique. Avec un 1, je met en pause, avec un 0 je continue. Ici le -1 signifie que je change l'état à chaque appel.

oslStopSound(music);
Je pense que vous avez deviné, ici on stoppe la musique. Au prochain appel de PlaySound la musique repartira du début.
Comme vous pouvez le constater, pas besoin de préciser le canal.

oslAudioVSync();
A appeler à chaque frame pour palier au bug de la mise en veille (voir la doc pour plus de détails)


4) Eboot

Téléchargez l'eboot compilé pour 1.5 ici (http://hothmoon.free.fr/psp/dev/jour05_eboot.zip)

peb
20/03/2007, 22h58
Bonjour! voila j'applique ton cours dans une de mes créations, mais en faite j'ai un soucis...

quand j'utilise "oslAudioVSync();" quelques secondes plustard j'ai mon programme qui plante!

et quand je l'utilise pas, mon texte s'affiche mais il est illisible parce que ça bug, sa m'affiche des carrer gris vert^^

voila... tu vas finir par croire que je suis un bourrin avec mes problème cheulou! lol!

Brunni
20/03/2007, 23h09
J'imagine qu'il y a un buffer overflow (problème grave dans ton programme). Il faudra poster la source pour qu'on puisse t'aider ;)

peb
20/03/2007, 23h56
Buffer overflow? sa veut dire que j'ai trop charger d'image et de son?

Sinon je vous mais la boucle, et la fonction qui bug (sinon sa serait un peu long :p )




//on joue la presentation
//oslPlaySound(son_presentation, 1);

//pour la mise en veille
oslAudioVSync();

//on affiche l'image de fond
oslDrawImage(fond);

//Pause
Pause(8000);

//on affiche le menu1b pour le premier lancement du menu
oslDrawImage(menu1b2);

//Synchronise l'écran
oslSyncFrame();


//boucle principale
while ( !osl_quit)
{



//check des touches
menu_touches();

}






//La fonction
void menu_touches()
{ //void

//Permet de dessiner
oslStartDrawing();

//Lit les touches
oslReadKeys();

if (osl_keys->held.cross)
{
if (choix_menu == 1) choix_menu2 = 1;
if (choix_menu == 2) choix_menu2 = 2;
if (choix_menu == 3) choix_menu2 = 3;
if (choix_menu == 4) choix_menu2 = 4;
if (choix_menu == 5) choix_menu2 = 5;
}
if (osl_keys->held.left)
{ //if1
//Conditions possiblent et action à effectuer
if (choix_menu == 1) oslPlaySound(erreur, 1);
if (choix_menu > 1)
{//if1b
choix_menu = choix_menu - 1;

//on effectu le changement de menu
if (choix_menu == 1)
{
oslDrawImage(menu1b);
}
if (choix_menu == 2)
{
oslDrawImage(menu2b);
}
if (choix_menu == 3)
{
oslDrawImage(menu3b);
}
if (choix_menu == 4)
{
oslDrawImage(menu4b);
}
if (choix_menu == 5)
{
oslDrawImage(menu5b);
}
}//if1b
} //if1
if (osl_keys->held.right)
{ //if2
//Conditions possiblent et action à effectuer
if (choix_menu == 5) oslPlaySound(erreur, 1);
if (choix_menu < 5)
{//if2b
choix_menu = choix_menu + 1;

//on effectu le changement de menu
if (choix_menu == 1)
{
oslDrawImage(menu1b);
}
if (choix_menu == 2)
{
oslDrawImage(menu2b);
}
if (choix_menu == 3)
{
oslDrawImage(menu3b);
}
if (choix_menu == 4)
{
oslDrawImage(menu4b);
}
if (choix_menu == 5)
{
oslDrawImage(menu5b);
}
}//if2b
} //if2

//pour la mise en veille
//oslAudioVSync();
Pause(2700);




Le code en rouge fait tout planter si je l'active, mais comme ça le texte bug dans un autre menu


EDIT : en faite c'est assez aléatoire...des fois ça bug, des fois pas...
Sinon pour le texte, si je configure une touche pourquel joue un sonet que je joue le son, après mon texte ne bug plus...héhé...lol


EDIT2 : j'ai enlevé tout ce qui se rapportait au son, et la sa ne bug plus...donc sa vient bien des instructions liées au son...mais je ne vois pas qu'est ce qu'il pourrait rendre mon homebrew instable comme ça juste avec le son...

Brunni
15/04/2007, 19h33
Oops j'avais complètement oublié ce topic, désolé sincèrement :-'
Ton code ne me permet pas de trouver le problème, il manque les définitions des variables que tu utilises (son_presentation, erreur, etc.), où tu les charges, etc. Mais de façon générale, le plantage aléatoire signifie forcément un bug chiant qui n'est pas toujours lié avec la fonction qui plante (en l'occurence oslAudioVSync n'a aucune raison de planter).
Essaie déjà d'installer la dernière version d'oslib, on ne sait jamais... ;)

Haseo
31/05/2007, 18h40
J'ai eu du mal pour la conversion de la musique mais j'ai réussi^^

Haseo
31/05/2007, 23h24
Salut, j'ai un problème :

//La librairie principale OSLib
#include <oslib/oslib.h>

//les callbacks
PSP_MODULE_INFO("OSLib Sample", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);

//definition des pointeurs vers nos images
OSL_IMAGE *background, *vaisseauakaryuu;

//definition des pointeurs vers nos sons
OSL_SOUND *music, *son;

int main()
{
//Initialisation de la librairie
oslInit(0);

//Initialisation du mode graphique
oslInitGfx(OSL_PF_8888, 1);

//Initialiser l'audio
oslInitAudio();

//chargement des sons. Loading encore ? pas forcement...
music = oslLoadSoundFile("music.bgm", OSL_FMT_STREAM);
son = oslLoadSoundFile("son.wav", OSL_FMT_NONE);

//definition de la transparence
oslSetTransparentColor(RGB(192,192,192));

//chargement de nos images (oui, le "loading" :p)
background = oslLoadImageFile("background.png", OSL_IN_RAM, OSL_PF_5551);
vaisseauakaryuu = oslLoadImageFile("vaisseauakaryuu.png", OSL_IN_RAM, OSL_PF_5551);

//plus de transparence
oslDisableTransparentColor();

//vérification
if (!background || !vaisseauakaryuu || !music || !son)
oslDebug("Impossible de charger un ou plusieurs fichiers. Verifiez que tous les fichiers sont bien copiés dans le répertoire du jeu.");

//boucle principale
while (!osl_quit)
{
//Permet de dessiner
oslStartDrawing();

//Lit les touches
oslReadKeys();

//commandes du son
oslPlaySound(music, 0);
if (osl_keys->pressed.circle) oslPlaySound(son, 1);

//deplace le sprite du vaisseau
if (osl_keys->held.down) vaisseauakaryuu->y += 2;
if (osl_keys->held.up) vaisseauakaryuu->y -= 2;
if (osl_keys->held.left) vaisseauakaryuu->x -= 2;
if (osl_keys->held.right) vaisseauakaryuu->x += 2;

//dessine nos images
oslDrawImage(background);
oslDrawImage(vaisseauakaryuu);

//Fin du dessin
oslEndDrawing();

//Synchronise l'écran
oslSyncFrame();

//pour la mise en veille
oslAudioVSync();
}

//on quitte l'application
oslEndGfx();
oslQuit();
return 0;
}

Voila à cet encroit :
//commandes du son
oslPlaySound(music, 0);
if (osl_keys->pressed.circle) oslPlaySound(son, 1);
Je cherche comme vous le voyez à jouer "music" au démarrage du jeu sans que l'on appui sur une touche... Pouvez-vous m'aidez mici++

Solevis
20/10/2007, 17h00
Bonjour
Comment convertir un wav stereo en mono ?

daaa57150
20/10/2007, 21h27
Bonjour
Comment convertir un wav stereo en mono ?
je pense que tu peux utiliser tout simplement "sndrec32" si tu es sous windows (menu démarrer->exécuter->sndrec32).