Part 21: Permanently Saving the Audio Wav File

Play Part 21: Permanently Saving the Audio Wav File
Sign in to queue

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 accommodate the JsonConvert class:

 

Generic Episode Image

 

Now we're ready to fully implement the storage of the CustomSounds Json file to disk.

 

Generic Episode Image

 

  1. We use the JsonConvert.SerializeObject() method to serialize the CustomSounds object (and all it's children, etc.) into Json
  2. We'll use a special area of IsolatedStorage called IsolatedStorageSettings to save this object data. This is a simple way to save settings for your app. You can use the name / value pair pattern to save any settings you like for your app. So, in our case, we'll create a key and supply the value ... the value part is obviously the data -- the serialized Json data from the previous line of code. The key part will be a literal string that we'll create as a constant property in the SoundModel class definition. We'll need that key later to RETRIEVE the Json data back out of the IsolatedStorageSettings (we'll do that later in this lesson).
  3. We'll call the Save() method to actually save our new ApplicationSetting, the new name / value pair we created in the previous line of code.

Before we forget, let's implement that CustomSoundKey ... in the SoundModel.cs file, I'll add the following line of code (line 19, below):

 

Generic Episode Image

 

As you can see, this is nothing more than a constant string value. We want it to be constant because it should never change. It's simply a unique string we'll use as the means of getting back at the right ApplicationSetting in the IsolatedStorageSettings store.

Next, we'll want to load our custom sounds into memory at the same time we instantiate all of the other SoundGroup objects ... in the SoundModel.cs file, in the LoadData() method:

 

Generic Episode Image

 

In line 28 (above) we'll call a helper method, LoadCustomSounds(), to populate the CustomSounds property of the SoundModel class. Use the technique I demonstrated earlier to generate a method stub for this new method.

In our new LoadCustomSounds() method, we'll attempt to retrieve the Json that contains the serialized Custom Sound data from the IsolatedStorageSettings:

Generic Episode Image

 

  1. We perform a TryGetValue() method on the IsolatedStorageSettings.ApplicationSettings ... if the CustomSoundKey exists in IsolatedStorage, then it should return the value (i.e., the Json we stored previously) into the out parameter, "dataFromAppSettings". If not, then the else code block will create a new (empty) instance of SoundGroup.
  2. Now that we have the serialized data, we want to DESERIALIZE that data back into instances of SoundGroup (and SoundData) objects. We call the generic DeserializeObject<T>() method, giving it the type we expect to deserialize it into (i.e., SoundGroup) and pass in the data we retrieved from the IsolatedStorageSettings.
  3. Assuming the TryGetValue failed, that means no custom sounds were created (or perhaps there was a problem retrieving the data). In either case, return an empty SoundGroup.

Now we cross our fingers and test the app. I'll record a sound and attempt to save the sound with the name "another test".

 

Generic Episode Image

 

All looks good until I return to the MainPage.xaml after I've saved the new custom sound and attempt to play it. However, it doesn't play back! That's because we need to modify the playback code on the MainPage.xaml to load CustomSounds FROM THE NEW FOLDER! It only loads from the /Assets folder right now!

The goal is to set the MediaElement's Source property with the correct location of the sound file associated with the tile our user tapped. We'll look in one of two places ... either in the /Assets folder, or in the IsolatedStorage area.

In the MainPage.xaml.cs, in the LongListSelector_SelectionChanged() event handler method I add the following:

 

Generic Episode Image

 

Here I'm attempting to see if the tile selected by the user is a custom sound. If we can't locate the file name associated with the tile in the Assets\ folder, then we'll look for it in the /customSounds/ sub-folder where in the app's IsolatedStorage area.

For this check, we'll need to access the file system of the Phone, so we'll use the System.IO.File object. The screenshot above shows how we will want to add the appropriate using statement at the top of the code file to include System.IO.

Additionally, we'll want to include a reference to System.IO.IsolatedStorage since we'll be working with classes in that namespace next:

 

Generic Episode Image

 

Back in the LongListSelector_SelectionChanged() event handler method, the File.Exists() will return false if the SoundData object's FilePath cannot be found in the default location. Otherwise it will be in the /Assets folder. So, based on that I write the following code:

 

Generic Episode Image

 

  1. Here I am setting the MediaElement's Sound property like before using the SoundData's FilePath property
  2. In this case, the file was not in the /Assets folder so we'll search for it in IsolatedStorage. Here we create a reference to the IsolatedStorage for our app. Note the using statement so that we can properly dispose of this resource when we're finished.
  3. Here we get access to the file using a new technique. We're opening the custom sound as a stream, or more specifically, a IsolatedStorageFileStream. More about streams in a moment.
  4. Here we use the SetSource property of the MediaElement to the stream containing our custom sound from IsolatedStorage.

This time when we run the app, record and save a sound, then return to the "mine" (Custom Sounds) category, each of our saved custom sounds should play correctly!

 

Generic Episode Image

 

Recap

To recap, the big take aways from this lesson were Serializing and Deserializing objects into JSON using Newtonsoft Json, which is a very valuable skill that transcends Phone development. We also learned how to work with IsolatedStorage, particularly the IsolatedStorageSettings to store name / value pairs. We used the System.IO.File class to examine the file system, and learned about working with streams. We also used the InputPrompt from the Coding4Fun Toolkit and a bunch more. We are almost done ... we'll just add one last touch to the app to make it fun to use.

Embed

Download

The Discussion

  • User profile image
    Hieu

    I have this problem and can't find way to solve it:
    When I play a recorded sound twice, the program crashes.

  • User profile image
    BobTabor

    @Hieu: Have you downloaded the source code we supply?  Does THAT crash for you, too?

  • User profile image
    Hieu

    Yes, your source code crashes, too. But I found the solution.

    Just change this line:

    using (var stream = new IsolatedStorageFileStream(data.FilePath, FileMode.Open, storageFolder))

    to this one:

    using (var stream = new IsolatedStorageFileStream(data.FilePath, FileMode.Open, FileAccess.Read, storageFolder))

  • User profile image
    ZhouningMan

    Very informative. Thank you!

  • User profile image
    BobTabor

    @Hieu: Great catch.  Thank you!

    @ZhouningMan: No, thank you!  Smiley

  • User profile image
    QuocTruong

    @Hieu:

    This solution not work for me.

    My solution:

    - Declare "stream" as member of MainPage class.

    - In method LongListSelector_SelectionChanged, if stream != null, I call method Close() to close it.

  • User profile image
    DiegoRico

    @Hieu:

    I noticed the same issue. I tried your proposed solution and it seemed to work. Thanks for the Tip!

    @Bob

    Thank you for helping to create these very informative tutorial videos. They have really been helpful in getting started with programming for the Windows Phone 8 platform. I completed your C# For Absolute Beginners Series and I am now about to begin the second half of this series (#24-35).

  • User profile image
    BobTabor

    @QuocTruong: Did you get this figured out?  Are you still stuck?

    @DiegoRico: Very good ... hope it still is making sense and you're able to follow along.  Please let me know when you get stuck.

  • User profile image
    QuocTruong

    @BobTabor: When I programming with C. I alway remember close a file when open it. I apply this to solved problem "program crash when I play a recorded sound two times".

  • User profile image
    Shinto

    @Hieu The solution worked. Thanks.

  • User profile image
    mohramzan
    Great series
  • User profile image
    Geetha

    I get the following error while installing Json.Net. I tried both v5.0.3 as well as v5.0.6. Both versions give me the same error. Please let me know how to resolve this.

    Install-Package Newtonsoft.Json -Version 5.0.3
    Successfully installed 'Newtonsoft.Json 5.0.3'.
    Successfully uninstalled 'Newtonsoft.Json 5.0.3'.
    Install failed. Rolling back...
    Install-Package : Could not install package 'Newtonsoft.Json 5.0.3'. You are trying to install this package into a project that targets 'WindowsPhone,Version=v8.0',
    but the package does not contain any assembly references that are compatible with that framework. For more information, contact the package author.
    At line:1 char:1
    + Install-Package Newtonsoft.Json -Version 5.0.3
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [Install-Package], InvalidOperationException
    + FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PowerShell.Commands.InstallPackageCommand

  • User profile image
    Clint

    @Geetha: update your nuget package manager.  Do this by going to "Tools->Extensions and Updates" then on the left side of that window, click "Updates"

  • User profile image
    Geetha

    Thanks @Clint. That fixed it.

  • User profile image
    Clint

    @Geetha: Smiley

  • User profile image
    mvpspl619

    I followed everything as it is. And even I see the "Mine" page after adding the JSON code.

    My problem is,

    I don't think the recorded and saved wav file is not linking up to the CustomSounds at all. Even before adding the JSON implementation, it showed up in the video tutorial without any pivot page name. But in my test device(Lumia 720), it did not show up in the empty pivot page between Animals and Warnings. I just thought lets move till the JSON code and see if it works.

    But then in vain, the saved file doesnt show up.

    Can you tell me what might cause this problem so that I can look into it myself ?

    @Clint @BobTabor

  • User profile image
    Clint

    @mvpspl619: Few things here

    • Did you compare our step 21 to your step 21 source code.
    • Are you sure it is being the file is being written to iso (did the file play?)
    • Are you sure you are adding it to your App.ViewModel.CustomSound? (use breakpoints)
    • Did you see what the json output and input is? (use breakpoints)
  • User profile image
    mvpspl619

    @Clint: I solved it.

    It was a previous code problem. In App.xaml.cs while initializing the public ViewModel class, I did not include the initializing of ViewModel to a new SoundGroup element inside the if condition. Now I put it back inside the if condition, it all works.

    Thanks for the resolution anyway Smiley

  • User profile image
    mvpspl619

    While sending the stream data to be played on selection changed event, is it possible to extract the filepath of the custom sound file in application storage to the data.FilePath variable so that we can directly use the if statement to see if the file exists and play it by setting the AudioPlayer source element to data.FilePath even for the custom recorded sounds ??

  • User profile image
    Clint

    @mvpspl619: anything is possible here, I made a design decision of wanting custom names versus file paths.  I also designed this application with beginners in mind, there are things I personally would have done differently but were outside the scope.

    I'm not 100% following what you're saying here as well.  could you pseudo code out what you are proposing?

    What I'd do is create some small proof of concept apps, insert a file into isolated storage at load (I highly suggest using proper terms, storage in this context is Isolated storage (Or Iso Storage for short) and play around with different technics.  This way you can play without all the added complexity of the full program.

  • User profile image
    mvpspl619

    Yes I understand that you designed the app to take custom names. And the filepath is just the timestamp of when the wav file is created.

    Previously I didnot understand what is happening inside the second using method. Now I understand that the stream variable has the audio file that is selected so the AudioPlayer's source attribute is set to stream. So it plays. Everything is clear to me now. Thank you.  Smiley

     

  • User profile image
    Quyen Ha

    I have an error with Navigation Service. For example, after I clicked on one of Animal Sound button, I open AudioPage. Then I click on the back button to perform navigation back to MainPage. It will play audio sound of the button I clicked earlier and open MainPage.What I want is that it will open a new MainPage. I'm trying to get rid of this problem, but no hope. I think we have a way to set the navigationBack to new instant of MainPage. Anyone has any idea ?

  • User profile image
    Clint

    @Quyen Ha: so Soundboard doesn't have an Audio Page.

    However, what you are reporting is a bug in the real application.  This is one of those "what is happening, how do I fix it".

    So what is happening is the Source is still set and we have AutoPlay= true on the media element, _audioPlayer.  When we navigate back, it will automatically play.

    Now, the easy fix is to basically null out the Source on the media element.  On the MainPage.xaml.cs, we just need to adjust the RecordAudioClick method and do just what I stated above, null out the Source

    private void RecordAudioClick(object sender, EventArgs e)
    {
        _audioPlayer.Source = null;
        NavigationService.Navigate(new Uri("/RecordAudio.xaml", UriKind.RelativeOrAbsolute));
    }

  • User profile image
    rfreytag

    @BobTabor, @Clint - thanks again for making this series. 

     

    @QuocTruong - Thanks for pointing out the double-click problem and that one should use FileAccess.Read as a necessary parameter to IsolatedStorageFileStream. 

    I found that I did not need to close the stream (so far) no matter how often I double-clicked so no need to persist it on a parent class nor *.Close() it.  Instead I just called IsolatedStorageFileStream as below. 

    I'm vague on the underlying file and stream access model so if there is a bug lurking here I would appreciate being made wise. 

    MainPage.xaml.cs code follows....

     

    private void LongListSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)

    {         

    var selector = sender asLongListSelector;

    if (selector == null) return;

    var data = selector.SelectedItem asSoundData;

    if (data == null) return;

    if (File.Exists(data.FilePath))

    {

        AudioPlayer.Source =

       newUri(data.FilePath,UriKind.RelativeOrAbsolute);

    }

    else{

        using (IsolatedStorageFile storageFolder = IsolatedStorageFile.GetUserStoreForApplication()){

            using ( IsolatedStorageFileStream stream = new IsolatedStorageFileStream(data.FilePath, FileMode.Open, FileAccess.Read, storageFolder)){

              AudioPlayer.SetSource(stream);

            }

        }

    }

    }

  • User profile image
    Wilfre

    hi @Clint @BobTabor

    I'm having a similar issue. When I record the audio I can't play it back, even before saving it. It was working before we tried to store it permanently. After I save it, it shows on the 'mine' page, but when I click it, it doesn't play back the sound. After the second click, it throws an exception when trying to create the stream object in the second 'using' statement. Any ideas as to where I can look for a fix. I tried passing FileAcces.Read like someone suggested in a comment but that didn't work either.

    Thanks

  • User profile image
    BobTabor

    @Wilfre: Not sure ... would need to parse through the code for a while and see if anything jumped out at me.  Here's the first thing I would do ... grab the source code from https://aka.ms/absbeginnerdevwp8 and compare what you did with what Clint / I did.  Perhaps even back up and re-trace your steps through the video (assuming you can Ctrl+Z or you saved off a previous copy).  Maybe something will jump out at @Clint based on the behavior you're experiencing.

  • User profile image
    Clint
    @Wilfre: just like bob stated, my advise is the same. Chances are there is a very small difference in the file path. I would compare source codes. If that doesn't solve it, upload a zip to the codeplex with a new bug
  • User profile image
    norasabau

    Hi Bob, I managed to follow step by step these series....and I'm so glad. It's an amazing way to learn windows phone development. Awesome job Smiley Very well done, I love the detailed explanations.

    I have a question. Where should I add the "Delete" ....to delete the wav files....near the microphone  icon or as a menu item above "about", or better near the "Save" button?

    Thanks,

    Nora

  • User profile image
    Clint

    @norasabau: I'd do what I tend to recommend and mimic how Windows Phone would do it.  Play with the Photos and you'll see what I'm talking about.  If you press and hold, you get a context menu (http://phone.codeplex.com has this control) and they have a multi-select long list selector to delete multiple photos.

    I would also do this on the page where you have the audio recordings (MainPage.xaml), not the recording page.

  • User profile image
    gauravi

    hi Bob,

    awesome videos.. but i have one issue.. I am not able to play customsounds. it is coming under mine pivot. but i am not able to play

     

  • User profile image
    Clint
    @gauravi: did you check your code against ours? Chances are you are missing a slash or something.
  • User profile image
    Rui

    Hi bob
    i couldn't type any words when i was trying to save my sound.can u help me with this?

  • User profile image
    gauravi

    Hi Clint

    Thank You so much..

    Now my code is working...

  • User profile image
    gauravi

    @rui

     

    you have to click page down key on your key borad..

  • User profile image
    Harsh Shah

    Hey Bob and Clint,
    No files play now and I get an exception.

    An exception of type 'System.IO.IsolatedStorage.IsolatedStorageException' occurred in mscorlib.ni.dll but was not handled in user code

    What can be done?

  • User profile image
    Clint

    @Harsh Shah: without seeing more of the exception, I can't really help. 

    I'm betting you left off a slash or mistyped something.  I suggest looking line by line comparing our solution to this video to your project.

    Worst case, zip up your code (remove sounds and the bin/obj folders for file size) https://absolutebeginner.codeplex.com/WorkItem/Create

  • User profile image
    Harsh Shah

    I did line by line checking. I will zip the code.
    https://absolutebeginner.codeplex.com/workitem/1225
    Please help. I deleted Audio and Tiles. I have not included packages as well.

  • User profile image
    Clint

    @Harsh Shah: So looking at this right away.  you've gone off and done your own thing which is great.  With that however, you are no longer on our sample which makes helping a lot harder.

    Next, this is about playing the MP3s you have, not actually your recorded audio (which works cause I tested)

    Basically the details of the exception is it can't find the MP3 you have.  It was exactly what I thought, a mistyped filepath.  You have an extra slash.

    In SoundModel.cs, you have

    string basepath = "/Assets/Sounds/GOW1/";

    it should be

    string basepath = "Assets/Sounds/GOW1/";

     

  • User profile image
    Harsh Shah

    Thanks a lot Clint. Sorry for not exactly following the tutorial. This is my way of learning. Thanks a lot for the help.

  • User profile image
    Clint

    @Harsh Shah: 100% understand, just makes helping a LOT harder. 

  • User profile image
    Antu

    I am not able to figure out what i did wrong. I record the voice, play it there, it plays. Then i click on save -> named it -> back to mine column. There i can spot the recording i saved. But when i press it to play, it is not playing.

  • User profile image
    Clint

    @Antu: are you sure you're saving the proper file path?

    Look at our sample for this lesson and be sure the little things like slashes are where they should be.

    if you still can't get it to work, create a ticket with your solution zipped up at https://absolutebeginner.codeplex.com/WorkItem/Create  chances are you'll have to delete the BIN, OBJ and your sound folder.

  • User profile image
    Antu

    I figured it out! Just missed a very short step. Thanks for this awesome tutorial for windows phone development. Really learned a lot of things which i wont be able to understand without this tutorial!

  • User profile image
    Clint

    @Antu: Glad you figured it out!  Remember, we do provide the source code for each step

  • User profile image
    usaidather

    Could not install package 'Newtonsoft.Json 5.0.6'. You are trying to install this package into a project that targets 'WindowsPhone,Version=v8.0', but the package does not contain any assembly references that are compatible with that framework. For more information, contact the package author.

    im having issue in installing json.net

  • User profile image
    Clint

    @usaidather: update your nuget manager in visual studio.

    With a fresh install of Visual Studio 2012, we'll need to update NuGet to get some of the newer packages such as the Coding4Fun Toolkit.  It is a super easy process and can be done in a few clicks.

    1. Go to the Tools Menu –> Extensions and Updates
    2. Go to the Update Tab –> Visual Studio Gallery
      nugetUpdate
    3. Click Update
    4. Restart Visual Studio
  • User profile image
    usaidather

    thanks Smiley

  • User profile image
    cookie lumai

    Hi Bob,l am following every step of your video,and just after typing the "data Title = "Mine"" i tried to emulator the app,but got this:
    error 1 Failed to locate the source file “C:\WINDOWS\TEMP\WindowsPhone,Version=v8.0.AssemblyAttributes.cs” C:\Users\luominguo\Documents\Visual Studio 2012\Projects\SoundBoard\SoundBoard\CSC SoundBoard
    can you help me with this

  • User profile image
    cookie lumia

    Hi Bob,now i just found that all my windows phone apps cannot be emulatored ,maybe l removed some important stuffs from my computer.
    the coding process is okay

  • User profile image
    Clint

    @cookie lumia: yeah, sounds like a file you have is missing.  Are you sure you didn't delete something?

  • User profile image
    Joel

    I am running into a problem with the custom sounds. I can record and save them just fine. The tile gets created with the proper name. When I play it the first time, it works. If I try to play it a second time it fails to get the stream
    on this line

    using (var stream = new IsolatedStorageFileStream(data.FilePath, FileMode.Open, storageFolder))

    in MainPage.xaml.cs. The storageFolder is System.IO.IsolatedStorage.IsolatedStorageFile. When it works the first time it has the same value. I'm clueless and Bob never tried it twice on the video.

    It goes down with

    + $exception {System.IO.IsolatedStorage.IsolatedStorageException: Operation not permitted on IsolatedStorageFileStream.
    at System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, IsolatedStorageFile isf)
    at System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor(String path, FileMode mode, IsolatedStorageFile isf)
    at SoundBoard.MainPage.LongListSelector_SelectionChanged(Object sender, SelectionChangedEventArgs e)
    at Microsoft.Phone.Controls.LongListSelector.set_SelectedItem(Object value)
    at Microsoft.Phone.Controls.LongListSelector.OnItemTap(Object sender, GestureEventArgs e)
    at MS.Internal.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args)
    at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName)} System.Exception {System.IO.IsolatedStorage.IsolatedStorageException}

    Any idea what could be wrong?










  • User profile image
    Joel

    Forgot to tell you the data.FilePath. It was "/customAudio/130249594038184333.wav" each time. Should this be a relative path as with the assets? If the path were wrong it wouldn't work the first time either.

  • User profile image
    Joel

    If I play a different custom sound each time it works fine but if I repeat the same one twice in a row it fails.

  • User profile image
    Clint

    @Joel: create a ticket with your solution zipped up at https://absolutebeginner.codeplex.com/WorkItem/Create  chances are you'll have to delete the BIN, OBJ and your sound folder.

    I'm betting one small little thing is causing this.

  • User profile image
    goodsreaper

      Fantastic rapid response, Clint. Thanks. You were right, it was a small thing, but I'm really relieved that it was your small thing and not mine. Wink. I put the code in my solution and it works. Testing's a drag, isn't it.

    Can you please explain to me why it would fail to get the stream when the filepath was the same as the last time, but only on those filepaths stored with Json?

    Anyway, great course. This is fantastic. And to think it's all free (well, thanks to Microsoft). I look forward to finishing this course and probably doing a more advanced one next. Can you suggest one?

    Joel

  • User profile image
    Clint

    @goodsreaper: The stream is still open for the file and we are trying to open the file again.

    For more advanced stuff, check out the jump starter series.  I personally stand behind start working on an application that you want to build and start on that Smiley

  • User profile image
    cookie lumia

    Thanks Clint,finally l found the issue,and just reinstalled windows 8 and wp8 sdk.now all the things are fine

  • User profile image
    Trhac

    Hi Bob,

    why didnt you simply use NavigationService.GoBack method to return to MainPage? You want to return back, not to navigate to another page...

  • User profile image
    Clint

    @Trhac: Excellent question, think I was building out the application and it was more complex.  Your way is how i'd recommend doing it.

  • User profile image
    Sesha

    Successfully installed 'Newtonsoft.Json 5.0.8'.
    Successfully uninstalled 'Newtonsoft.Json 5.0.8'.
    Install failed. Rolling back...
    Could not install package 'Newtonsoft.Json 5.0.8'. You are trying to install this package into a project that targets 'WindowsPhone,Version=v8.0', but the package does not contain any assembly references that are compatible with that framework. For more information, contact the package author.

    Nuget Package Manager is updated as well.
    Please help me fix this.
    Thank you

  • User profile image
    Clint

    @Sesha: how are you verifying your nuget is up-to-date?  I just did a test project and installed Json.net via nuget.

  • User profile image
    Sesha

    @Clint: Hi thanks for your reply. It Was my mistake Clint. I had not updated Nuget properly and now the extension works cool. Thank you

  • User profile image
    Kiren Paul

    While Installing JSON.NET shows some error.

    Install failed. Rolling back...
    Could not install package 'Newtonsoft.Json 5.0.8'. You are trying to install this package into a project that targets 'WindowsPhone,Version=v8.0', but the package does not contain any assembly references that are compatible with that framework. For more information, contact the package author.

    Any idea why ? And how to solve this problem ????

  • User profile image
    Clint

    @Kiren Paul:  update your nuget manager in visual studio.

    With a fresh install of Visual Studio 2012, we'll need to update NuGet to get some of the newer packages such as the Coding4Fun Toolkit.  It is a super easy process and can be done in a few clicks.

    1. Go to the Tools Menu –> Extensions and Updates
    2. Go to the Update Tab –> Visual Studio Gallery
      nugetUpdate
    3. Click Update
    4. Restart Visual Studio
  • User profile image
    L Cat

    I am having pivot custom sounds, but with no tiles...
    private void LongListSelector_SelectionChanged(object sender, SelectionChangedEventArgs e)

    maybe in this method needed to load assets file stuff and the last for customSound, which is saved into IsolatedStorageFile. I cannot do it...

  • User profile image
    Seke1412

    Hi Bob;
    This is really a great series. I've created a cool app with your introduction. Everything works fine. T've just realized that my records sound disappear when i close my simulator and reopen the app, is there anything to do to save my records permanently that when i open my apps again it will be fully loaded?

    Thanks

  • User profile image
    Clint
    @Seke1412: the emulator does a full reset back to a "new" state everytime the starts from new. If you are talking about having the custom sounds stay in the app, that is coming up in the next few lessons Smiley
  • User profile image
    Seke1412

    Thank Clint,

    I'm on lesson 24 and I'm getting addicted with Bob Taylor series. "Hi, I'm Bob Taylor from learning visualstudio.net...".

  • User profile image
    amir

    Hi i have a problem with the code i have witnessed all the video lectures but now i got stuck at lecture 21... when i debug the Application it gives me an error exception
    "System.IO.IsolatedStorage.IsolatedStorageException"

    Noi idea whats going over there...

    Please help me to figure out this stuff

    Thanks...
    Amir

  • User profile image
    amir

    My application performs all the rest of the functionality well but when it comes to play the sounds from animals/warnings/taunts by clicking on the tiles... it generates the exception on the MainPage.xaml.cs
    /////////////////////////////
    ////////////Code////////////
    ///////////////////////////
    using(var storageFolder = IsolatedStorageFile.GetUserStoreForApplication())
    {
    using (var stream = new IsolatedStorageFileStream(data.FilePath, FileMode.Open, storageFolder))
    {
    AudioPlayer.SetSource(stream);
    }
    }
    /////////////////////////////
    ////////////Code////////////
    ///////////////////////////

    Thats the line where the exception occurs...

    using (var stream = new IsolatedStorageFileStream(data.FilePath, FileMode.Open, storageFolder))


    Please help me to figure out the issue.


    Thanks
    Amir

  • User profile image
    wayne

    In line 67, ApplicationBar.IsVisible = true;
    Why can we access ApplicationBar in uncheck even? ApplicationBar wasn't declared in the scope, right?

  • User profile image
    wayne

    I mean uncheck event method.
    private void RecordButton_Unchecked(object sender, RoutedEventArgs e)
    {
    _recorder.Stop();
    SaveTempAudio(_recorder.Buffer);
    Play.IsEnabled = true;
    ApplicationBar.IsVisible = true; // Why can I access ApplicationBar here?
    }

  • User profile image
    Duncanma

    @wayne: ApplicationBar is a property of the page itself, the class that your button event is contained inside. This means it is in scope in all of the code of that class, without having to be declared inside each function or method.

  • User profile image
    zombie197

    @amir: how did u solve the
    "System.IO.IsolatedStorage.IsolatedStorageException"

    problem?

  • User profile image
    Param

    In my app, file.Exists is giving false. I don't know why because it's able to play the stored sounds. My sounds are stored as /Assets/Rock/1.mp3 and so on.. Hence I'm not able to apply the if else condition to distinguish between the custom and stored sounds.. Plz help me

  • User profile image
    wayne

    @Duncanma
    Thanks for the explanation. Figured it's a property of PhoneApplicationPage.

    Another question, is there a way we can set the current pivot item to "customSounds" when we use NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative)) back to the MainPage.xaml. Actually I just got my windows phone few weeks ago, and I like it a lot. I still don't have to many apps in my phone but I notice that some apps have this problem. When users hit the back page button, the app set the page back to previous one, but lost the last view item (pivot item, or position in stack panel).

  • User profile image
    Sahil Jain

    First of all i would like you sir for providing such a nice tutorial with ebook and videos.
    Sir i have one query and i will really appreciate your help.
    I have followed every step and checked it many times.
    My entire app runs fine , except i am not able to save any sound.
    I am able to record sound and play it.But when i save it with the name , nothing(no tile) appears in "mine"/"custom sounds".
    I debugged the program many times setting break points at various places , what i noticed is even after execution of this statement
    " App.ViewModel.CustomSounds.Items.Add(soundData); "
    the item count of custom sounds shows zero during bebugging.
    I understand that it would it difficult for you to understand what i did wrong , byt can you please suggest what could be wrong.
    Thanking You

  • User profile image
    BobTabor

    @Sahil Jain: Have you tried setting some break points to make sure the code that saves to storage is actually firing?  I would make sure the code is getting called before jumping to any erroneous conclusions about what could be wrong.

  • User profile image
    Sahil Jain

    Yes Sir, i have checked it.The code that saves to storage is indeed firing.
    I have tried using "CustomSounds = new SoundGroup() " just to be sure if there's any mistake in my LoadCustomSounds() method , like you did in your video tutorial before using JSON , but i am not able to see any tile in the pivot of Custom Sounds. :(

  • User profile image
    Sahil Jain

    Problem Solved :
    i did some mistake in App.xaml.cs file :) :)

  • User profile image
    Omri Dagan

    @Sahil Jain: I have the exact same problam and I can't find what's wrong with my App.xaml.cs file.. How did you fix the problem?

  • User profile image
    Rishi

    hello Sir,
    You explained really good through out the series.
    I just want to know how to located "customAudio" Folder.
    As my recorded audio stores at some location, how to locate that location

  • User profile image
    Kiel

    Question: say you wanted to rename a custom sound after it has been created. essentially you want to change the value of soundData.Title. How do you go about that? I've implemented INotifyPropertyChanged in my model already, but I can't seem to access the properties of individual object in the viewmodel from the MainPage.cs file. I'm only able to add or remove whole objects using a selected item in the listbox and invoking App.ViewModel.Add/Remove().

    Is there any way to change the properties of objects in the viewmodel?

  • User profile image
    vanderghast

    Seems that we should also have a way to delete a "custom" file.

    But what is the reason to use JSon over, say, the supplied Serialize method available from DotNet ?

  • User profile image
    BobTabor

    @vanderghast:  Re: deleting ... that would be a great challenge!  Do it!!!

    The DataContractJsonSerializer is from Microsoft. (Can't remember if we're using that or not, but now that's the preferred way).  The Serialize uses XML if I recall correctly.  As the old joke goes ... "I had a problem so I used XML.  Now I have two problems."  :)

  • User profile image
    James

    Hey, great series, thanks for creating it.

    I'm having a problem that once I save my custom sound title, it does not show up in the pivot for custom sounds. I tried checking my code along with the screen shots and the video, but I'm not sure what's causing it to not show up.

    Thanks!

  • User profile image
    Julie

    I had a error in 'File.Exists(data.FilePath)'.
    In this time, I Fixed it. :-)

    --- SoundModel.cs ---

    string basePath = "/Assets/Audio/Animals/";
    ==> string basePath = "Assets/Audio/Animals/";


  • User profile image
    BobTabor

    @James: Try setting breakpoints in your code at the point where the file is saved to disk to make sure it got there, then set a breakpoint where it is added to the list of sounds.  At this point, debugging and understanding what's not happening when it should is the best way to figure out where the problem is.

    @Julie: Figuring out something as small as that is impressive.  Good work!

  • User profile image
    Julie

    Thank you!! Bob Tabor!! :)

  • User profile image
    Abhinav

    Hey!!
    Wonderful series...Loving it
    I just didn't understand one thing. Why do we have to use that "JSON thing" to store our recorded sounds permanently on our disk.
    We had already saved the file permanently on our disk when we created the sounddata object in the "save" event handler.
    Please help!!

    Thank you in advance.

  • User profile image
    iamatsundere


    I have this issue but i don't know how to fix this, can you help me 

    http://i.imgur.com/X66vXcs.jpg

  • User profile image
    kukuom

    @iamatsundere: I think you should describe the issue when running your app. Its little difficult to solve with just a image :)

    @BobTabor:@Clint: thank you so much with this Series. Its really awesome 

     

  • User profile image
    ChuckJ

    Ive added a Context menu to the Data Template which lets you press and hold. What I would like is to press and hold to saveasringtone. But I cant figure out what to put as the source in ringtonetask code in the mainpage.cs that will save the audio of the Tile you press. Any ideas?

  • User profile image
    AayKay

    @BobTabor @Clint .. Thanks for the tutorial, everything is fine until i add the following code:

    if (File.Exists(data.FilePath))
    {

    AudioPlayer.Source = new Uri(data.FilePath, UriKind.RelativeOrAbsolute);
    }

    else {

    using (var storageFolder = IsolatedStorageFile.GetUserStoreForApplication())
    {

    using(var stream = new IsolatedStorageFileStream(data.FilePath, FileMode.Open ,FileAccess.Read , storageFolder))
    {
    AudioPlayer.SetSource(stream);

    }

    }

    }

    After i add this ,the app doesn't doesn't play any sound instead when i click on any of the tiles it gives following exception:

    + $exception {System.IO.IsolatedStorage.IsolatedStorageException: Operation not permitted on IsolatedStorageFileStream.
    at System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, IsolatedStorageFile isf)
    at System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor(String path, FileMode mode, FileAccess access, IsolatedStorageFile isf)
    at SoundBoard.MainPage.LongListSelector_SelectionChanged_1(Object sender, SelectionChangedEventArgs e)
    at Microsoft.Phone.Controls.LongListSelector.set_SelectedItem(Object value)
    at Microsoft.Phone.Controls.LongListSelector.OnItemTap(Object sender, GestureEventArgs e)
    at MS.Internal.CoreInvokeHandler.InvokeEventHandler(Int32 typeIndex, Delegate handlerDelegate, Object sender, Object args)
    at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName)} System.Exception {System.IO.IsolatedStorage.IsolatedStorageException}

  • User profile image
    AayKay

    @BobTabor: @Clint: thanks for the tutorials.....the problem is  just that the custom sound doesn't play back after i save it... otherwise all is good,  i tried to telly my code with the source code provided on this page but couldn't find any dissimilarities... i am confused ,watched the tutorial about 7,8 times but still cant figure the error.... help please..

  • User profile image
    BlaBla

    Thank for the tutorials.
    But, How to it keep record when the phone locked? (run in background)
    Thanks.

  • User profile image
    Nathiel

    Hy, i have a problem,how i can Creat that Class SoundData.cs? I starter to see at 17-21 Video tutorial,that class was creat in the same project before 17 Tutorial? Thanks!

Add Your 2 Cents