This project has moved and is read-only. For the latest updates, please go here.

Playing sound file not consistent

Jan 4, 2014 at 7:26 PM
It might be really straightforward, but as I was out of programming in the last 10-15 years, catching up takes a little bit:
Loading at each start of my app the soundfile from PC to the brick, leads sometimes to not very consistent results. Playing it back from the brick is sometimes too fast or with beginning truncated. Checking the file in the brick itself confirms that indeed the file somehow is distorted.

What I am using:
        /// <summary>
        /// Loads the sound file from the PC to the EV3 brick
        /// </summary>
        /// <returns>Object Task to be waited to be finalized</returns>
        private async Task LoadSoundResource()
            soundShortFileName = soundFullFileName.Substring(soundFullFileName.LastIndexOf("\\")+1);
            soundShortFileNameNoExt = soundShortFileName.Remove(soundShortFileName.LastIndexOf("."));

            await myBrick.SystemCommand.CopyFileAsync(soundFullFileName, soundBrickPath+soundShortFileName);
Thanks for any support.
Jan 4, 2014 at 7:52 PM
Edited Jan 4, 2014 at 7:53 PM
Can you send a copy of the sound file you're using? Use the contact page on my blog which can attach a file.

Also, not that I think it's the issue, but take a look at the Path class which contains a series of methods to manipulate paths and get what you're after without having to rely on a Substring call...
Jan 4, 2014 at 7:59 PM
Edited Jan 4, 2014 at 9:00 PM
I'm using the standard Okey-dokey.rsf which comes with the EV3. In about 66-75%%, the file is downloaded and played properly.

On the manipulating filenames, I told you that I'm rusty, learning my way in the world where most of the things are already canned and ready to be consumed :)


Later Edit: There is a timing issue (maybe I am not mastering the async). It seems that having after the call something like
if (LoadSoundResource().IsCompleted)
gives more consistent result but still 10-20% of the cases sound file is heard truncated (always the beginning) or playback speed is wrong.
Jan 9, 2014 at 3:58 AM
Edited Jan 9, 2014 at 4:20 AM
Which platform are you using? WinRT, Desktop or Phone? How are you connecting? Bluetooth/USB/WiFi?

Edit: Testing here with that sound file is working, and your code above looks correct. Maybe it's specific to a platform/connection type...


How are you calling LoadSoundResource? Do you have an await before it?
await LoadSoundResource();
await _brick.DirectCommand.PlaySoundAsync(params);
In your code above with the if statement, I don't see an await. If there's no await, your LoadSoundResource method will run as a "fire and forget" method, so when you call the Play command, the LoadSoundResource method may not have been completed. Using await will keep things in sync.
Jan 11, 2014 at 1:16 PM
I'm making a Desktop app in Win8.1, connecting via USB which I understand is not the most reliable way.

I'm having the same issue with the await as well:
                    await EV3Brick.LoadSoundResourceAsync();
        public static async Task LoadSoundResourceAsync()
            soundShortFileName = System.IO.Path.GetFileName(soundFullFileName);
            soundShortFileNameNoExt = System.IO.Path.GetFileNameWithoutExtension(soundShortFileName);
            await myBrick.SystemCommand.CopyFileAsync(soundFullFileName, soundBrickPath + soundShortFileName);
        public static async Task PlaySoundFileAsync()
            await myBrick.DirectCommand.PlaySoundAsync(100, soundBrickPath + soundShortFileNameNoExt);
As said before, playing is done properly, playing back the sound file as uploaded to the brick. So still this loading is an issue. Anyway, at startup of the application I'm loading the resource, playback is triggered by a button and it makes no difference if I'm waiting 1 sec or 10 sec before pushing that button on the interface.

Something similar in terms of timing I'm getting when reading the status of the ports: somehow, values are not available immediately when asked for in general, I'm getting the right values a little bit afterwards.
Jan 12, 2014 at 7:58 PM
I think you may be being bitten by the desktop USB flakiness with the library. Sound uploading is a several part process, uploading the file chunk-by-chunk. Because my USB layer is a bit flakey, it sometimes likes to write packets that seem to be successful that wind up never making it to the other side. So it sounds like you could be getting a corrupted upload.

As for the values not available immediately, that's one of the known issues with desktop USB as well. I find that values can be up to a second delayed (sometimes even more). They don't stream smoothly as they do over bluetooth/wifi/USB on WinRT.

Overall, my only suggestion to you is to change to bluetooth or wifi as your connection layer and see if that clears up the issue. Your code above is perfectly valid, but I'll also give you one suggestion just for better async usage: if you have a method that only includes an await as the final line of the method, instead of awaiting it, return the Task instead and await it at the caller. For example:
        public static async Task PlaySoundFileAsync()
            await myBrick.DirectCommand.PlaySoundAsync(100, soundBrickPath + soundShortFileNameNoExt);
        public static Task PlaySoundFileAsync()
            return myBrick.DirectCommand.PlaySoundAsync(100, soundBrickPath + soundShortFileNameNoExt);
It saves you a setting up an async action when it's not necessary in cases like this. Hope that makes some kind of sense, but it's not anything to do with the issue you're experiencing, just a suggestion. :)