Cook up a Storm with WinUI 3.0

The Sound of Coding

Alright, fellow coders and kitchen maestros, today we are going to bake a melodious cake with our code. Ever wondered how to play your own delightful sounds in your app? Well, let's whip up a batch of sweet notes!

To explain this in our culinary terms, think of MediaPlayer as our new baking tool and the sound file as a key ingredient that adds a unique flavor to our app. This tool can play a variety of sound formats, including WAV files, giving you the power to customize the user experience.

So let's move to the key ingredient of our recipe - the sound file. First, we need to add it to our project. In the context of Visual Studio, these files are often referred to as "Assets". These can be images, sound files, or any other content that is part of your application.

Adding a new asset is like shopping for a rare spice. We want some free sound effects to play with. Luckily, Aarni Koskela has made some CC0-license files available on Github link. Go to the provided Github link, download the 'Polite.wav' sound file (or whichever you'd like), and add it to your project's Assets folder. Now we're ready to bake that cake!

winui-3-basics-5-asset-folder

A project's Assets folder is a place to store additional files like images, icons, or other resources needed for the project. To add files to the Assets folder, you can right-click on the folder in the Solution Explorer, choose "Add," and then select the files you want to add. Or just drag and drop the file from the File Explorer over the folder.

Having the WAV file in your Assets folder, you need to make sure it's included in your app when you build it. Here's how:

  1. Click on the WAV_Polite.wav file in the Solution Explorer to select it.
  2. Locate Properties window (usually below Solution Explorer). If you can't see it, open it from View > Properties Window or press F4 on you keyboard.
  3. Find "Build Action" and set it to "Content".
  4. Also, find "Copy to Output Directory" and set it to "Copy if newer". winui-3-basics-5-build-action

By default, Visual Studio doesn't set those properties to avoid including unnecessary files in the app. It helps keep the app size smaller and makes it faster to build. But we need to set them for important files so they're included and copied correctly when the app is built.

These settings will make sure the file is included in your app and copied to the right place when you build it.

Everything Happening At The Same Time

Next, let's create a method that plays our sound file. Here we use a couple of new things. Normally in programming, one thing happens after the next, and we'll only move to the next bit after the first thing is done. But is different. Async comes from the word asynchronous, which basically means that things can happen at the same time. And when you use in a method, you have to tell the method that it's going to be "async".

C#
public async void PlayNotificationSound()
{
}

Async and await are used in programming to handle tasks that may take some time to complete, like loading files. They help to make programs not freeze up while they're waiting. Think of it like marinating meat before cooking. You might marinate it for 10 hours and continue with other tasks while waiting. When the meat is ready, the "await" tells you it's completed marinating and you can move on to cooking it.

C#
public async void PlayNotificationSound()
{
    StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/WAV_Polite.wav"));
}

In this step, we're gathering our ingredients. The StorageFile acts as a container for our sound file. It fetches our WAV file from the Assets folder. This is like asking a buddy to fetch a can of tomatoes from the store. But because we used the "await", we can continue doing something else while he's gone.

GetFileFromApplicationUriAsync is a way to get a hold of a file in a Windows app using its location. A URI is like a special address that points to something, for example a web address or the address of a file on your computer. ms-appx:/// is what we use at the start of a URI when we want to use the app resources. We use them to easily find and use files in our app, like pictures or sounds.

Honk, Honk! Here Comes the Sound!

Next, we need our new gadget, the MediaPlayer. It's a tool specifically designed to handle sounds in your application. In other words, we can tell it to play a sound, and it just plays it!

C#
MediaPlayer player = new MediaPlayer();
player.Source = MediaSource.CreateFromStorageFile(file);

After the MediaPlayer is initialized, we're telling it what sound to play. To do this, we create a MediaSource from our sound file. Why can't we just play the sound file directly? Well, it's a bit complicated.

Different sound files (like MP3, OGG, WAV) each may have different requirements for decoding and playback. Each source (local, online, streaming) might have different protocols or mechanisms to access the media. Typically, a media player app or browser takes care of all of this. But we're not using those applications. We're using our own application. Not to worry! We can use MediaSource and tell it to take care of decodings and protocols and all that so that we can focus on what matters.

So, when we have created the MediaSouce, we can set it as the source for the player.

C#
player.Play();

Lastly, we tell the MediaPlayer to Play() the sound. Voilร ! Your app now has a distinct sound that plays whenever you call PlayNotificationSound.

Let's put it to a test and call the method at the end of ShowToastNotification.

C#
public void ShowToastNotification(string title, string content)
{
    // ... Other code
    PlayNotificationSound();
}

When the toast notification pops up, you should hear your selected sound file play back. Don't forget to unmute your computer in Windows!

You can always enhance your user's experience with the right mix of code ingredients. Don't be afraid to experiment. After all, you're the chef in your code kitchen! Just be careful not to bombard your user with constant noise. Sound notifications should be the garnish, not the main dish.