Lancez du son comme un pro avec UWP !

Vous avez besoin de jouer une mélodie en boucle ou des bruits de lasers pour votre jeu ou votre application orientée son ? Vous ne savez pas comment faire en UWP ? Cet article est fait pour vous !

Pour commencer, il est possible de jouer des sons avec MediaPlayerElement mais ce n’est pas vraiment la solution idéale car il faudra stocker autant d’instance de MediaPlayerElement que de sons. De plus il y a souvent un petit délai lorsque l’on lance le son avec ce contrôle. On préférera donc une solution plus professionnelle.

Au début d’UWP, la manipulation du son, s’effectuait via une librairie en C++ pas toujours très simple d’accès : XAudio2. Heureusement, Microsoft, a penser aux développeurs C# en ajoutant AudioGraph dans sa boite à outils.

Cette classe permet d’ouvrir des fichiers audio au format mp3, wav, wma et m4a.

AudioGraph permet de créer des noeuds d’entrée (en général par le biais de fichier audio) que l’on peut associer à des noeuds de sortie (carte son ou fichier audio de sortie). Il est également possible de mixer différents noeuds d’entrées. Ce n’est pas très compliqué mais c’est assez verbeux en terme d’écriture.

Pour simplifier l’accès à cette classe je viens d’écrire une petite librairie permettant de faire le travail pour vous (hourra !) : AudioPlayer

Les bases

Avant tout de chose on va créer une instance de de la class AudioPlayer. AudioPlayer permet d’associer un fichier audio à une clé pour faciliter son stockage. Comme AudioPlayer est très souple d’utilisation, vous pouvez lui fournir le type de clé que vous souhaitez (entier, string, …) . Par exemple j’aime bien utiliser des enums comme clé représentant mes sons (AudioKeys), AudioPlayer sera donc déclaré ainsi :

// key for the sound dictionnary of the AudioPlayer
enum MyAudioKeys
{
   Loop,
   Connected,
   Connected10Channels
}

AudioPlayer<MyAudioKeys> audioPlayer = new AudioPlayer<MyAudioKeys>();

On pourra ensuite l’initialiser :

await audioPlayer.InitializeAsync();

Et enfin ajouter des sons associé à nos clés :

await audioPlayer.AddSoundFromApplicationAsync(MyAudioKeys.Loop, "ms-appx:///Assets/Sounds/Loop.wav");

await audioPlayer.AddSoundFromApplicationAsync(MyAudioKeys.Connected, "ms-appx:///Assets/Sounds/Connected.wav");

Il est possible d’ajouter des son à partir d’un StorageFile (méthode AddSoundAsync) ou, comme dans l’exemple, d’une uri absolue pointant vers un fichier dont l’action de génération est “Content” (méthode AddSoundFromApplicationAsync).

Un son peut être retiré d’AudioPlayer avec la méthode RemoveSound associé à sa clé. RemoveSound peut être appelé également sans clé si vous désirez retirer l’ensemble des sons de la librairies. Si vous n’avez plus besoin de son dans votre application, c’est une bonne pratique d’appeler RemoveSound qui disposera correctement les noeuds d’entrée utilisées dans AudioPlayer.

Let’s play !

Pour jouer les sons que vous avez préalablement stockés à l’aide de la clé vous avez le choix entre trois méthodes :

  • PlayLoop : vous permet de jouer un son en boucle.
  • PlaySound : Vous permet de jouer un son immédiatement, sans attendre sa fin.
  • PlaySoundAsync : Vous permet également de jouer un son mais en attendant sa fin.
audioPlayer.PlayLoop(MyAudioKeys.Loop);
audioPlayer.PlaySound(MyAudioKeys.Connected);
await audioPlayer.PlaySoundAsync(MyAudioKeys.Connected);

Si vous testez la démo fournit avec la librairie vous constaterez que lorsque vous lancer le son ‘Connected’, par exemple, puis relancer quelques secondes après ce même son, alors qu’il continue toujours de jouer, il sera stoppé pour être joué de nouveau. Malheureusement, ce n’est pas toujours le comportement souhaité. C’est particulièrement le cas dans les jeux de tir ou chaque coup de feu nécessite un nouveau canal sonore. Normalement ce comportement n’est pas supporté par AudioGraph mais AudioPlayer le simule en ajoutant un noeud d’entrée par canal sonore désiré.

await audioPlayer.AddSoundFromApplicationAsync(MyAudioKeys.Connected10Channels, "ms-appx:///Assets/Sounds/Connected.wav", 10); // 10 canaux de rajoutés

audioPlayer.Play(MyAudioKeys.Connected10Channels); // le son peut être simultanément joué 10 fois sans être interrompu.

Pump up the volume !

Il est possible de fixer individuellement le volume du son à jouer en rajoutant un paramètre volume sur les méthodes Play. La valeur du volume est normalisée de 0 à 1 (un volume de 50% sera exprimé par 0.5).

// Play with a 50% volume 
audioPlayer.PlaySound(MyAudioKeys.Connected, 0.5);

Le volume peut être également ajusté via la méthode SetVolume

audioPlayer.SetVolume(MyAudioKeys.Loop, 0.25);

Un volume global peut être également fixé via la propriété Volume de AudioPlayer

audioPlayer.Volume = 0.75;

Il est parfois pratique de pouvoir coupez globalement le son de l’application en conservant le volume d’origine. C’est possible par le biais de la propriété IsMute et de la méthode SwitchMute qui passe d’un état à un autre.

// passe le volume général à 75%
audioPlayer.Volume = 0.75;
// coupe le volume
audioPlayer.IsMute = true;
// remet le volume à 75%
audioPlayer.SwitchMute();

Stop !

pour stopper un son en train d’être joué, il suffit d’appeler la méthode Stop avec la clé du son qui doit être stoppé.

audioPlayer.Stop(MyAudioKets.Loop); // Arrête la mélodie joué en boucle

Il également possible d’arrêter tous les sons en train d’être joués.

audioPlayer.Stop();

Conclusion

Vous avez maintenant toutes les clés en main pour gérer parfaitement l’environnement sonore de vos applications et de vos jeux.

Vous pouvez trouver le code de la librairie AudioPlayer et un exemple de fonctionnement sur GitHub :

https://github.com/samoteph/AudioPlayer

Leave a Reply

Your email address will not be published. Required fields are marked *