用C#实现百度实时语音识别,出现引发的异常:“System.ArgumentOutOfRangeException”(位于 mscorlib.dll 中) 语音识别.exe Information: 0 : SAPI does not implement phonetic alphabet selection.为什么?

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.Net;
using System.Speech.Recognition;
using System.Speech.Synthesis;

namespace 语音识别
{
class Program
{
private static IntPtr inputDevice;

    //调用wavein的dll
    [DllImport("winmm.dll")]
    //获取有多少可用输入设备
    public static extern int waveInGetNumDevs();
    [DllImport("winmm.dll")]
    //增加一个缓冲区
    public static extern int waveInAddBuffer(IntPtr hwi, ref WaveHdr pwh, UInt32 cbwh);
    [DllImport("winmm.dll")]
    //关闭麦克风
    public static extern int waveInClose(IntPtr hwi);
    [DllImport("winmm.dll")]
    //打开麦克风
    public static extern int waveInOpen(out IntPtr phwi, UInt32 uDeviceID, ref WaveFormatEx lpFormat, WaveDelegate dwCallback, UInt32 dwInstance, UInt32 dwFlags);
    [DllImport("winmm.dll")]
    //标记为可用的缓冲区
    public static extern int waveInPrepareHeader(IntPtr hWaveIn, ref WaveHdr lpWaveInHdr, UInt32 uSize);
    [DllImport("winmm.dll")]
    //标记为不可用的缓冲区
    public static extern int waveInUnprepareHeader(IntPtr hWaveIn, ref WaveHdr lpWaveInHdr, UInt32 uSize);
    [DllImport("winmm.dll")]
    //把缓冲区内容重置
    public static extern int waveInReset(IntPtr hwi);
    [DllImport("winmm.dll")]
    //开始录制
    public static extern int waveInStart(IntPtr hwi);
    [DllImport("winmm.dll")]
    //停止录制
    public static extern int waveInStop(IntPtr hwi);
    [StructLayout(LayoutKind.Sequential)]
    //接受的波形数据放入的缓冲区
    public struct WaveHdr
    {

        public IntPtr lpData;//缓冲区
        public UInt32 dwBufferLength;//缓冲区长度
        public UInt32 dwBytesRecorded;//某一刻读取到了多少字节的数据
        public UInt32 dwUser;//自定义数据
        public UInt32 dwFlags;
        public UInt32 dwLoops;//是否循环
        public IntPtr lpNext;//链表的下一缓冲区
        public UInt32 reserved;//没实际意义
    }

