Как передать поток из Naudio в MS SpeechRecognization? - PullRequest
0 голосов
/ 15 мая 2019

Я пытаюсь использовать метод SetInputToAudioStream для речевого движка.

Но он не работает.Я также искал несколько статей и пытался всеми возможными способами.но все равно не работает.

https://stackoverflow.com/a/6203533/1336662

https://stackoverflow.com/a/6203533/1336662

Мне пришлось использовать класс SpeechStreamer, описанный в Ответ Шона , чтобыдля работы SpeechRecognitionEngine.

Вот мой код, пожалуйста, если кто-нибудь может мне помочь, это будет здорово.

using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Speech.Recognition;
using System.Speech.AudioFormat;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;

namespace WpfAppNAudio
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            console.AppendText("Click to start recording");
        }
        public WaveIn waveSource = null;
        public WaveFileWriter waveFile = null;
        private SpeechRecognitionEngine _recognizer = null;
        //Stream a = null;
        SpeechStreamer stream = null;
        private bool _recognizing;

        void RecognizeSpeechAndWriteToConsole()
        {
            _recognizer = new SpeechRecognitionEngine();
            try
            {
                //_recognizer.
                // Create and load a grammar.  
                Grammar dictation = new DictationGrammar();
                dictation.Name = "Dictation Grammar";

                _recognizer.LoadGrammar(dictation);


                _recognizer.SpeechRecognized += _recognizer_SpeechRecognized; // if speech is recognized, call the specified method
                _recognizer.SpeechRecognitionRejected += _recognizer_SpeechRecognitionRejected; // if recognized speech is rejected, call the specified method
                _recognizer.SpeechDetected += _recognizer_SpeechDetected;
                _recognizer.RecognizeCompleted += _recognizer_RecognizeCompleted;


            }
            catch (Exception)
            {

            }
        }

        private void _recognizer_RecognizeCompleted(object sender, RecognizeCompletedEventArgs e)
        {
        }

        private void _recognizer_SpeechDetected(object sender, SpeechDetectedEventArgs e)
        {
        }

        private void _recognizer_SpeechRecognitionRejected(object sender, SpeechRecognitionRejectedEventArgs e)
        {
            console.AppendText("speech rejected");
        }

        private void _recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
        {
            console.AppendText("speech recognized" + e.Result.Text);
        }

        private void StartBtn_Click()
        {

            waveSource = new WaveIn();
            waveSource.WaveFormat = new WaveFormat(22050, 8, 1);

            waveSource.DataAvailable += new EventHandler<WaveInEventArgs>(waveSource_DataAvailable);
            waveSource.RecordingStopped += new EventHandler<StoppedEventArgs>(waveSource_RecordingStopped);

            waveFile = new WaveFileWriter(@"C:\Temp\Test0001.wav", waveSource.WaveFormat);

            console.AppendText("Starting recording");
            RecognizeSpeechAndWriteToConsole();
            waveSource.StartRecording();

        }

        void StopBtn_Click(object sender, EventArgs e)
        {
            waveSource.StopRecording();
        }

        void waveSource_DataAvailable(object sender, WaveInEventArgs e)
        {
            if (waveFile != null)
            {
                stream = new SpeechStreamer(e.Buffer.Length);               
                stream.Write(e.Buffer, 0, e.BytesRecorded);
                waveFile.Write(e.Buffer, 0, e.BytesRecorded);
                waveFile.Flush();
                if (!_recognizing)
                {
                    _recognizing = true;
                    _recognizer.SetInputToAudioStream(stream, new System.Speech.AudioFormat.SpeechAudioFormatInfo(22050, System.Speech.AudioFormat.AudioBitsPerSample.Eight, System.Speech.AudioFormat.AudioChannel.Mono));
                    var s = _recognizer.RecognizerInfo.SupportedAudioFormats;
                    _recognizer.RecognizeAsync(RecognizeMode.Multiple);
                }
            }
        }

        void waveSource_RecordingStopped(object sender, StoppedEventArgs e)
        {
            if (waveSource != null)
            {
                waveSource.Dispose();
                waveSource = null;
            }

            if (waveFile != null)
            {
                waveFile.Dispose();
                waveFile = null;
            }

        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            StartBtn_Click();
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            waveSource.StopRecording();
        }
    }

    class SpeechStreamer : Stream
    {
        private AutoResetEvent _writeEvent;
        private List<byte> _buffer;
        private int _buffersize;
        private int _readposition;
        private int _writeposition;
        private bool _reset;

        public SpeechStreamer(int bufferSize)
        {
            _writeEvent = new AutoResetEvent(false);
            _buffersize = bufferSize;
            _buffer = new List<byte>(_buffersize);
            for (int i = 0; i < _buffersize; i++)
                _buffer.Add(new byte());
            _readposition = 0;
            _writeposition = 0;
        }

        public override bool CanRead
        {
            get { return true; }
        }

        public override bool CanSeek
        {
            get { return false; }
        }

        public override bool CanWrite
        {
            get { return true; }
        }

        public override long Length
        {
            get { return -1L; }
        }

        public override long Position
        {
            get { return 0L; }
            set { }
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            return 0L;
        }

        public override void SetLength(long value)
        {

        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            int i = 0;
            while (i < count && _writeEvent != null)
            {
                if (!_reset && _readposition >= _writeposition)
                {
                    _writeEvent.WaitOne(100, true);
                    continue;
                }
                buffer[i] = _buffer[_readposition + offset];
                _readposition++;
                if (_readposition == _buffersize)
                {
                    _readposition = 0;
                    _reset = false;
                }
                i++;
            }

            return count;
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            for (int i = offset; i < offset + count; i++)
            {
                _buffer[_writeposition] = buffer[i];
                _writeposition++;
                if (_writeposition == _buffersize)
                {
                    _writeposition = 0;
                    _reset = true;
                }
            }
            _writeEvent.Set();

        }

        public override void Close()
        {
            _writeEvent.Close();
            _writeEvent = null;
            base.Close();
        }

        public override void Flush()
        {

        }
    }
}
...