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;
                    }
                });
            }));
        }