    [StructLayout(LayoutKind.Sequential)]
    //波形格式
    public struct WaveFormatEx
    {
        public UInt16 wFormatTag;//波形的类型
        public UInt16 nChannels;//通道数(1,单声道   2,立体音)
        public UInt32 nSamplesPerSec;//采样率
        public UInt32 nAvgBytesPerSec;//字节率
        public UInt16 nBlockAlign;
        public UInt16 wBitsPerSample;//每个样多少位
        public UInt16 cbSize;//长度
    }
    public delegate void WaveDelegate(IntPtr hwi, UInt32 uMsg, UInt32 dwInstance, UInt32 dwParam1, UInt32 dwParam2);
    /// <summary>
    /// 通过HTTP协议去上传base64数据
    /// </summary>
    /// <param name="URL">服务器的url</param>
    /// <param name="strPostdata">上传的东西</param>
    /// <param name="strEncoding">采用的编码格式</param>
    /// <returns></returns>
    public static string OpenReadWithHttps(string URL, string strPostdata, string strEncoding)
    {
        Encoding encoding = Encoding.Default;
        //默认的编码格式为default(GB2312)
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
        //向自定义的URL链接发送请求 request
        request.Method = "post";
        //请求的方式为post
        request.Accept = "*/*";
        //告诉服务器能接受*/*(任意)的参数类型
        request.ContentType = "application/x-www-form-urlencoded";
        //最常见的post提交数据的方式
        byte[] buffer = encoding.GetBytes(strPostdata);
        //用一个byte数组接收发送的数据字节
        request.ContentLength = buffer.Length;
        //告诉服务器自己上传的数组长度
        request.GetRequestStream().Write(buffer, 0, buffer.Length);
        //写入请求流从第一位开始写入buffer数组,写入长度为buffer.Length的数据流
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        //从服务器得到的数据为请求获得的数据
        using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(strEncoding)))
        {
            //返回从URL获得的内容信息
            return reader.ReadToEnd();
        }
    }
    static void waveInHandler(IntPtr hwi, UInt32 uMsg, UInt32 dwInstance, UInt32 dwParam1, UInt32 dwParam2)
    {
        switch (uMsg)
        {
            case 0x3BE: break;
            case 0x3C0:
                unsafe
                {
                    var waveHdr = (WaveHdr*)dwParam1;
                }
                break;
            case 0x3BF: break;
        }
    }
    public static void loading(string listen, string url)
    {
        var file = File.OpenRead(url);
        var sr = new StreamReader(file);
        List<string> include = new List<string>();
        while (!sr.EndOfStream)
        {
            var str = sr.ReadLine();
            foreach (var chara in str)
                if (!char.IsLetter(chara))
                    str = str.Replace(chara, ' ');
            str = str.Trim();
            include.Add(str);
        }
        for (int i = 0; i < include.Count; i++)
        {
            if (String.Compare(listen.Trim(), include[i].Trim(), StringComparison.CurrentCultureIgnoreCase) == 0)
            {
                SpeechSynthesizer speaker = new SpeechSynthesizer();
                speaker.SetOutputToDefaultAudioDevice();
                speaker.Speak(include[i + 1]);
                return;
            }
        }
        SpeechSynthesizer speak = new SpeechSynthesizer();
        speak.SetOutputToDefaultAudioDevice();
        speak.Speak("口音有问题,请重说。");
        throw new Exception("口音有问题,请重说。");
    }
    public static string Recognize(string getin)
    {
        var responses = new string[]
        {
           "楼主帅吗",
           "当然了",
           "聪明吗",
           "必须的",
            //你想写和你想输出的语句
        };
        getin = getin.ToLower();
        foreach (var chara in getin)
            if (!char.IsLetter(chara))
                getin = getin.Replace(chara, ' ');
        getin = getin.Trim();
        int matches;
        var k = getin.Split();
        for (var i = 0; i < responses.Length; i++)
        {
            responses[i] = responses[i].ToLower();
            foreach (var chara in responses[i])
                if (!char.IsLetter(chara))
                    responses[i] = responses[i].Replace(chara, ' ');
            responses[i] = responses[i].Trim();
        }
        foreach (var repWord in responses)
        {
            matches = 0;
            var j = repWord.Split();
            foreach (var myword in k)
            {
                if (j.Contains(myword))
                {
                    matches++;
                    if (((float)matches / j.Length) >= 0.5F)
                        return repWord;
                }
            }
        }
        return "你说错了,请重说";
    }
    static void Main(string[] args)
    {
        try
        {
            var inputFormat = new WaveFormatEx();//波形格式
            inputFormat.wFormatTag = 1;//波形类型
            inputFormat.nChannels = 1;
            inputFormat.nSamplesPerSec = 8000;
            inputFormat.nAvgBytesPerSec = 16000;
            inputFormat.nBlockAlign = 2;
            inputFormat.wBitsPerSample = 16;
            inputFormat.cbSize = 0;
            for (; ; )
            {

                waveInOpen(out inputDevice, UInt32.MaxValue, ref inputFormat, new WaveDelegate(waveInHandler), 0, 0x00030000);

                int bufferSize = 960000;
                var buffer1 = new WaveHdr();
                buffer1.lpData = Marshal.AllocHGlobal(bufferSize);
                buffer1.dwBufferLength = (UInt32)bufferSize;
                buffer1.dwLoops = 1;
                waveInPrepareHeader(inputDevice, ref buffer1, (UInt32)Marshal.SizeOf(typeof(WaveHdr)));
                waveInAddBuffer(inputDevice, ref buffer1, (UInt32)Marshal.SizeOf(typeof(WaveHdr)));

                SpeechRecognitionEngine recognizer = null;
                foreach (var installed in SpeechRecognitionEngine.InstalledRecognizers())
                {
                    if (installed.Culture.Name.Equals("zh-CN", StringComparison.CurrentCultureIgnoreCase) && installed.Id.Equals("MS-2052-80-DESK"))
                    {
                        recognizer = new SpeechRecognitionEngine(installed);
                        break;
                    }
                }
                var grammars = new GrammarBuilder();
                grammars.AppendDictation();
                recognizer.LoadGrammar(new Grammar(grammars));
                recognizer.SetInputToDefaultAudioDevice();

                bool recognizeStarted = false;
                int speechCount = 0;
                int silenceCount = 0;

                Console.WriteLine("正在等候语音输入...");
                recognizer.RecognizeAsync(RecognizeMode.Multiple);
                waveInStart(inputDevice);
                for (; ; )
                {
                    if (!recognizeStarted)
                    {
                        if (recognizer.AudioState == AudioState.Speech)
                            speechCount++;
                        else speechCount = 0;
                    }
                    if (!recognizeStarted && speechCount >= 2)
                    {
                        recognizeStarted = true;
                        speechCount = 0;
                        Console.WriteLine("检测到语音输入,正在录制...");
                    }
                    if (recognizeStarted)
                    {
                        if (recognizer.AudioState == AudioState.Silence)
                            silenceCount++;
                        else silenceCount = 0;
                    }
                    //checkingMutex.Set();
                    if (recognizeStarted && silenceCount >= 220)
                    {
                        //checkingMutex.Reset();
                        silenceCount = 0;
                        unsafe
                        {
                            Console.WriteLine("正在分析语音数据...");

                            waveInReset(inputDevice);
                            waveInStop(inputDevice);
                            recognizer.RecognizeAsyncStop();
                            if (recognizer.AudioState == AudioState.Silence)
                                silenceCount++;
                            else silenceCount = 0;
                            var apiKey = "GhC8XzGxu0QVh1WGHdN4UGch";
                            var secretKey = "kIkXRu20oLnXaC8IZqw4lbR1xFxI0ijF";
                            var token = OpenReadWithHttps("https://openapi.baidu.com/oauth/2.0/token" + $"?grant_type={ "client_credentials" }&client_id={ apiKey }&client_secret={ secretKey }", String.Empty, "utf-8");
                            var tokenPrefix = "\"access_token\":[\"";
                            int i;
                            token = token.Substring(i = token.IndexOf(tokenPrefix) + tokenPrefix.Length + 1, token.IndexOf("\"", i + tokenPrefix.Length) - i);

                            var postData = new StringBuilder();
                            postData.Append("{").Append($"\"format\":\"pcm\",\"rate\":16000,\"channel\":1,\"token\":\"{ token }\",\"cuid\":\"F96625D0-0FBC-491C-B617-9EC0B3A0D5A6\",\"lan\":\"\",");
                            var base64Data = new byte[buffer1.dwBytesRecorded];
                            Marshal.Copy(buffer1.lpData, base64Data, 0, (int)buffer1.dwBytesRecorded);
                            var base64 = Convert.ToBase64String(base64Data);
                            postData.Append("\"speech\":\"").Append(base64).Append("\",").Append($"\"len\":{ buffer1.dwBytesRecorded }").Append("}");
                            try
                            {
                                Console.Write("\n识别结果: ");
                                Marshal.FreeHGlobal(buffer1.lpData);
                                var result = OpenReadWithHttps("http://vop.baidu.com/server_api", postData.ToString(), "utf-8");
                                var prefix = "\"result\":[\"";
                                result = result.Substring(i = result.IndexOf(prefix) + prefix.Length, result.LastIndexOf("\"]") - i + 1);
                                string[] restt = result.Split('\"');
                                var restlt = restt[0];
                                Console.WriteLine(restlt);
                                //string resultfinally = Recognize(restlt);
                                try
                                {
                                    string resultfinally = Recognize(restlt);
                                    loading(resultfinally, "word.txt");
                                }
                                catch (Exception ex)
                                {
                                    Console.WriteLine(ex.Message);
                                    //(new SpVoiceClass()).Speak("你说的有些不标准,请重新说");
                                }
                                Console.WriteLine();
                            }
                            catch (Exception)
                            {
                                Console.WriteLine("无法识别所说的话语。\n");

                            }
                            //checkingMutex.Set();
                        }
                        //checking.Dispose(checkingFinished);
                        break;
                    }
                    Thread.Sleep(1);
                }

                //checkingFinished.WaitOne();
            }
        }
        catch (Exception exception)
        {
            Console.WriteLine(exception);
        }

    }
}

}


查看全部
weixin_46648322
weixin_46648322
2020/04/21 10:01
  • 人工智能
  • 点赞
  • 收藏
  • 回答
    私信

1个回复