Probleme avec FMOD en C
Forum Programmation : Probleme avec FMOD en C
slt tous le monde je tente un petit exercice pour reviser mes cours de C mais j'ai un petit probleme pour jouer un son court avec FMOD c'est un tir de fusil, j'utilise la SDL : avec SDL_WaitEvent sa marche mais avec SDL_PollEvent le son déraille, en gros au lieu de "PAN" sa fait "Pranzazing".... voici ma boucle while, je ne peux pas poster le code entier c'est trop long....
/* EVENEMENTS */
while (continuer == 1)
{// debut WHILE
if (pause ==0)
SDL_ShowCursor(SDL_DISABLE);
else
SDL_ShowCursor(SDL_ENABLE);
SDL_PollEvent (& event);
switch (event.type)
{// début SWITCH
/**/ case SDL_QUIT:
/**/ continuer =0;
/**/ break;
/**/ case SDL_KEYDOWN:
/**/ switch(event.key.keysym.sym)
{//evenement clavier
/**/ case SDLK_ESCAPE:
/**/ continuer = 0 ;
/**/ break;
/**/ case SDLK_p:
/**/ pause = 1;
/**/ posViseurPause.x = posViseur.x;
/**/ posViseurPause.y = posViseur.y;
/**/ break;
/**/
/**/ case SDLK_o:
/**/ if (pause != 0) {//début if en pause
/**/ SDL_WarpMouse(posViseurPause.x+viseur-> w/2,posViseurPause.y+viseur-> h/2);
/**/ pause =0;
/**/
}//fin if en pause
}//fin evenement clavier retour evenement souris et autre
/**/ break;
/**/ if (pause == 0) { // debut if ! en pause
/**/ case SDL_MOUSEMOTION:// le pointeur de la souris "devient" le viseur
/**/ if (event.motion.x < 640 - viseur-> w/2 )//attribut les coordonnées x du viseur tant qu'il est dans la fenetre
/**/ posViseur.x=event.motion.x - viseur->h/2;
/**/ if (event.motion.y < 480 - viseur-> h/2 )//attribut les coordonnées y du viseur tant qu'il est dans la fenetre
/**/ posViseur.y=event.motion.y - viseur->w/2;
/**/ /* le fusil suit le viseur*/
/**/ posfusil.x = posViseur.x+4;
/**/ posfusil.y = 480- fusil->h;
/**/ break;
/**/ case SDL_MOUSEBUTTONDOWN:
if (event.button.button == SDL_BUTTON_LEFT)
{
/**/ if ( l < 1001 && pause == 0)
{
/**/ posimpact[l].x = event.button.x - impact->w /2;
/**/ posimpact[l].y = event.button.y - impact->h /2;
/**/ FSOUND_PlaySound(FSOUND_FREE, tir);/* Jouer le son d'un coup de feu */
}
i++;
/**/ break;
}
}//fin if ! en pause
}/* < /// SWITCH > */
if (pause == 0)
{
for(m=0;m<1000;m++)
{
SDL_BlitSurface(impact, NULL, ecranImpact, &posimpact[m]);
}
SDL_FillRect(ecran, NULL,SDL_MapRGB(ecran->format, 0,255,255)); // efface l'ecran precedent pour une animation futur
SDL_BlitSurface(fusil, NULL, ecran, &posfusil);
if (posEnnemis.x < 0)
SDL_BlitSurface(ennemis, &ennemisT , ecran, &posEnnemis);
if (posEnnemis.x > 0)
SDL_BlitSurface(ennemis, NULL , ecran, &posEnnemis);
SDL_BlitSurface(ecranImpact, NULL , ecran, &posEcranImpact);
SDL_BlitSurface(viseur, NULL, ecran, &posViseur);
SDL_Flip(ecran);
}
}/* fin de WHILE => evenement */
la fonction FSOUND_PlaySound() est synchrone ?
c'est a dire ? Si je clique le son se joue mais il est deformé
Est-ce que la fonction rend la main dessuite (asynchrone) ? ou est-ce qu'il faut que le son soit terminé pour que la fonction retourne (synchrone) ?
Si c'est asynchrone, il faut s'assurer que le son ne soit pas joué plusieurs fois.
heu je n'ai pas tout compris mais le son doit être joué plusieurs fois comme tu l'as dit... Comment faire pour le jouer une seul fois ?
Bon, j'ai un peu regardé la doc, et visiblement, c'est bien asynchrone.
Donc, avant de faire ton playSound, teste si aucun son n'est en train d'être joué avec la fonction FSOUND_IsPlaying
Message édité par CRicky le 10-02-2007 à 10:57:46
en essayant d'utiliser ta fonction je me suis rendu compte d'un truc
case SDL_MOUSEBUTTONDOWN:
c'est peut être pas un probleme de son en fin de compte mais d'evenement si je reste appuyé sur le clic gauche le son est joué a chaque tours dans la boucle wihle mais si j'appuie trés vite le son est joué moins de fois j'ai essayé avec
case SDL_MOUSEBUTTONUP:
le resultat est un peu mieux mais des fois le son est joué plusieur fois et si je reste appuyé sur le clic gauche il n'y a pas de son, je le relache et là le son ne s'arrête plus...
Oui, c'est un problème d'évènement, c'est pour ça que je te demandais si la fonction est asynchrone.
Tu peux avoir le même problème avec le clavier.
je n'arrive pas a m'en sortir avec FSOUND_IsPlaying tu peux me mettre un exemple stp ?
déclare 2 variables booléennes:
Code :
|
la fonction FSOUND_PlaySound() retourne le channel handler, mémorise-le lors de l'appel, indique qu'un son est joué.
Comme ça, pour la boucle suivante, tu testes si un son est joué, et s'il est joué sur le canal indiqué. Lorsque le son est terminé, il faut penser à remettre à 0.
Code :
|
J'ai décomposé les if pour mieux expliquer. On peut faire mieux.
il y a du mieux mais maintenant si les tir sont trop rapprocher dans le temps le son n'est pas joué....(autant le sdz traite trés bien les cours de progra autant le passage sur le son est trés mal abordé....)
Oui, alors comme tous les jeu, il faut mettre un temps d'attente avant de refaire une action. Avec SDL_GetTicks(), tu fais un timer que tu initialises après le play sound.
Lorsque ça dépasse un certain temps (donné en ms), tu considères que l'on peut à nouveau tirer.
A la limite, tu peux faire un FSOUND_StopSound() pour arrêter l'ancien son avant de reprendre un nouveau.
Sinon, pour le son, tu utilise fmod, c'est bien, mais c'est aussi géré par SDL:
http://lazyfoo.net/SDL_tutorials/lesson11/index.php
Tu as peut-être moins de fonctionnalité.
| Citation : il faut mettre un temps d'attente avant de refaire une action. Avec SDL_GetTicks() |
SDL_Delay(500);/*attend une demi seconde*/
Dans un jeu, un delay (ou sleep) c'est pas bon parce que le jeu doit continuer à tourner et pas rester bloquer, sinon ce sont des lenteurs qui s'accumulent.
Message édité par CRicky le 14-02-2007 à 00:02:01
oui mais d'aprés le site où j'apprend la sdl ne gere pas trés bien le son donc on est parti vers FMOD ^^
ça sa va empecher le blit de l'impact non ? je ne peux pas faire en sorte que le son se joue même si un blit est trop rapproché d'un autre ? Sa fait quelque chose si on met un timer dans une boucle ? un timer est appelé quoi qu'il arrive même a l'exterrieur d'une boucle mais je n'ai jamais vu de timer dans une boucle while, sa va l'appeler plusieurs fois non ?
En fait le principe c'est de ne jamais bloquer l'intérieur d'un boucle évènementielle pour traiter tout autre évènement. Donc, s'il faut faire une attente, il faut se contenter de laisser passer sans rien faire jusqu'à ce que le temps soit écoulé.
Pour ça, quand ton tir se déclenche tu mets une variable:
Code :
|
Et dans chaque passage, si tu veux savoir si tu es sorti du temps d'attente, il te suffit de faire le test:
Code :
|
où tu auras définit la durée en constante en millisecondes:
Code :
|
ça permet de verrouiller le tir toutes les 100ms.
après si le son n'est pas tiré, tu peux arrêter le son précédent comme j'avais indiqué, mais tu peux aussi accumuler les sons (je pense que ça utilise un nouveau numéro de canal).
Si tu utilise un SDL_Delay(), ta boucle évènementielle va se bloquer, donc aucun évènement de souris ou clavier, ni rafraichissement d'affichage ne sera effectué. Si tu n'en fais qu'un d'une centaine de ms, ça ne se verra pas, mais lorsque le jeu se complexifiera petit à petit, tu verras des problème (injouable), car il faut rester dans du temps réel.
ok merci j'essayerai de tester tout ça en se moment je n'ai pas trop le temps...
Il y a 916 utilisateurs connus et inconnus. Pour voir la liste des connectés connus, cliquez ici.
