Robot Engage Blog Buy Now

Misty Community Forum

Azure Text To Speech - Error when trying to save an audio file on Misty in C#


Below is the code to call the Azure Text To Speech API in C#.

using Microsoft.CognitiveServices.Speech;
using Microsoft.CognitiveServices.Speech.Audio;

            using (var fileOutput = AudioConfig.FromWavFileOutput(outputFilename))
                using (var synthesizer = new SpeechSynthesizer(config, fileOutput))
                    var result = await synthesizer.SpeakTextAsync(text_value);

                    if (result.Reason == ResultReason.SynthesizingAudioCompleted)
                        Console.WriteLine($"Speech synthesized to [{outputFilename}] for text [{text_value}]");
                    else if (result.Reason == ResultReason.Canceled)
                        var cancellation = SpeechSynthesisCancellationDetails.FromResult(result);
                        Console.WriteLine($"CANCELED: Reason={cancellation.Reason}");

                        if (cancellation.Reason == CancellationReason.Error)
                            Console.WriteLine($"CANCELED: ErrorCode={cancellation.ErrorCode}");
                            Console.WriteLine($"CANCELED: ErrorDetails=[{cancellation.ErrorDetails}]");

The code works on my laptop but not on Misty. I assume it is a permission issue but do not know how to fix it.

Below is the error message:

Misty Robotics [••] SDK : 12/17/19 02:26:57.680 PM => MistyGreeter : ConvertTextToSpeech: => Exception
==> Exception: System.ApplicationException: Exception with an error code: 0x8 (SPXERR_FILE_OPEN_FAILED)
at Microsoft.CognitiveServices.Speech.Internal.SpxExceptionThrower.ThrowIfFail(IntPtr hr)
at Microsoft.CognitiveServices.Speech.SpeechSynthesizer.FromConfig(SpeechConfig speechConfig, AudioConfig audioConfig)
at Microsoft.CognitiveServices.Speech.SpeechSynthesizer…ctor(SpeechConfig speechConfig, AudioConfig audioConfig)
at MistyGreeter.MistyNativeSkill.ConvertTextToSpeech(String text_value, String outputFilename)

To save images to an Azure Blob Storage Container I created this code:
var storageLibrary = await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
// change to the subfolder ‘images’ where the Misty photos are stored.
StorageFolder storageSubfolder = await storageLibrary.SaveFolder.GetFolderAsync(“images”);
// Get the file from the folder.
var storageFile = await storageSubfolder.GetFileAsync(filename);
// Create Reference to Azure Storage Account
String storageAccountKey2 = MistyAzureInfo.STORAGE_ACCOUNT_KEY;
CloudStorageAccount storageacc = CloudStorageAccount.Parse(storageAccountKey2);
//Create Reference to Azure Blob
CloudBlobClient blobClient = storageacc.CreateCloudBlobClient();
// Get a reference to the Azure Blob Container.
CloudBlobContainer container = blobClient.GetContainerReference(“mistyimages”);
// Upload the file with the name to the container “mistyimages”
CloudBlockBlob blockBlob = container.GetBlockBlobReference(filename);
using (var photoOutputStream = await storageFile.OpenStreamForWriteAsync())
// Upload the photo to Azure Blob Storage in the ‘mistyimages’ Container.
await blockBlob.UploadFromStreamAsync(photoOutputStream);

it works but I have to use the storageFile.OpenStreamForWriteAsync()) to save to Misty.

What code do I use to replace this:
using (var fileOutput = AudioConfig.FromWavFileOutput(outputFilename))
I assume I need to use a Windows.Storage method like the OpenStreamForWriteAsync() above.

Thanks for any help.


Hi Wes,

When you use this sample on your computer, where on your computer does it save your audio file? It would be ideal if you use the azure tts api to actually get a file and then use Misty’s api to upload that to the robot. Even if you were able to use the Windows Storage api to save the file to the robot, it would have to be stored with the other audio assets for the robot to play it.

I don’t understand the connection with the bit you posted about images. Could you elaborate?

Hi Erin,

Actually I have some other code that calls the Azure tts api (on a Linux server) then Misty calls my api to download the file and play it. I just assumed that with the C# SDK it was better to call the Azure apis directly from the robot.

So thanks for the clarifying the common way to implement it. I will use my original code.


p.s. As for the image code, it accesses the \pictures\images folder where the .jpg files get stored when doing a C# _misty.TakePicture() and then it uploads the .jpg to Azure Blob Storage. It was just a sample showing how I used the Window.Storage api to access the .jpg file.

Wes - Thanks for clarifying. Let us know if you are able to implement using Misty apis and how that performs for you.

1 Like