En théorie, le flag
FMOD_CREATESAMPLE permet de charger n'importe quel type de son, y compris les formats compressés MP3, OGG, WMA. Le problème concerne les sons « longs », c'est-à-dire les musiques.
En effet, une musique dure en moyenne 3 à 4 minutes. Or, avec ce flag, la fonction
FMOD_System_CreateSound charge
tout le fichier en mémoire (et c'est la version décompressée qui est mise en mémoire, donc ça prend beaucoup de place !).
Si vous avez un son long (on va parler de « musique » dorénavant), il est préférable de le charger en
streaming, c'est-à-dire d'en charger de petits bouts au fur et à mesure de la lecture ; c'est d'ailleurs ce que font tous les lecteurs audio.
Trouver des musiques
Là, on rentre en terrain miné, épineux, explosif (comme vous préférez).
En effet, la plupart des musiques et chansons que l'on connaît sont soumises au droit d'auteur. Même si vous ne faites qu'un petit programme, il faut verser une redevance à la SACEM (en France du moins).
Donc, mis à part les MP3 soumis à droit d'auteur, que nous reste-t-il ?
Heureusement, il y a des chansons libres de droit ! Les auteurs vous autorisent à diffuser librement leurs chansons, il n'y a donc aucun problème pour que vous les utilisiez dans vos programmes.
Si votre programme est payant, il faudra en parler à l'artiste, à moins que celui-ci n'autorise explicitement une utilisation commerciale de son œuvre. Une chanson libre de droit peut être téléchargée, copiée et écoutée librement, mais ça ne veut pas dire qu'on vous autorise à vous faire de l'argent sur le dos des artistes !
Bon, la question maintenant est : « où trouver des musiques libres de droit ? ». On pourrait faire une recherche de « Free Music » sur Google, mais là pour le coup il n'est pas notre ami. En effet, allez savoir pourquoi, on a beau taper le mot « Free », on tombe quand même sur des sites qui nous proposent d'acheter des musiques !
Il existe heureusement des sites qui sont dédiés à la musique libre de droit. Là, je vous recommande
Jamendo qui est un très bon site, mais ce n'est pas le seul qui existe dans le domaine.
Les chansons sont classées par style. Vous avez beaucoup de choix. On y trouve du bon, du moins bon, du très très bon, du très très nul… En fait, tout dépend de vos goûts et de votre réceptivité aux différents styles de musique. De préférence, prenez une chanson qui peut servir de musique de fond et qui correspond bien à l'univers de votre jeu.
Pour information, cette chanson provient de l'album « Lies and Speeches » du groupe français « Hype ». Pour en savoir plus sur « Hype », vous pouvez visiter
leur page MySpace.
Je suis parfaitement conscient que les goûts et les couleurs ne se discutent pas. N'ayez donc pas peur de prendre une autre musique si celle-ci ne vous plaisait pas.
J'ai donc téléchargé l'album et je vais utiliser
la chanson « Home » au format MP3.
Vous pouvez la télécharger directement si vous voulez faire des tests en même temps que moi. C'est un des avantages de la musique libre : on peut la copier / distribuer librement, donc ne nous gênons pas.
Les étapes à suivre pour jouer une musique
La seule différence est le flag donné à la fonction
FMOD_System_CreateSound.
Au lieu de lui donner le flag
FMOD_CREATESAMPLE, on lui donnera les flags suivants :
FMOD_SOFTWARE,
FMOD_2D et
FMOD_CREATESTREAM.
Ne vous attardez pas trop sur la signification de ces flags ; celui qui nous intéresse le plus est
FMOD_CREATESTREAM, car c'est lui qui dira à FMOD de charger la musique bout par bout.
Pour utiliser tous ces flags en même temps, on utilisera l'opérateur logique
| de cette façon :
Code : C | FMOD_System_CreateSound(system, "ma_musique.mp3", FMOD_SOFTWARE | FMOD_2D | FMOD_CREATESTREAM, 0, &sound);
|
Et voilà le travail !
Mais ce n'est pas tout. Dans le cas d'une musique, il peut être bien de savoir modifier le volume, gérer les répétitions de la chanson, la mettre en pause ou même l'arrêter. C'est ce genre de choses que nous allons voir maintenant.
Mais avant ça, nous aurons besoin de travailler sur les canaux directement.
Récupérer un canal ou un groupe de canaux
Dans des versions précédentes de la librairie FMOD, le simple numéro d'identification d'un canal suffisait pour pouvoir modifier le volume ou bien mettre en pause une chanson.
Depuis FMOD Ex, il y a eu un petit changement : à partir du numéro de canal, on utilise une fonction qui fournit un pointeur vers ce canal. L'idée est restée la même, seule l'implémentation a changé.
Un canal est défini comme étant du type
FMOD_CHANNEL, et la fonction qui permet de récupérer un canal à partir d'un numéro id est
FMOD_System_GetChannel.
Par exemple, si j'ai un objet système
system et que je veux récupérer le canal n°9, il faut faire :
Code : C | FMOD_CHANNEL *channel;
FMOD_System_GetChannel(system, 9, &channel);
|
Rien de plus simple !
- Le premier paramètre est l'objet système.
- Le deuxième est le numéro id du canal.
- Le troisième est l'adresse du pointeur où l'on veut stocker l'information voulue.
Une fois qu'on aura notre pointeur de canal, on pourra facilement manipuler la musique (modifier le volume, mettre en pause…).
Notez qu'on peut aussi récupérer tout un groupe de canaux en un seul pointeur ; ça évite de refaire la même manipulation pour chaque canal distinct.
Le type d'un groupe de canaux est
FMOD_CHANNELGROUP, et une des fonctions qui nous intéresse le plus est
FMOD_System_GetMasterChannelGroup, car elle permet d'obtenir un pointeur vers la totalité des canaux utilisés par un objet système.
Le mode de fonctionnement de cette fonction est identique à la précédente.
Modifier le volume
Pour modifier le volume, on peut le faire soit pour un canal précis, soit pour tous les canaux.
Par exemple, pour le faire pour tous les canaux, il faut d'abord récupérer un pointeur vers le groupe de canaux, puis utiliser la fonction
FMOD_ChannelGroup_SetVolume dont le prototype est :
Code : C | FMOD_RESULT FMOD_ChannelGroup_SetVolume(
FMOD_CHANNELGROUP * channelgroup,
float volume
);
|
Le paramètre
channelgroup est celui qu'on vient de récupérer.
Le paramètre
volume est du type
float, tel que 0.0 correspond au silence, et 1.0 correspond à une lecture pleine puissance (c'est cette valeur qui est par défaut).
Répétition de la chanson
On a souvent besoin de répéter la musique de fond. C'est justement ce que propose la fonction
FMOD_Sound_SetLoopCount. Elle prend 2 paramètres :
- Le pointeur vers la chanson.
- Le nombre de fois qu'elle doit être répétée. Si vous mettez 1, la chanson sera donc lue deux fois. Si vous mettez un nombre négatif (comme -1), la chanson sera répétée à l'infini.
Avec ce code source, notre musique sera donc répétée à l'infini :
Code : C | FMOD_Sound_SetLoopCount(musique, -1);
|
Pour que la répétition fonctionne, il faut envoyer FMOD_LOOP_NORMAL en troisième paramètre de la fonction FMOD_System_CreateSound.
Mettre en pause la chanson
Il y a ici 2 fonctions à connaître :
- FMOD_Channel_GetPaused(canal, &etat) : indique si la chanson jouée sur le canal indiqué est en pause ou pas. Elle met vrai dans etat si la chanson est en pause, faux si elle est en train d'être jouée.
- FMOD_Channel_SetPaused(canal, etat) : met en pause ou réactive la lecture de la chanson sur le canal indiqué. Envoyez 1 (vrai) pour mettre en pause, 0 (faux) pour réactiver la lecture.
Ce bout de code de fenêtre SDL met en pause la chanson si on appuie sur la touche
P du clavier, et la réactive si on appuie à nouveau sur
P.
Code : C 1
2
3
4
5
6
7
8
9
10
11
12 | case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_p) // Si on appuie sur P
{
FMOD_BOOL etat;
FMOD_Channel_GetPaused(canal, &etat);
if (etat == 1) // Si la chanson est en pause
FMOD_Channel_SetPaused(canal, 0); // On enlève la pause
else // Sinon, elle est en cours de lecture
FMOD_Channel_SetPaused(canal, 1); // On met en pause
}
break;
|
Si on veut appliquer le même traitement à tous les canaux réunis, on utilisera les fonctions
FMOD_ChannelGroup_GetPaused et
FMOD_ChannelGroup_SetPaused, à la seule différence qu'il faut faire passer comme paramètre un
FMOD_CHANNELGROUP au lieu d'un
FMOD_CHANNEL.
Stopper la lecture
Il suffit d'appeler
FMOD_Channel_Stop pour stopper une musique sur un canal, ou bien
FMOD_ChannelGroup_Stop pour un ensemble de canaux. On leur envoie respectivement le pointeur vers le canal ou bien le pointeur vers le groupe de canaux.
Et bien d'autres choses
On peut faire beaucoup d'autres choses, mais je ne vais pas vous les énumérer toutes ici, autant lire la doc ! Je vous invite donc à y jeter un œil si vous cherchez des fonctions supplémentaires.
Libérer la mémoire
Pour décharger la musique de la mémoire, appelez
FMOD_Sound_Release et donnez-lui le pointeur.
Code : C | FMOD_Sound_Release(musique);
|
Code complet de lecture du MP3
Le code ci-dessous vous montre un programme jouant la musique « Home » qu'on a récupérée sur Jamendo.
La musique est jouée dès le début du programme. On peut la mettre en pause en appuyant sur
P.
Code : C 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83 | #include <stdlib.h>
#include <stdio.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <fmodex/fmod.h>
int main(int argc, char *argv[])
{
SDL_Surface *ecran = NULL, *pochette = NULL;
SDL_Event event;
SDL_Rect position;
int continuer = 1;
FMOD_SYSTEM *system;
FMOD_SOUND *musique;
FMOD_RESULT resultat;
FMOD_System_Create(&system);
FMOD_System_Init(system, 1, FMOD_INIT_NORMAL, NULL);
/* On ouvre la musique */
resultat = FMOD_System_CreateSound(system, "hype_home.mp3", FMOD_SOFTWARE | FMOD_2D | FMOD_CREATESTREAM, 0, &musique);
/* On vérifie si elle a bien été ouverte (IMPORTANT) */
if (resultat != FMOD_OK)
{
fprintf(stderr, "Impossible de lire le fichier mp3\n");
exit(EXIT_FAILURE);
}
/* On active la répétition de la musique à l'infini */
FMOD_Sound_SetLoopCount(musique, -1);
/* On joue la musique */
FMOD_System_PlaySound(system, FMOD_CHANNEL_FREE, musique, 0, NULL);
SDL_Init(SDL_INIT_VIDEO);
ecran = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
SDL_WM_SetCaption("Gestion du son avec FMOD", NULL);
pochette = IMG_Load("hype_liesandspeeches.jpg");
position.x = 0;
position.y = 0;
while (continuer)
{
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = 0;
break;
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_p) //Si on appuie sur P
{
FMOD_CHANNELGROUP *canal;
FMOD_BOOL etat;
FMOD_System_GetMasterChannelGroup(system, &canal);
FMOD_ChannelGroup_GetPaused(canal, &etat);
if (etat) // Si la chanson est en pause
FMOD_ChannelGroup_SetPaused(canal, 0); // On enlève la pause
else // Sinon, elle est en cours de lecture
FMOD_ChannelGroup_SetPaused(canal, 1); // On active la pause
}
break;
}
SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0));
SDL_BlitSurface(pochette, NULL, ecran, &position);
SDL_Flip(ecran);
}
FMOD_Sound_Release(musique);
FMOD_System_Close(system);
FMOD_System_Release(system);
SDL_FreeSurface(pochette);
SDL_Quit();
return EXIT_SUCCESS;
}
|
Histoire d'avoir autre chose qu'une fenêtre noire, j'ai mis la pochette de l'album en image de fond.
Pour apprécier pleinement le résultat, je vous invite à regarder la vidéo du programme en cours d'exécution.