public Windows.Foundation.IAsyncOperationWithProgress <uint, uint> WriteAsync(IBuffer buffer) { return(System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.Run <uint, uint>((token, progress) => { return Task.Run(() => { // If it's the first WriteAsync in the stream // the buffer should contains the WAV Header if ((internalStream.Size == 0) && (wavHeaderLength == 0)) { WriteDataIndex = 0; // Check header byte[] array = buffer.ToArray(); wavHeaderLength = ParseAndGetWAVHeaderLength(array); internalStream.WriteAsync(buffer).AsTask().Wait(); WriteDataIndex += buffer.Length; progress.Report((uint)(buffer.Length)); return (uint)(buffer.Length); } else { if (internalStream.Position != internalStream.Size) { System.Diagnostics.Debug.WriteLine("Warning WriteAsync: " + internalStream.Position.ToString() + "/" + internalStream.Size.ToString()); } ulong index = internalStream.Size; uint byteToWrite = buffer.Length; // System.Diagnostics.Debug.WriteLine("WriteAsync: " + buffer.Length.ToString() + " at position: " + internalStream.Position); internalStream.WriteAsync(buffer.ToArray(0, (int)byteToWrite).AsBuffer()).AsTask().Wait(); WriteDataIndex += buffer.Length; var byteArray = buffer.ToArray(); if (byteArray.Length >= 2) { var amplitude = Decode(byteArray).Select(Math.Abs).Average(x => x); if (AudioLevel != null) { this.AudioLevel(this, amplitude); } // Currently the level is too low if (thresholdDurationInBytes > 0) { if (audioStream == null) { if (internalStream.Size > thresholdDurationInBytes) { var readStream = internalStream.GetInputStreamAt(internalStream.Size - thresholdDurationInBytes); byte[] readBuffer = new byte[thresholdDurationInBytes]; readStream.ReadAsync(readBuffer.AsBuffer(), (uint)thresholdDurationInBytes, InputStreamOptions.None).AsTask().Wait(); var level = Decode(readBuffer).Select(Math.Abs).Average(x => x); if (level > thresholdLevel) { System.Diagnostics.Debug.WriteLine("Audio Level sufficient to start recording"); thresholdStart = WriteDataIndex - thresholdDurationInBytes; audioStream = SpeechToTextAudioStream.Create(nChannels, nSamplesPerSec, nAvgBytesPerSec, nBlockAlign, wBitsPerSample, thresholdStart); var headerBuffer = CreateWAVHeaderBuffer(0); if ((audioStream != null) && (headerBuffer != null)) { audioStream.WriteAsync(headerBuffer.AsBuffer()).AsTask().Wait(); audioStream.WriteAsync(readBuffer.AsBuffer()).AsTask().Wait(); } } } } else { audioStream.WriteAsync(buffer.ToArray(0, (int)byteToWrite).AsBuffer()).AsTask().Wait(); var readStream = internalStream.GetInputStreamAt(internalStream.Size - thresholdDurationInBytes); byte[] readBuffer = new byte[thresholdDurationInBytes]; readStream.ReadAsync(readBuffer.AsBuffer(), (uint)thresholdDurationInBytes, InputStreamOptions.None).AsTask().Wait(); var level = Decode(readBuffer).Select(Math.Abs).Average(x => x); if (level < thresholdLevel) { System.Diagnostics.Debug.WriteLine("Audio Level lower enough to stop recording"); thresholdEnd = WriteDataIndex; audioStream.Seek(0); var headerBuffer = CreateWAVHeaderBuffer((uint)(thresholdEnd - thresholdStart)); if (headerBuffer != null) { audioStream.WriteAsync(headerBuffer.AsBuffer()).AsTask().Wait(); } if (audioQueue != null) { audioStream.endIndex = thresholdEnd; audioQueue.Enqueue(audioStream); } if (BufferReady != null) { this.BufferReady(this); if (audioStream != null) { audioStream = null; } thresholdStart = 0; thresholdEnd = 0; } } } } } if (maxSize > 0) { // check maxSize if ((internalStream.Size > maxSize) && (audioStream == null)) { lock (maxSizeLock) { byte[] headerBuffer = null; if (wavHeaderLength > 0) { // WAV header present headerBuffer = new byte[wavHeaderLength]; inputStream = internalStream.GetInputStreamAt(0); inputStream.ReadAsync(headerBuffer.AsBuffer(), (uint)wavHeaderLength, InputStreamOptions.None).AsTask().Wait(); } seekOffset += (internalStream.Size - wavHeaderLength); internalStream.Dispose(); inputStream.Dispose(); internalStream = new Windows.Storage.Streams.InMemoryRandomAccessStream(); if (headerBuffer != null) { internalStream.WriteAsync(headerBuffer.AsBuffer()).AsTask().Wait(); } inputStream = internalStream.GetInputStreamAt(0); } } } if (internalStream.Position == internalStream.Size) { WriteDataIndex += buffer.Length; } progress.Report((uint)buffer.Length); return (uint)buffer.Length; } }); })); }