SOMMAIRE |
Texel |
|
Lecture d'un fichier audio
Nous allons voir, dans ce tutorial, la manière la plus simple de lire un fichier wave ou midi. Pour ces deux types de fichiers le programme est exactement le même. Vous pouvez télécharger le code source de ce programme ICI.
Ce tutorial (fortement inspiré de celui du SDK 8) a été écrit dans le but d'expliquer la manière de lire un fichier wave. Notez bien que si vous voulez vraiment exploiter les capacités de DirectMusic pour la lecture de fichier midi, ce tutorial vous sera nécessaire mais insuffisant. En effet, avec la méthode présenter ici, la lecture des fichiers midi se fait avec les sons standards du synthétiseur standard de Microsoft ( Microsoft Software Synthetizer ). Un synthétiseur transforme la musique midi en son wave à partir d'une bibliothèque de son (pour les différents instruments). 1. L'initialisation Pour commencer, on n'oublie pas de rajouter la ligne #define INITGUID pour les interfaces COM avant d'inclure les deux headers dont on a besoin: dmusicc.h et dmusici.h. Puis on déclare en variable globale trois objets pour les trois interfaces dont on a besoin et que l'on initialise à NULL:
L'interface IDirectMusicLoader8 contient les méthodes pour charger le fichier audio dans un objet IDirectMusicSegment8 qui va le stocker (Mais en réalité, il est stocké dans un buffer grâce à un objet de type IDirectSoundBuffer8). Si vous utilisez plusieurs sons dans votre application, vous devez charger chaques sons dans une interface IDirectMusicSegment8 différente.
L'interface IDirectMusicPerformance8 possède des méthodes pour la lecture des sons stockés dans l'interface IDirectMusicSegment8.
Ensuite, il faut initialiser l'objet COM de DirectMusic. Si vous connaissez DirectDraw, vous devez vous attendre à utiliser une fonction du genre DirectMusicCreateEx. Et bien cette fonction n'existe pas. En plus, vous avez peut-être remarquer que nous n'avons pas déclarés d'objet IDirectMusic. En faite, il va être créé automatiquement (Idem pour l'objet DirectSound) par la méthode InitAudio, mais il nous faut quand même appeler la fonction CoInitialize pour initialiser la librairie COM:
Nous avons déclarés en variables globales trois interfaces. Il nous faut obtenir des pointeurs vers deux d'entre elles par une fonction COM de la façon suivante:
Ce n'est pas très important de connaître la signification de tous les arguments de CoCreateInstance. C'est du model COM, donc compliqué. Ne vous intéressez qu'au premier et aux deux derniers. Recopiez les autres.
Le premier argument est "l'identifiant de la classe de l'objet". Comme vous le voyez, il commence par CLSID et finit par le nom de l'interface que l'on veut avoir. L'avant dernier argument est l'identificateur GUID de l'interface. Le dernier argument est l'objet que nous avons déclaré. Maintenant il ne nous reste plus qu'à initialiser l'interface IDirectMusicPerformance8 et le synthétiseur par sa méthode InitAudio:
Les deux premiers arguments sont les adresses d'interfaces IDirectMusic et IDirectSound. DirectMusic s'appuie en effet sur DirectSound pour jouer le son. Si ces arguments sont NULL, des interfaces sont automatiquement créées en interne sans que vous ayez à vous en occuper. Le troisième argument est l'handle de la fenêtre principale de l'application (notre programme d'exemple n'en a pas). Le quatrième argument définit la voie audio (ou chemin audio) que l'on souhaite avoir. Cette voie mène vers un buffer (tampon). Avec les drapeaux suivants, on choisit une voie vers le type de buffer que l'on souhaite:
La réverbération est conseillé pour les musiques (Les sons paraissent moins vides). Il peut y avoir plusieurs voies audio dans un programme. Ce qui permet d'avoir des buffers de type différent avec des effets différents. On peut ensuite décider sur quelle voie audio on désire jouer un son. Pour créer des voies audio supplémentaires en plus de celles crées ici par défaut, il faut obtenir un pointeur vers une interface IDirectMusicAudioPath8. Nous verrons comment le faire dans le tutorial sur le son dans l'espace.
Le cinquième paramètre est le nombre maximal de canaux qui peuvent être utilisés. Un son wave a un seul canal. Les musiques midi en on besoin de plus de 16. Ils permettent à plusieurs instruments différents de jouer en même temps. Le sixième argument définit les capacités du synthétiseur comme la gestion de la 3D ou de l'EAX . Le drapeau DMUS_AUDIOF_ALL permet d'utiliser tous les effets. Le dernier argument définit encore des paramètres, mais NULL suffit dans la majorité des cas. L'initialisation est terminer, il faut maintenant charger le fichier audio. 2. Chargement du fichier audio
Le chargement du fichier audio va le mettre en mémoire pour qu'il puisse être disponible lorsque l'on aura besoin de le lire. Ce qui suit n'est donc à effectuer qu'une seul fois (au démarrage de l'application ou du niveau d'un jeux).
Comme je vous l'ai dit précédemment, c'est par l'interface IDirectMusicLoader8 que l'on charge le fichier dans l'interface IDirectMusicSegment8. La méthode utilisée est LoadObjectFromFile :
Les deux premiers arguments sont les identificateurs COM pour l'interface IDirectMusicSegment8.
Le troisième argument est le nom du fichier à charger. Le préfixe "L" convertit la chaîne de caractère de l'ASCII vers une chaîne de caractère étendue. Le dernier argument est l'adresse de l'interface qui reçoit le pointeur. Ensuite, les données wave du son wave ou les données wave des instruments de la musique midi doivent être téléchargées de l'interface IDirectMusicSegment8 à l'interface IDirectMusicPerformance8 par la méthode download de la première interface:
3. Lecture et arrêt La lecture et l'arrêt du fichier audio se font par deux méthodes de l'interface IDirectMusicPerformance8. Pour la lecture:
Le premier argument est le segment à jouer. Le deuxième argument est toujours à NULL. Le troisième argument permet de faire des transitions entre les sons. Consultez la documentation du SDK pour plus d'information. Le quatrième argument est un drapeau qui définit la manière dont sera joué le son. Voici deux exemples de drapeaux, pour les autres consultez la documentation: DMUS_SEGF_SECONDARY permet la lecture de plusieurs sons en même temps. Le nouveau son est alors lut en segment secondaire. En effet, les segments sur lesquelles sont chargés les sons peuvent être joués en segment primaire ou secondaire. Il ne peut exister qu'un seul segment primaire. Mais il peut y avoir plusieurs segments secondaires. Si vous n'utilisez pas de segment secondaire, vous ne pouvez pas jouer plusieurs sons à la fois. Donc si vous n'utiliser pas ce drapeau pour jouer un nouveau son lorsqu'un son est déjà en cours de lecture, ce dernier s'arrêtera pour permettre la lecture du nouveau son. DMUS_SEGF_QUEUE permet d'ajouter le nouveau son que l'on désire jouer à la fin du segment primaire. Le nouveau son ne sera joué qu'après la fin de la lecture du son précédent du segment primaire. Le cinquième argument sert apparemment à définir à quel instant on souhaite jouer le son. Je n'ai pas encore eu le temps de voir comment ça marche alors on passe à la suite. Le sixième argument est l'adresse d'une interface IDirectMusicSegmentState8 qui contient l'état d'un segment. Consultez la documentation pour plus d'information. C'est pas très utile donc on le met à NULL. Le septième argument est un segment ou une voie audio à stopper lorsque le nouveau segment est joué. Si l'argument est une voie audio, tous les sons joués sur cette voie sont stoppé. Si on n'a rien à stopper on utilise NULL. Le dernier argument est la voie audio sur laquelle on désire jouer le son. Si l'argument est NULL, on utilise la voie audio par défaut. Pour l'arrêt:
Le premier argument est le segment à stopper. NULL stop tous les segments. Le deuxième argument est le segment d'état à stopper. Les deux derniers arguments servent à stopper le son à des dates définis un peut comme le cinquième argument de PlaySegmentEx. Mettez les à zéro pour stopper le son immédiatement. Pour la répétition: Pour répéter un son plusieurs fois, il suffit d'utiliser la méthode SetRepeats de L'interface IDirectMusicSegment8 à partir du segment à répéter.
L'unique argument de cette fonction est le nombre de fois que le son doit être répété ou bien le drapeau DMUS_SEG_REPEAT_INFINITE pour répéter le son en boucle. 4. Fermeture de l'application Comme toujours avec les librairies DirectX, il faut libérer les interfaces avant la fermeture du programme.
Avant d'utiliser la méthode Release pour les trois interfaces que l'on a créer, il faut utiliser la méthode CloseDown de l'interface IDirectMusicPerformance8:
Puis, il faut déinitialiser la librairie COM par la fonction suivante:
Conclusion: Comme vous le voyez, l'utilisation de DirectX Audio est très simple. Le fichier dmutil.cpp disponible avec son header dans le SDK simplifie encore plus son utilisation grâce des classes en C++ (répertoire samples\multimedia\common). Jetez-y un coup d'œil. Il est facile d'utiliser des classes C++ même si l'on ne connaît pas ce langage (on peut même comprendre une grande partie des sources). |