Part 21: Permanently Saving the Audio Wav File

Part 21: Permanently Saving the Audio Wav File

Update: 2013-06-26
Share

Description

Source Code: https://aka.ms/absbeginnerdevwp8
PDF Version: https://aka.ms/absbeginnerdevwp8pdf

At this point, we are recording audio and saving it to a temp file on the app's IsolatedStorage. Next, we need to allow the user to permanently save the sound providing details like the display name for the new custom sound.

The game plan:

  1. Add an event handler method to the "save" application bar button
  2. We'll manage the state of the application bar ... it should only be visible if a temporary audio file has been created and is ready to be saved permanently
  3. We'll use the Coding4Fun Toolkit once again, this time to display an InputDialog to capture the name of the new custom sound audio file
  4. We'll serialize the data for the CustomSounds into a JSON file
  5. And we'll modify our data model to also load the CustomSounds JSON file to create new instances of the data model for those custom sounds

 

1. Add an event handler method to the "save" button and manage application bar state

Earlier we created the application bar for the RecordAudio.xaml page by enabling the BuildLocalizedApplicationBar() method. So all we need to do is make it active:

Generic Episode Image

 

  1. In line 43 I add an event handler to the Click method using the technique we've utilized throughout this series ... while we're at it, use the other technique I've demonstrated to generate a method stub for the SaveRecordingClick method (hover-mouse-over-blue-dash to reveal an Intellisense menu option to generate the method stub)
  2. In line 46 I immediately hide the application bar ... we only want to show it when we have a sound to save (after the user records a custom sound)

Next, we'll enable the application bar after the user stops recording. In the RecordAudioUnchecked() method, we'll set the IsVisible property to true (see line 67, below):

Generic Episode Image

 

2. Use the Coding4Fun Toolkit to display an InputDialog to capture the name of the new custom sound audio file

In the previous step we added a method stub for the SaveRecordingClick() method.

Generic Episode Image

I'll replace the line of code that throws an exception as a reminder and write the following (line 51, below):

Generic Episode Image

Since the InputPrompt is from a different namespace than the others we've utilized so far, we'll need to add a using statement (using the hover-over-the-blue-dash method to reveal the contextual menu).

Next we'll configure and show the InputPrompt:

Generic Episode Image

  1. Here we set the Title and Message we want to appear in the InputPrompt
  2. We attach an event handler method (and generate the method stub using techniques I've demonstrated before) to the Completed event ... we'll tackle that in the next step
  3. Once configured, I show the dialog

When the user types in a name for the new custom sound and clicks the checkmark button, the FileNameCompleted() event handler method will fire.

Generic Episode Image

 

We'll ensure that the InputPrompt was exited properly by the user by checking the result. We'll check the PopUpResult that was sent into this event handler method as an input parameter. If the result is "OK" then we can perform the logic necessary to save the temporary file as a new "permanent" sound. See the code I added below, as well as the code comments which give me an outline of the "next steps" I'll want to perform:

 

Generic Episode Image

 

  1. If the user correctly typed in a new name and clicked the checkmark button to exit the InputDialog, then we'll perform the tasks required to save the custom sound and make it available in the Custom Sounds view of the Sound Board.
  2. Finally, we'll navigate back to the MainPage.xaml

Between callouts 1 and 2, above, are an outline of what needs to happen in order for this to work correctly. Before we attempt to implement those ideas, let's make sure the flow works as we would expect so far by running the application.

I record a custom sound by using the ToggleButton. When I stop recording, I in fact see the application bar appear:

 

Generic Episode Image

 

When I click the disk icon to save the custom sound, it displays the InputDialog:

 

Generic Episode Image

 

And when I type in a new sound name and click the checkmark icon, the dialog disappears and returns me to the MainPage.xaml. Great!

Now, for the hard part ... we'll perform those tasks I outlined in the code comments.

 

3. Save the sound file into a permanent IsolatedStorage area, serialize the data for the CustomSounds into a JSON file

At this point we have a custom sound recorded and stored as a temporary file and we've just collected a friendly display name for that sound. We want to accomplish two basic tasks:

  1. First, we want to add the custom sound to our data model. If information about our new custom sound is never added to the data model, then we'll never be able to render it to the Custom Sounds view on our MainPage.xaml. So, we'll create a new instance of the SoundData class and fill in the FilePath and Title properties appropriately.
  2. Next, we'll want to move that file from its temporary location to a permanent subfolder called /customAudio/ ... this is purely to keep all our custom sound files organized in one place.

So, I add the following code to the FileNameCompleted() method:

 

Generic Episode Image

 

  1. I create a new instance of SoundData and fill in the Title and FilePath attributes. Notice that we'll be giving our custom sound a new name, but the contents of the file will remain the same.
  2. Just like when we originally recorded the custom sound, we get a reference to the IsolatedStorage area specifically for our app. We do this with a using statement to properly let go of unmanaged resources (like the Phone's storage). The very first time this code is executed, it may need to create the special folder where we're storing our custom audio files (line 76). Finally, we're moving the temporary file to the new permanent storage area and giving it a new name all in one fell swoop (line 78).
  3. Next, we're adding the new instance of the SoundData class to our CustomSounds.Items collection. At this moment, we should be able to return back to the MainPage.xaml and see the new custom sound appear in the list of Custom Sounds.

However, what will happen when we close the application and it is complete removed from the Phone's memory? When that happens, the CustomSounds.Items collection will be removed from memory and the next time the app is run, it will have no memory of our custom sounds. We need a way to store our custom sounds data so that we can load it into our data model the next time the user runs our app.

 

4. Serialize and deserialize the CustomSounds SoundGroup into / out of Json

To do this, we'll need to serialize our CustomSounds.Items collection into a data format. There are many data formats we could choose, but we'll pick a very popular, light-weight easy to use format called JSON. It is short for the JavaScript Object Notation. It will allow us to easily represent our collection as JavaScript objects. If we utilize a third-party open source library called Json.NET, we won't even have to think about the data's format ... much of that complexity will be hidden behind simple method calls.

To begin, we'll open up the NuGet Package Manager (using the technique I demonstrated earlier ... right-click the References folder and choose the Manage NuGet Packages ... option.

Generic Episode Image

 

  1. Search for: Json ... one of the top options should be Json.NET.
  2. Click the Install button next to the Json.NET package. It will take a few moments to install that package into your project.
  3. Click the Close button to continue.

To verify that Json.NET was installed successfully, open up the References folder in the SoundBoard project and verify that Newtonsoft.Json appears there:

 

Generic Episode Image

 

Back in the FileNameCompleted() method, the next step is to convert the CustomSounds.Items collection to Json, then store it to disk.

We'll use the Newtonsoft.Json.JsonConvert class to perform the conversion ... you'll need to add the appropriate using statements to acc

Comments 
00:00
00:00
x

0.5x

0.8x

1.0x

1.25x

1.5x

2.0x

3.0x

Sleep Timer

Off

End of Episode

5 Minutes

10 Minutes

15 Minutes

30 Minutes

45 Minutes

60 Minutes

120 Minutes

Part 21: Permanently Saving the Audio Wav File

Part 21: Permanently Saving the Audio Wav File

Bob Tabor, Clint Rutkas