public SpeechToTextAudioStream GetAudioStream()
        {
            SpeechToTextAudioStream audioStream = null;

            if (audioQueue != null)
            {
                if (audioQueue.TryDequeue(out audioStream))
                {
                    return(audioStream);
                }
            }
            return(audioStream);
        }
        private SpeechToTextMainStream(ulong MaxSizeInBytes = 0, uint ThresholdDuration = 0, uint ThresholdLevel = 0)
        {
            tresholdDuration         = ThresholdDuration;
            thresholdDurationInBytes = 0;
            thresholdLevel           = ThresholdLevel;
            maxSize = MaxSizeInBytes;

            thresholdStart = 0;
            thresholdEnd   = 0;
            audioStream    = null;
            internalStream = new Windows.Storage.Streams.InMemoryRandomAccessStream();
            inputStream    = internalStream.GetInputStreamAt(0);
            audioQueue     = new ConcurrentQueue <SpeechToTextAudioStream>();
        }
Beispiel #3
0
        public static SpeechToTextAudioStream Create(
            uint Channels,
            uint SamplesPerSec,
            uint AvgBytesPerSec,
            uint BlockAlign,
            uint BitsPerSample,
            ulong AudioStart
            )
        {
            SpeechToTextAudioStream stts = null;

            try
            {
                stts = new SpeechToTextAudioStream(Channels, SamplesPerSec, AvgBytesPerSec, BlockAlign, BitsPerSample, AudioStart);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("Exception while creating SpeechToTextAudioStream: " + ex.Message);
            }
            return(stts);
        }
        /// <summary>
        /// SendAudioStream method
        /// This method sends a SpeechToTextAudioStream towards Cognitive Services REST API.
        /// Usually, the method GetAudioStream returns the SpeechToTextAudioStream (if available) then the method SendAudioStream
        /// sends a SpeechToTextAudioStream towards Cognitive Services REST API.
        /// </summary>
        /// <param name="locale">language associated with the current buffer/recording.
        /// for instance en-US, fr-FR, pt-BR, ...
        /// </param>
        /// <param name="stream">AudioStream which will be forwarded to REST API.
        /// </param>
        /// <return>The result of the SpeechToText REST API.
        /// </return>
        public async System.Threading.Tasks.Task <SpeechToTextResponse> SendAudioStream(string locale, SpeechToTextAudioStream stream)
        {
            SpeechToTextResponse r = null;
            int loop = 1;

            while (loop-- > 0)
            {
                try
                {
                    string os        = "Windows" + SpeechToText.SystemInformation.SystemVersion;
                    string deviceid  = "b2c95ede-97eb-4c88-81e4-80f32d6aee54";
                    string speechUrl = SpeechUrl + "?scenarios=ulm&appid=D4D52672-91D7-4C74-8AD8-42B1D98141A5&version=3.0&device.os=" + os + "&locale=" + locale + "&format=json&requestid=" + Guid.NewGuid().ToString() + "&instanceid=" + deviceid + "&result.profanitymarkup=1&maxnbest=3";
                    Windows.Web.Http.HttpClient hc = new Windows.Web.Http.HttpClient();
                    System.Threading.CancellationTokenSource cts = new System.Threading.CancellationTokenSource();
                    hc.DefaultRequestHeaders.TryAppendWithoutValidation("Authorization", Token);
                    Windows.Web.Http.HttpResponseMessage hrm     = null;
                    Windows.Web.Http.HttpStreamContent   content = null;
                    content = new Windows.Web.Http.HttpStreamContent(stream.GetInputStreamAt(0));
                    content.Headers.ContentLength = (ulong)stream.Size;
                    if ((content != null) && (content.Headers.ContentLength > 0))
                    {
                        System.Diagnostics.Debug.WriteLine("REST API Post Content Length: " + content.Headers.ContentLength.ToString());
                        content.Headers.TryAppendWithoutValidation("ContentType", "audio/wav; codec=\"audio/pcm\"; samplerate=16000");
                        IProgress <Windows.Web.Http.HttpProgress> progress = new Progress <Windows.Web.Http.HttpProgress>(ProgressHandler);
                        hrm = await hc.PostAsync(new Uri(speechUrl), content).AsTask(cts.Token, progress);
                    }
                    if (hrm != null)
                    {
                        switch (hrm.StatusCode)
                        {
                        case Windows.Web.Http.HttpStatusCode.Ok:
                            var b = await hrm.Content.ReadAsBufferAsync();

                            string result = System.Text.UTF8Encoding.UTF8.GetString(b.ToArray());
                            if (!string.IsNullOrEmpty(result))
                            {
                                r = new SpeechToTextResponse(result);
                            }
                            break;

                        case Windows.Web.Http.HttpStatusCode.Forbidden:
                            string token = await RenewToken();

                            if (string.IsNullOrEmpty(token))
                            {
                                loop++;
                            }
                            break;

                        default:
                            int    code      = (int)hrm.StatusCode;
                            string HttpError = "Http Response Error: " + code.ToString() + " reason: " + hrm.ReasonPhrase.ToString();
                            System.Diagnostics.Debug.WriteLine(HttpError);
                            r = new SpeechToTextResponse(string.Empty, HttpError);
                            break;
                        }
                    }
                }
                catch (System.Threading.Tasks.TaskCanceledException)
                {
                    System.Diagnostics.Debug.WriteLine("http POST canceled");
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine("http POST exception: " + ex.Message);
                }
                finally
                {
                    System.Diagnostics.Debug.WriteLine("http POST done");
                }
            }
            return(r);
        }
        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;
                    }
                });
            }));
        }