Reputation: 2258
I have to create an audio file from a stream generated by the SpeechSynthesizer.
This is the code am using
var stream = await _SpeechSynth.GetSpeakStreamAsync(text, this.Language);
var reader = new Windows.Storage.Streams.DataReader(stream.GetInputStreamAt(0));
await reader.LoadAsync((uint)stream.Size);
byte[] bytes = new byte[stream.Size];
reader.ReadBytes(bytes);
var audioFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync(_AgendaAudioFilename, CreationCollisionOption.ReplaceExisting);
using (var outputStream = await audioFile.OpenAsync(FileAccessMode.ReadWrite))
{
Stream os = outputStream.GetOutputStreamAt(0).AsStreamForWrite();
await os.WriteAsync(bytes, 0, bytes.Length);
}
I found out the problem was that at "os.WriteAsync" was not being awaited. When i put a breakpoint at that line and wait for a few secs then the file was being created properly. Shouldnt the await keyword wait till all the bytes are copied into the stream before going to the next line?
I dont mind if anyone can suggest any better way of copying an InMemoryRandomAccessStream to a file?
EDIT:
Mahantesh's answer works like a charm. Thanks a lot. But am facing a new problem.
After the file is created am trying to open it again to play it but am getting this error.
"Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))"
This is my code.
if (!cacheHit)
{
var stream = await _SpeechSynth.GetSpeakStreamAsync(text, this.Language);
//write the stream to disk (seems to be buggy when attempting to playback from the result of the speech synth request)
var audioFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync(_AgendaAudioFilename, CreationCollisionOption.ReplaceExisting);
outputStream = await audioFile.OpenAsync(FileAccessMode.ReadWrite);
await RandomAccessStream.CopyAsync(stream, outputStream);
}
//read agenda from disk and play back the audio
var agendaStorageFile = await ApplicationData.Current.TemporaryFolder.GetFileAsync(_AgendaAudioFilename);
var agendaStreamFromDisk = await agendaStorageFile.OpenAsync(FileAccessMode.Read);
_MediaPlayer.Url = text;
_MediaPlayer.SetBytestream(agendaStreamFromDisk);
_MediaPlayer.Play();
Am getting the error at this line:
var agendaStreamFromDisk = await agendaStorageFile.OpenAsync(FileAccessMode.Read);
Any idea what might be going wrong?
Upvotes: 0
Views: 818
Reputation: 2898
I think you can try with
await RandomAccessStream.CopyAsync(inMemoryStream, outputStream);
Solution to new Problem:
if (!cacheHit)
{
var stream = await _SpeechSynth.GetSpeakStreamAsync(text, this.Language);
//write the stream to disk (seems to be buggy when attempting to playback from the result of the speech synth request)
var audioFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync(_AgendaAudioFilename, CreationCollisionOption.ReplaceExisting);
using(outputStream = await audioFile.OpenAsync(FileAccessMode.ReadWrite)){
await RandomAccessStream.CopyAsync(stream, outputStream);}
}
//read agenda from disk and play back the audio
var agendaStorageFile = await ApplicationData.Current.TemporaryFolder.GetFileAsync(_AgendaAudioFilename);
using (var agendaStreamFromDisk = await agendaStorageFile.OpenAsync(FileAccessMode.Read)){
_MediaPlayer.Url = text;
_MediaPlayer.SetBytestream(agendaStreamFromDisk);
_MediaPlayer.Play(); }
Upvotes: 1
Reputation: 10386
As you are using await
keyword for waiting it is better to use syncronous versions of methods, like
using (var outputStream = audioFile.Open(FileAccessMode.ReadWrite))
{
Stream os = outputStream.GetOutputStreamAt(0).AsStreamForWrite();
os.Write(bytes, 0, bytes.Length);
}
Upvotes: 0