2019-07-30 10:31:07 qq_24822271 阅读数 115
  • Android 实战开发 三方SDK 讯飞语音SDK

    Android 第三方SDK开发视频教程,给课程结合讯飞语音这个第三方SDK进行实战教学,实现在线语音合成,将文字信息转化为声音信息,给应用配上“嘴巴;语音听写,将连续语音识别为文字,给应用配上“耳朵”。

    4707 人正在学习 去看看 Frank Lee

科大接口调用文档:
https://www.xfyun.cn/doc/asr/voicedictation/Linux-SDK.html#_2、sdk集成指南

from ctypes import *
import time
import threading

# 调用动态链接库
dll = cdll.LoadLibrary("../Linux_iat1226_xxxxxxx/libs/x64/libmsc.so")
# 登录参数,apppid一定要和你的下载SDK对应
login_params = b"appid = xxxxxx, work_dir = ."

FRAME_LEN = 640  # Byte

MSP_SUCCESS = 0
# 返回结果状态
MSP_AUDIO_SAMPLE_FIRST = c_int(1)
MSP_AUDIO_SAMPLE_CONTINUE = c_int(2)
MSP_AUDIO_SAMPLE_LAST = c_int(4)
MSP_REC_STATUS_COMPLETE = c_int(5)
# 你的语音文件路径
filename = "./f1.wav"


class Msp:
    def __init__( self ):
        self.recogStatus = c_int(8)
        self.counter = 0
        self.laststr = ''
        self.sessionID = None
        self.epStatus = None
        self.count = 0

    def login( self ):
        ret = dll.MSPLogin(None, None, login_params)
        # print('MSPLogin =>', ret)

    def logout( self ):
        ret = dll.MSPLogout()
        # print('MSPLogout =>', ret)

    def isr( self, audiofile, session_begin_params ):
        ret = c_int()
        self.sessionID = c_voidp()
        dll.QISRSessionBegin.restype = c_char_p
        self.sessionID = dll.QISRSessionBegin(None, session_begin_params, byref(ret))
        print('QISRSessionBegin => self.sessionID:', self.sessionID, 'ret:', ret.value)

        # 每秒【1000ms】  16000 次 * 16 bit 【20B】 ,每毫秒:1.6 * 16bit 【1.6*2B】 = 32Byte
        # 1帧音频20ms【640B】 每次写入 10帧=200ms 【6400B】

        # piceLne = FRAME_LEN * 20
        piceLne = 1638 * 2
        self.epStatus = c_int(0)
        self.recogStatus = c_int(0)

        wavFile = open(audiofile, 'rb')

        while wavFile:
            wavData = wavFile.read(piceLne)

            aud_stat = MSP_AUDIO_SAMPLE_CONTINUE
            if (self.count == 0):
                aud_stat = MSP_AUDIO_SAMPLE_FIRST  # 第一句

            if len(wavData) <= 0:
                # print('最后一句话')
                ret = dll.QISRAudioWrite(self.sessionID, None, 0, MSP_AUDIO_SAMPLE_LAST, byref(self.epStatus),byref(self.recogStatus))
                #print('send last ,recogStatus:',self.recogStatus.value,'ret:',ret)
                break
            else:
                ret = dll.QISRAudioWrite(self.sessionID, wavData, len(wavData), aud_stat,
                                         byref(self.epStatus),
                                         byref(self.recogStatus))
                #print('len(wavData):', len(wavData), 'QISRAudioWrite ret:', ret, 'epStatus:', self.epStatus.value, 'recogStatus:', self.recogStatus.value)
            self.count += 1
            time.sleep(0.1)
            if self.recogStatus.value==0:
                self.get_result()
        wavFile.close()
        print("所有待识别音频已全部发送完毕")

        while self.recogStatus.value != 5:
            self.get_result()
            time.sleep(1)


    def get_result( self , ):
        #print('开始获取识别结果', self.recogStatus.value)
        ret = c_int(0)
        dll.QISRGetResult.restype = c_char_p
        retstr = dll.QISRGetResult(self.sessionID, byref(self.recogStatus), 0, byref(ret))
        #print("error code : ", ret.value, 'recogStatus:', self.recogStatus.value)

        if retstr is not None:
            self.laststr += retstr.decode()
            print(self.laststr)

        if self.recogStatus.value == 5:
            ret = dll.QISRSessionEnd(self.sessionID, 'end')
            print('语音识别结束')
        return self.laststr

        


def XF_text( filepath, audiorate ):
    msp = Msp()
    print("登录科大讯飞")
    msp.login()
    print("科大讯飞登录成功")
    session_begin_params = b"sub = iat, ptt = 0, result_encoding = utf8, result_type = plain, domain = iat"
    if 16000 == audiorate:
        session_begin_params = b"sub = iat, domain = iat, language = zh_cn, accent = mandarin, sample_rate = 16000, result_type = plain, result_encoding = utf8,vad_enable=0"
    text = msp.isr(filepath, session_begin_params)
    msp.logout()
    return text





if __name__ == '__main__':
    res = XF_text(filename, 16000)
2014-05-29 14:23:07 VoiceFans 阅读数 70120
  • Android 实战开发 三方SDK 讯飞语音SDK

    Android 第三方SDK开发视频教程,给课程结合讯飞语音这个第三方SDK进行实战教学,实现在线语音合成,将文字信息转化为声音信息,给应用配上“嘴巴;语音听写,将连续语音识别为文字,给应用配上“耳朵”。

    4707 人正在学习 去看看 Frank Lee

     百度Android语音识别SDK分在线与离线两种,这篇文章介绍在线SDK的使用方法。

     在线SDK是以JAR包和动态链接库形式发布和使用,可以从百度开放云平台网站中下载SDK及使用说明文档。

http://developer.baidu.com/wiki/index.php?title=docs/cplat/media/voice

     完成语音SDK的集成分以下几步,本文将一步步介绍SDK集成方法。

      

 1、注册开放开放平台   

 点击管理控制台,选择移动应用管理


 选择创建应用,填写应用名称

      


可以看到右上角有ID、API KEY、Secret KEY,点击可以复制其内容,保存这些字符串,在使用语音SDK时会用到。


2、申请开启语音识别服务 ,选择媒体云---语音识别,点击申请开启服务,填写理由。


等待对接成功


3、使用语音识别SDK前的准备

之前准备了SDK开发包以及ID、API KEY、Secret KEY。

首先将开发包中的lib中的库添加到工程中


        声明权限

     <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /></span>

   4、语音识别

SDK有两种实现语音识别的方式,一种是直接使用SDK中的语音识别控件,一种是使用SDK中的语音识别服务。

语音识别控件方式

语音识别控件BaiduASRDigitalDialog,提供了整套语音交互、提示音、音量反馈、动效反馈。开发者初始化一个BaiduASRDigitalDialog对象,并设置相关参数及结果回调,调用Show()方法就可以弹出对话框开始识别,识别结束后会在回调中得到识别结果。

if (mDialog == null || mCurrentTheme != Config.DIALOG_THEME) {
                    mCurrentTheme = Config.DIALOG_THEME;
                    if (mDialog != null) {
                        mDialog.dismiss();
                    }
                    Bundle params = new Bundle();
                    params.putString(BaiduASRDigitalDialog.PARAM_API_KEY, Constants.API_KEY);
                    params.putString(BaiduASRDigitalDialog.PARAM_SECRET_KEY, Constants.SECRET_KEY);
                    params.putInt(BaiduASRDigitalDialog.PARAM_DIALOG_THEME, Config.DIALOG_THEME);
                    mDialog = new BaiduASRDigitalDialog(this, params);
                    mDialog.setDialogRecognitionListener(mRecognitionListener);
                }
                mDialog.getParams().putInt(BaiduASRDigitalDialog.PARAM_PROP, Config.CURRENT_PROP);
                mDialog.getParams().putString(BaiduASRDigitalDialog.PARAM_LANGUAGE,
                        Config.getCurrentLanguage());
                mDialog.show();


识别对话框支持的参数定义在BaiduASRDigitalDialog中以PARAM_前缀的常量。列表如下:

PARAM_API_KEY

string

 

开放平台认证API_key

PARAM_SECRET_KEY

string

 

开放平台认证Secret_key

PARAM_LANGUAGE

string

LANGUAGE_CHINESE

语种,取值定义在VoiceRecognitionConfig类中前缀为LANGUAGE_的常量

PARAM_PARTIAL_RESULTS

boolean

true

连续上屏

PARAM_NLU_ENABLE

boolean

false

是否语义解析。Prop为输入时暂不支持语义,请显示指定为其它领域。

PARAM_NLU_PARAMS

string

 

预留语义解析参数

PARAM_PROP

int

PROP_INPUT

领域参数,定义在VoiceRecognitionConfig类中前缀为PROP_的常量

PARAM_PORMPT_TEXT

string

“请说话”

对话框提示语

PARAM_PROMPT_SOUND_ENABLE

boolean

true

提示音,需要集成SDK包Raw文件夹的资源

PARAM_DIALOG_THEME

int

THEME_BLUE_LIGHTBG

样式。定义在前缀为THEME_的常量中

PARAM_TIPS

String[]

 

引导语列表

PARAM_SHOW_TIPS_ON_START

boolean

false

对话框弹出时首先显示引导语列表

PARAM_SHOW_TIP

boolean

false

识别启动3秒未检测到语音,随机出现一条引导语

PARAM_SHOW_HELP_ON_SILENT

boolean

false

静音超时后将“取消”按钮替换为“帮助”

设置回调方法,处理返回的结果

 mRecognitionListener = new DialogRecognitionListener() {

            @Override
            public void onResults(Bundle results) {
                ArrayList<String> rs = results != null ? results
                        .getStringArrayList(RESULTS_RECOGNITION) : null;
                if (rs != null && rs.size() > 0) {
                    mResult.setText(rs.get(0));
                }

            }
        };



API方式
首先需要配置语音识别引擎ASREngine的参数VoiceRecognitionConfig
VoiceRecognitionConfig config = new VoiceRecognitionConfig();
                config.setProp(Config.CURRENT_PROP);
                config.setLanguage(Config.getCurrentLanguage());
                config.enableVoicePower(Config.SHOW_VOL); // 音量反馈。
                if (Config.PLAY_START_SOUND) {
                    config.enableBeginSoundEffect(R.raw.bdspeech_recognition_start); // 设置识别开始提示音
                }
                if (Config.PLAY_END_SOUND) {
                    config.enableEndSoundEffect(R.raw.bdspeech_speech_end); // 设置识别结束提示音
                }
                config.setSampleRate(VoiceRecognitionConfig.SAMPLE_RATE_8K); // 设置采样率,需要与外部音频一致

然后启动识别
 int code = mASREngine.startVoiceRecognition(mListener, config);

其中mListener是识别过程的回调,需要对其中的方法进行实现
 /**
     * 重写用于处理语音识别回调的监听器
     */
    class MyVoiceRecogListener implements VoiceClientStatusChangeListener {

        @Override
        public void onClientStatusChange(int status, Object obj) {
            switch (status) {
            // 语音识别实际开始,这是真正开始识别的时间点,需在界面提示用户说话。
                case VoiceRecognitionClient.CLIENT_STATUS_START_RECORDING:
                    isRecognition = true;
                    mHandler.removeCallbacks(mUpdateVolume);
                    mHandler.postDelayed(mUpdateVolume, POWER_UPDATE_INTERVAL);
                    mControlPanel.statusChange(ControlPanelFragment.STATUS_RECORDING_START);
                    break;
                case VoiceRecognitionClient.CLIENT_STATUS_SPEECH_START: // 检测到语音起点
                    mControlPanel.statusChange(ControlPanelFragment.STATUS_SPEECH_START);
                    break;
                // 已经检测到语音终点,等待网络返回
                case VoiceRecognitionClient.CLIENT_STATUS_SPEECH_END:
                    mControlPanel.statusChange(ControlPanelFragment.STATUS_SPEECH_END);
                    break;
                // 语音识别完成,显示obj中的结果
                case VoiceRecognitionClient.CLIENT_STATUS_FINISH:
                    mControlPanel.statusChange(ControlPanelFragment.STATUS_FINISH);
                    isRecognition = false;
                    updateRecognitionResult(obj);
                    break;
                // 处理连续上屏
                case VoiceRecognitionClient.CLIENT_STATUS_UPDATE_RESULTS:
                    updateRecognitionResult(obj);
                    break;
                // 用户取消
                case VoiceRecognitionClient.CLIENT_STATUS_USER_CANCELED:
                    mControlPanel.statusChange(ControlPanelFragment.STATUS_FINISH);
                    isRecognition = false;
                    break;
                default:
                    break;
            }

        }

        @Override
        public void onError(int errorType, int errorCode) {
            isRecognition = false;
            mResult.setText(getString(R.string.error_occur, Integer.toHexString(errorCode)));
            mControlPanel.statusChange(ControlPanelFragment.STATUS_FINISH);
        }

        @Override
        public void onNetworkStatusChange(int status, Object obj) {
            // 这里不做任何操作不影响简单识别
        }
    }

获得识别BDVRClient对象

mASREngine = VoiceRecognitionClient.getInstance(this);
        mASREngine.setTokenApis(Constants.API_KEY, Constants.SECRET_KEY);

请求参数设置
每次识别需要通过通过VoiceRecognitionConfig设置参数,其中一些方法在API中有说明

方法

参数

描述

enableBeginSoundEffect

int soundResourceId 启动提示音资源Id

设置开始提示音,soundResourceId为放置在Raw文件夹的资源Id。

 

enableEndSoundEffect

int soundResourceId 说话结束提示音资源Id

检测到用户说话结束播报的提示音,非识别结束

setSampleRate

int rate 采样率

设置音频采样率,

通常建议开发者不指定采样频率,由BDVRClient自动根据当前网络环境选择采样频率。WiFi环境下将使用16kHz采样,移动网络下将使用8kHz采样,来节省流量。参考常量定义

SAMPLE_RATE_8K 8K采样率

SAMPLE_RATE_16K 16K采样率

setProp

int prop

开发者可以通过指定垂直分类来获取更精准的语音识别结果。

注:垂直分类目前支持地图,音乐,视频,APP,网址,开发者需要注意设定采样频率时只能在这五种垂直分类中选择。若指定其他分类,可能会影响识别结果的精度。参考PROP_前缀的常量定义。

setUseDefaultAudioSource

boolean useDefaultSource

设置是否使用缺省的录音。 如果不使用,用户需要调用VoiceRecognitionClient对象的feedAudioBuffer方法为识别器提供语音数据

enableNLU

 

启用语义解析,只在搜索模式起作用

getSampleRate

 

获取当前识别采样率

setLanguage

String Language

设置语种。目前支持的语种有中文普通话(LANGUAGE_CHINESE)、中文粤语(LANGUAGE_CANTONSE)、英文(LANGUAGE_ENGLISH)。


开始语音识别,BDVRClient在开始识别后,会启动录音、预处理、上传到服务器并获取识别结果。

 int code = mASREngine.startVoiceRecognition(mListener, config);
                if (code != VoiceRecognitionClient.START_WORK_RESULT_WORKING) {
                    mResult.setText(getString(R.string.error_start, code));
                } 

取消语音识别

 mASREngine.stopVoiceRecognition();

结束语音识别

mRecognitionClient.speakFinish();

读者可以结合着SDK文档与demo源代码一起来学习百度语音识别SDK的使用。


语音识别的demo下载: http://download.csdn.net/detail/voicefans/7451441


小伙伴注意: 需要按照文章开头的去申请api key和secret key, 修改Constant.java,填上自己的key就ok了。VoiceRecognitionDemoActivity.java  展示了如何使用Dialog方式识别


如果遇到问题欢迎留言交流。












2014-01-06 09:36:13 qinyuanpei 阅读数 9722
  • Android 实战开发 三方SDK 讯飞语音SDK

    Android 第三方SDK开发视频教程,给课程结合讯飞语音这个第三方SDK进行实战教学,实现在线语音合成,将文字信息转化为声音信息,给应用配上“嘴巴;语音听写,将连续语音识别为文字,给应用配上“耳朵”。

    4707 人正在学习 去看看 Frank Lee

            今天我们来继续学习百度语音识别SDK的相关内容,今天我们以百度语音识别SDK提供的API接口为前提,来实现自己的语音识别交互界面。在正式开始今天的文章之前,我们首先来了解下百度语音识别SDK中的几个重要的类吧。

            1、VoiceRecognitionClient

             VoiceRecognitionClient是整个语音识别API中的入口API,我们对于语音识别的整体控制都集中在这个类当中。VoiceRecognitionClient提供了speakFinish()、startVoiceRecognition()、stopVoiceRecognition()三个主要的方法。分别用来控制语音识别结束(指已经说完)、语音识别停止、语音识别开始。通过VoiceRecognitionClient类我们可以对整个语音识别进行宏观上的调控(大笑请原谅我这么说),这是整个语音识别SDK中的入口类。 

            2、VoiceRecognitionConfig

            VoiceRecognitionConfig是语音识别的配置类,在这个类里我们可以对当前语音识别环境进行配置,如语音识别的模式、语音识别音效、语音识别采样率等。

            3、VoiceClientStatusChangeListener

            VoiceClientStatusChangeListener是语音识别的回调接口类,我们要调用百度语音识别API就必须实现这个类,因此这个类是整个语音识别中最重要的一个类,换句话说,如果说VoiceRecognitionClient控制整个宏观层面上的语音识别,那么VoiceClientStatusChangeListener就是在控制整个语音识别的微观层面,一个语音识别的过程包括语音识别开始、语音识别监听、语音识别识别、语音识别反馈,而通过VoiceClientStatusChangeListener我们就能对语音识别的每一个过程进行控制,这个类相对复杂,我们待会会做详细的讨论。

           好了,现在主要的类已经介绍完了,下面大家可以跟着我一起来学习今天的内容了。首先说一下今天想要实现的内容,在今天的程序中,我们将实现通过两个Button来控制语音识别的开始和结束并在界面上反馈当前语音识别的状态和最终的结果,通过一个进度条控件(程序演示需要,非必需)来显示当前用户说话音量的大小情况。首先,我们来初始化语音识别的入口类:

        @Override
	protected void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.layout_voice);
		InitView();
		//获取mClent
		mClient=VoiceRecognitionClient.getInstance(this);
		//设置应用授权信息
		mClient.setTokenApis(API_KEY, SECRET_KEY);
		//初始化主线程
		mHandler=new Handler();
	}

         在这里为了让大家更好的关注于语音识别SDK,我将界面元素初始化的过程写到了InitView()方法中,大家可以参照最后给出的代码。其中的mHandler仅仅是为了配合进度条刷新界面,即非必需。接下来我们来写整个程序中最为重要的一个类,即VoiceClientStatusChangeListener接口,我们一起来看代码:

	/** 语音识别回调接口  **/
	private VoiceClientStatusChangeListener mListener=new VoiceClientStatusChangeListener()
	{
        public void onClientStatusChange(int status, Object obj) {
            switch (status) {
                // 语音识别实际开始,这是真正开始识别的时间点,需在界面提示用户说话。
                case VoiceRecognitionClient.CLIENT_STATUS_START_RECORDING:
                    IsRecognition = true;
                    mVolumeBar.setVisibility(View.VISIBLE);
                    BtnCancel.setEnabled(true);
                    BtnStart.setText("说完");
                    Status.setText("当前状态:请说话");
                    mHandler.removeCallbacks(mUpdateVolume);
                    mHandler.postDelayed(mUpdateVolume, UPDATE_INTERVAL);
                    break;
                case VoiceRecognitionClient.CLIENT_STATUS_SPEECH_START: // 检测到语音起点
                    Status.setText("当前状态:说话中");
                    break;
                case VoiceRecognitionClient.CLIENT_STATUS_AUDIO_DATA:
                    //这里可以什么都不用作,简单地对传入的数据做下记录
                    break;
                // 已经检测到语音终点,等待网络返回
                case VoiceRecognitionClient.CLIENT_STATUS_SPEECH_END:
                    Status.setText("当前状态:正在识别....");
                    BtnCancel.setEnabled(false);
                    mVolumeBar.setVisibility(View.INVISIBLE);
                    break;
                // 语音识别完成,显示obj中的结果
                case VoiceRecognitionClient.CLIENT_STATUS_FINISH:
                    Status.setText(null);
                    UpdateRecognitionResult(obj);
                    IsRecognition = false;
                    ReSetUI();
                    break;
                // 处理连续上屏
                case VoiceRecognitionClient.CLIENT_STATUS_UPDATE_RESULTS:
                    UpdateRecognitionResult(obj);
                    break;
                // 用户取消
                case VoiceRecognitionClient.CLIENT_STATUS_USER_CANCELED:
                    Status.setText("当前状态:已取消");
                    IsRecognition = false;
                    ReSetUI();
                    break;
                default: 
                    break;
            }

        }

        @Override
        public void onError(int errorType, int errorCode) {
            IsRecognition = false;
            Result.setText("出错: 0x%1$s"+Integer.toHexString(errorCode));
            ReSetUI();
        }

        @Override
        public void onNetworkStatusChange(int status, Object obj) 
        {
            // 这里不做任何操作不影响简单识别
        }
	};

           在上面的代码中,我们需要深入了解的就是整个语音识别过程中不同的状态下具体应该做什么,这是我们真正要去考虑的事情。在这里我们给出几个辅助的方法:

           1、对识别结果的解析

/*
	 *将识别结果显示到界面上
	 */
	private void UpdateRecognitionResult(Object result) {
        if (result != null && result instanceof List) {
            @SuppressWarnings("rawtypes")
			List results = (List) result;
            if (results.size() > 0) {
                if (mType==VOICE_TYPE_SEARCH) {
                    Result.setText(results.get(0).toString());
                } else if (mType == VOICE_TYPE_INPUT) {
                    @SuppressWarnings("unchecked")
					List<List<Candidate>> sentences = ((List<List<Candidate>>) result);
                    StringBuffer sb = new StringBuffer();
                    for (List<Candidate> candidates : sentences) {
                        if (candidates != null && candidates.size() > 0) {
                            sb.append(candidates.get(0).getWord());
                        }
                    }
                    Result.setText(sb.toString());
                }
            }
        }
    }
          

            2、识别类型

            识别的类型有两种,一种是Search、一种是Input。Search适用于较短的句子的识别,即短语的识别;Input适用于长句子的识别,即长句的识别。总体来说,百度语音识别的效果还是很不错的

           接下来,我们对语音识别进行一个控制,一起来看代码吧:

/*
	 * 处理Click事件
	 */
	@Override
	public void onClick(View v) 
	{
	   switch(v.getId())
	   {
	     case R.id.Start:
	    	 if (IsRecognition) { // 用户说完
                 mClient.speakFinish();
             } else { // 用户重试,开始新一次语音识别
                 Result.setText(null);
                 // 需要开始新识别,首先设置参数
                 config = new VoiceRecognitionConfig();
                 if (mType == VOICE_TYPE_INPUT) 
                 {
                     config.setSpeechMode(VoiceRecognitionConfig.SPEECHMODE_MULTIPLE_SENTENCE);
                 } else {
                     config.setSpeechMode(VoiceRecognitionConfig.SPEECHMODE_SINGLE_SENTENCE);

                 }
                 //开启语义解析
                 config.enableNLU();
                 //开启音量反馈
                 config.enableVoicePower(true);
                 config.enableBeginSoundEffect(R.raw.bdspeech_recognition_start); // 设置识别开始提示音
                 config.enableEndSoundEffect(R.raw.bdspeech_speech_end); // 设置识别结束提示音
                 config.setSampleRate(VoiceRecognitionConfig.SAMPLE_RATE_8K); //设置采样率
                 //使用默认的麦克风作为音频来源
                 config.setUseDefaultAudioSource(true);
                 // 下面发起识别
                 int code = VoiceRecognitionClient.getInstance(this).startVoiceRecognition(
                         mListener, config);
                 if (code == VoiceRecognitionClient.START_WORK_RESULT_WORKING) 
                 { // 能够开始识别,改变界面
                     BtnStart.setEnabled(false);
                     BtnStart.setText("说完");
                     BtnCancel.setEnabled(true);
                 } else {
                     Result.setText("启动失败: 0x%1$s"+code);
                 }
             }
	    	 break;
	     case R.id.Cancel:
	    	 mClient.stopVoiceRecognition();
	    	 break;
	   }
	}

             注意到我们在上面的代码中是开启了音量反馈的,因此我们需要一个线程来刷新声音的进度条:

       /** 音量更新时间间隔   **/
	private static final int UPDATE_INTERVAL=200;
	
	/** 音量更新任务   **/
	private Runnable mUpdateVolume=new Runnable()
	{
		@Override
		public void run() 
		{
			if (IsRecognition) 
			{
                long vol = VoiceRecognitionClient.getInstance(BaiduVoiceActivity.this)
                        .getCurrentDBLevelMeter();
                mVolumeBar.setProgress((int)vol);
                mHandler.removeCallbacks(mUpdateVolume);
                mHandler.postDelayed(mUpdateVolume, UPDATE_INTERVAL);
            }
			
		}
	};
           当然,这段代码是可以不要的,如果我们取消了音量反馈的话;其次,在实际的语音识别应用中,我们通常会看到界面会根据用户输入的声音的大小绘制一定的波形,这已经超出了本文的研究范围,但是至少说明我们需要在实际的应用中研究这一过程,或者我们可以偷下懒,直接放个动画了事。最后,我们需要写一些用于释放语音识别资源的方法:

@Override
	protected void onDestroy() 
	{
	    VoiceRecognitionClient.releaseInstance(); // 释放识别库
        super.onDestroy();
	}

	@Override
	protected void onPause() 
	{
		if (IsRecognition) {
            mClient.stopVoiceRecognition(); // 取消识别
        }
		super.onPause();
	}
    
 
      到目前为止,百度语音识别SDK的所有API我们都已经研究完了,大家可以自己梳理下思路,最后我给出全部的代码:

package com.Android.BaiduVoice;


import java.util.List;

import com.baidu.voicerecognition.android.Candidate;
import com.baidu.voicerecognition.android.VoiceRecognitionClient;
import com.baidu.voicerecognition.android.VoiceRecognitionConfig;
import com.baidu.voicerecognition.android.VoiceRecognitionClient.VoiceClientStatusChangeListener;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public class BaiduVoiceActivity extends Activity implements OnClickListener
{
    /** 应用授权信息 **/
	private String API_KEY="8MAxI5o7VjKSZOKeBzS4XtxO";
	private String SECRET_KEY="Ge5GXVdGQpaxOmLzc8fOM8309ATCz9Ha";

	/** 界面布局元素 **/
	private TextView Status,Result;
	private ProgressBar mVolumeBar;
	private Button BtnStart,BtnCancel;
	
	/** 语音识别Client **/
	private VoiceRecognitionClient mClient;
	
	/** 语音识别配置 **/
	private VoiceRecognitionConfig config;
	
	/** 语音识别回调接口  **/
	private VoiceClientStatusChangeListener mListener=new VoiceClientStatusChangeListener()
	{
        public void onClientStatusChange(int status, Object obj) {
            switch (status) {
                // 语音识别实际开始,这是真正开始识别的时间点,需在界面提示用户说话。
                case VoiceRecognitionClient.CLIENT_STATUS_START_RECORDING:
                    IsRecognition = true;
                    mVolumeBar.setVisibility(View.VISIBLE);
                    BtnCancel.setEnabled(true);
                    BtnStart.setText("说完");
                    Status.setText("当前状态:请说话");
                    mHandler.removeCallbacks(mUpdateVolume);
                    mHandler.postDelayed(mUpdateVolume, UPDATE_INTERVAL);
                    break;
                case VoiceRecognitionClient.CLIENT_STATUS_SPEECH_START: // 检测到语音起点
                    Status.setText("当前状态:说话中");
                    break;
                case VoiceRecognitionClient.CLIENT_STATUS_AUDIO_DATA:
                    //这里可以什么都不用作,简单地对传入的数据做下记录
                    break;
                // 已经检测到语音终点,等待网络返回
                case VoiceRecognitionClient.CLIENT_STATUS_SPEECH_END:
                    Status.setText("当前状态:正在识别....");
                    BtnCancel.setEnabled(false);
                    mVolumeBar.setVisibility(View.INVISIBLE);
                    break;
                // 语音识别完成,显示obj中的结果
                case VoiceRecognitionClient.CLIENT_STATUS_FINISH:
                    Status.setText(null);
                    UpdateRecognitionResult(obj);
                    IsRecognition = false;
                    ReSetUI();
                    break;
                // 处理连续上屏
                case VoiceRecognitionClient.CLIENT_STATUS_UPDATE_RESULTS:
                    UpdateRecognitionResult(obj);
                    break;
                // 用户取消
                case VoiceRecognitionClient.CLIENT_STATUS_USER_CANCELED:
                    Status.setText("当前状态:已取消");
                    IsRecognition = false;
                    ReSetUI();
                    break;
                default: 
                    break;
            }

        }

        @Override
        public void onError(int errorType, int errorCode) {
            IsRecognition = false;
            Result.setText("出错: 0x%1$s"+Integer.toHexString(errorCode));
            ReSetUI();
        }

        @Override
        public void onNetworkStatusChange(int status, Object obj) 
        {
            // 这里不做任何操作不影响简单识别
        }
	};
	
	/** 语音识别类型定义 **/
	public static final int VOICE_TYPE_INPUT=0;
	public static final int VOICE_TYPE_SEARCH=1;
	
	/** 音量更新时间间隔   **/
	private static final int UPDATE_INTERVAL=200;
	
	/** 音量更新任务   **/
	private Runnable mUpdateVolume=new Runnable()
	{
		@Override
		public void run() 
		{
			if (IsRecognition) 
			{
                long vol = VoiceRecognitionClient.getInstance(BaiduVoiceActivity.this)
                        .getCurrentDBLevelMeter();
                mVolumeBar.setProgress((int)vol);
                mHandler.removeCallbacks(mUpdateVolume);
                mHandler.postDelayed(mUpdateVolume, UPDATE_INTERVAL);
            }
			
		}
	};
	
    /** 主线程Handler */
    private Handler mHandler;
    
    /** 正在识别中 */
    private boolean IsRecognition = false;
    
    /** 当前语音识别类型  **/
    private int mType=VOICE_TYPE_INPUT;
	@Override
	protected void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.layout_voice);
		InitView();
		//获取mClent
		mClient=VoiceRecognitionClient.getInstance(this);
		//设置应用授权信息
		mClient.setTokenApis(API_KEY, SECRET_KEY);
		//初始化主线程
		mHandler=new Handler();
	}
    
	/*
	 * 界面初始化
	 */
	private void InitView()
	{
		Status=(TextView)findViewById(R.id.Status);
		Result=(TextView)findViewById(R.id.Result);
		mVolumeBar=(ProgressBar)findViewById(R.id.VolumeProgressBar);
		BtnStart=(Button)findViewById(R.id.Start);
		BtnStart.setOnClickListener(this);
		BtnCancel=(Button)findViewById(R.id.Cancel);
		BtnCancel.setOnClickListener(this);
		
	}
	@Override
	protected void onDestroy() 
	{
	    VoiceRecognitionClient.releaseInstance(); // 释放识别库
        super.onDestroy();
	}

	@Override
	protected void onPause() 
	{
		if (IsRecognition) {
            mClient.stopVoiceRecognition(); // 取消识别
        }
		super.onPause();
	}
    
	/*
	 * 处理Click事件
	 */
	@Override
	public void onClick(View v) 
	{
	   switch(v.getId())
	   {
	     case R.id.Start:
	    	 if (IsRecognition) { // 用户说完
                 mClient.speakFinish();
             } else { // 用户重试,开始新一次语音识别
                 Result.setText(null);
                 // 需要开始新识别,首先设置参数
                 config = new VoiceRecognitionConfig();
                 if (mType == VOICE_TYPE_INPUT) 
                 {
                     config.setSpeechMode(VoiceRecognitionConfig.SPEECHMODE_MULTIPLE_SENTENCE);
                 } else {
                     config.setSpeechMode(VoiceRecognitionConfig.SPEECHMODE_SINGLE_SENTENCE);

                 }
                 //开启语义解析
                 config.enableNLU();
                 //开启音量反馈
                 config.enableVoicePower(true);
                 config.enableBeginSoundEffect(R.raw.bdspeech_recognition_start); // 设置识别开始提示音
                 config.enableEndSoundEffect(R.raw.bdspeech_speech_end); // 设置识别结束提示音
                 config.setSampleRate(VoiceRecognitionConfig.SAMPLE_RATE_8K); //设置采样率
                 //使用默认的麦克风作为音频来源
                 config.setUseDefaultAudioSource(true);
                 // 下面发起识别
                 int code = VoiceRecognitionClient.getInstance(this).startVoiceRecognition(
                         mListener, config);
                 if (code == VoiceRecognitionClient.START_WORK_RESULT_WORKING) 
                 { // 能够开始识别,改变界面
                     BtnStart.setEnabled(false);
                     BtnStart.setText("说完");
                     BtnCancel.setEnabled(true);
                 } else {
                     Result.setText("启动失败: 0x%1$s"+code);
                 }
             }
	    	 break;
	     case R.id.Cancel:
	    	 mClient.stopVoiceRecognition();
	    	 break;
	   }
	}
	
	/*
	 * 重置界面
	 */
	private void ReSetUI()
	{
		BtnStart.setEnabled(true); // 可以开始重试
		BtnStart.setText("重试");
        BtnCancel.setEnabled(false); // 还没开始不能取消
	}
	
	/*
	 *将识别结果显示到界面上
	 */
	private void UpdateRecognitionResult(Object result) {
        if (result != null && result instanceof List) {
            @SuppressWarnings("rawtypes")
			List results = (List) result;
            if (results.size() > 0) {
                if (mType==VOICE_TYPE_SEARCH) {
                    Result.setText(results.get(0).toString());
                } else if (mType == VOICE_TYPE_INPUT) {
                    @SuppressWarnings("unchecked")
					List<List<Candidate>> sentences = ((List<List<Candidate>>) result);
                    StringBuffer sb = new StringBuffer();
                    for (List<Candidate> candidates : sentences) {
                        if (candidates != null && candidates.size() > 0) {
                            sb.append(candidates.get(0).getWord());
                        }
                    }
                    Result.setText(sb.toString());
                }
            }
        }
    }

	
}

           当然,和上一篇文章一样,我们需要加入必要的权限,否则程序会报错的:

    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

          这样,今天的内容就学习完了,在下一篇文章中,我们会以前面两篇文章所介绍的技术为基础,来实现一个较为实际的应用,并对当下主流的语音识别软件进行一个对比,再次谢谢大家的关注!        


        

2018-01-08 14:53:39 androidzsp 阅读数 2284
  • Android 实战开发 三方SDK 讯飞语音SDK

    Android 第三方SDK开发视频教程,给课程结合讯飞语音这个第三方SDK进行实战教学,实现在线语音合成,将文字信息转化为声音信息,给应用配上“嘴巴;语音听写,将连续语音识别为文字,给应用配上“耳朵”。

    4707 人正在学习 去看看 Frank Lee

1.下载科大讯飞语音识别sdk(http://www.xfyun.cn/sdk/dispatcher)选择语音听写SDK(如下图) ,下载前会让你先创建应用,创建应用后会得到一个appid。然后点“立即开通”去开通“语音识别”功能,之后就会跳出“SDK下载”的页面,然后就可以下载了(未注册账号的要先注册一个账号)。


2.如果是android开发选择android如果是ios选择ios平台(如图)


3.将下载好的sdk中的libs里面的msc.jar以及libmsc.so文件复制到自己创建的libs下面 (如图)


4.接下来将Manifest中添加一下权限并且创建appid时包名需要跟自己创建的工程包名保持一致 (例如 com.vice.android)并且在application中设置android:name以及bunid gradle里面配置sourceSets(如下图)

<!--获取手机录音机使用权限,听写、识别、语义理解需要用到此权限 -->  
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!--连接网络权限,用于执行云端语音能力 -->
<uses-permission android:name="android.permission.INTERNET" />
<!--读取网络信息状态 -->  
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--获取当前wifi状态 -->  
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--允许程序改变网络连接状态 --> 
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<!--读取手机信息权限 -->  
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

5. 具体代码目录结构


6.主要代码如下

package com.voice.android;

import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceActivity;
import android.view.Window;

/**
 * 听写设置界面
 */
public class IatSettings extends PreferenceActivity implements OnPreferenceChangeListener {
   
   public static final String PREFER_NAME = "com.iflytek.setting";
   private EditTextPreference mVadbosPreference;
   private EditTextPreference mVadeosPreference;
   
   @SuppressWarnings("deprecation")
   public void onCreate(Bundle savedInstanceState) {
      requestWindowFeature(Window.FEATURE_NO_TITLE);
      super.onCreate(savedInstanceState);
      getPreferenceManager().setSharedPreferencesName(PREFER_NAME);
      addPreferencesFromResource(R.xml.iat_setting);
      
      mVadbosPreference = (EditTextPreference)findPreference("iat_vadbos_preference");
      mVadbosPreference.getEditText().addTextChangedListener(new SettingTextWatcher(IatSettings.this,mVadbosPreference,0,10000));
      
      mVadeosPreference = (EditTextPreference)findPreference("iat_vadeos_preference");
      mVadeosPreference.getEditText().addTextChangedListener(new SettingTextWatcher(IatSettings.this,mVadeosPreference,0,10000));
   }
   @Override
   public boolean onPreferenceChange(Preference preference, Object newValue) {
      return true;
   }
}

package com.voice.android;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;
/**
 * Json结果解析类
 */
public class JsonParser {

   public static String parseIatResult(String json) {
      StringBuffer ret = new StringBuffer();
      try {
         JSONTokener tokener = new JSONTokener(json);
         JSONObject joResult = new JSONObject(tokener);

         JSONArray words = joResult.getJSONArray("ws");
         for (int i = 0; i < words.length(); i++) {
            // 转写结果词,默认使用第一个结果
            JSONArray items = words.getJSONObject(i).getJSONArray("cw");
            JSONObject obj = items.getJSONObject(0);
            ret.append(obj.getString("w"));
         }
      } catch (Exception e) {
         e.printStackTrace();
      } 
      return ret.toString();
   }
}

package com.voice.android;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechRecognizer;
import com.iflytek.cloud.ui.RecognizerDialog;
import com.iflytek.cloud.ui.RecognizerDialogListener;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.LinkedHashMap;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    private EditText et_name;
    private ImageView iv_yuyin_button;
    // 语音识别对象
    private SpeechRecognizer mAsr;
    private Toast mToast;
    private SharedPreferences mSharedPreferences;
    // 语音听写UI
    private RecognizerDialog mIatDialog;
    private HashMap<String, String> mIatResults = new LinkedHashMap<String, String>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et_name= (EditText) findViewById(R.id.et_name);
        iv_yuyin_button= (ImageView) findViewById(R.id.iv_yuyin_button);
        initXfun();
        initView();
        initListener();
        mToast = Toast.makeText(this, "", Toast.LENGTH_SHORT);
    }
    @Override
    public void onClick(View view) {
        switch (view.getId()) {

            case R.id.iv_yuyin_button:
                voiceTurnWords();
                break;

            default:
                break;

        }
    }
    private void initView(){
        mIatDialog = new RecognizerDialog(this, mInitListener);
    }
    private void initListener(){
        iv_yuyin_button.setOnClickListener(this);
    }
    private void initXfun(){
        mAsr = SpeechRecognizer.createRecognizer(MainActivity.this, mInitListener);
    }
    /**
     * 初始化监听器。
     */
    private InitListener mInitListener = new InitListener() {

        @Override
        public void onInit(int code) {
            if (code != ErrorCode.SUCCESS) {
                showTip("初始化失败,错误码:"+code);
            }
        }
    };
    private void showTip(final String str) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mToast.setText(str);
                mToast.show();
            }
        });
    }
    private void voiceTurnWords(){
        setParam();
        mIatDialog.setListener(mRecognizerDialogListener);
        mIatDialog.show();
        showTip(getString(R.string.text_begin));
    }
    public void setParam() {
        // 清空参数
        mAsr.setParameter(SpeechConstant.PARAMS, null);
        // 设置听写引擎
        mAsr.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
        // 设置返回结果格式
        mAsr.setParameter(SpeechConstant.RESULT_TYPE, "json");
        // 设置语言
        mAsr.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
        // 设置语言区域
        mAsr.setParameter(SpeechConstant.ACCENT, "mandarin");
        // 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理
        mAsr.setParameter(SpeechConstant.VAD_BOS,"4000");
        // 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音
        mAsr.setParameter(SpeechConstant.VAD_EOS,  "1000");
        // 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点
        mAsr.setParameter(SpeechConstant.ASR_PTT,  "0");
    }
    /**
     * 听写UI监听器
     */
    private RecognizerDialogListener mRecognizerDialogListener = new RecognizerDialogListener() {
        public void onResult(RecognizerResult results, boolean isLast) {
            printResult(results);
        }
        /**
         * 识别回调错误.
         */
        public void onError(SpeechError error) {
            showTip(error.getPlainDescription(true));
        }

    };


    private void printResult(RecognizerResult results) {
        String text = JsonParser.parseIatResult(results.getResultString());

        String sn = null;
        // 读取json结果中的sn字段
        try {
            JSONObject resultJson = new JSONObject(results.getResultString());
            sn = resultJson.optString("sn");
        } catch (JSONException e) {
            e.printStackTrace();
        }

        mIatResults.put(sn, text);

        StringBuffer resultBuffer = new StringBuffer();
        for (String key : mIatResults.keySet()) {
            resultBuffer.append(mIatResults.get(key));
        }

        et_name.setText(resultBuffer.toString());
        et_name.setSelection(et_name.length());
    }
}
package com.voice.android;

import java.util.regex.Pattern;
import android.content.Context;
import android.preference.EditTextPreference;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.widget.Toast;

/**
 * 输入框输入范围控制
 */
public class SettingTextWatcher implements TextWatcher {
   private int editStart ;
   private int editCount ;
   private EditTextPreference mEditTextPreference;
   int minValue;//最小值
   int maxValue;//最大值
   private Context mContext;
   
   public SettingTextWatcher(Context context,EditTextPreference e,int min, int max) {
      mContext = context;
      mEditTextPreference = e;
      minValue = min;
      maxValue = max;
    }
   
   @Override
   public void onTextChanged(CharSequence s, int start, int before, int count) {
      editStart = start;
      editCount = count;
   }
   
   @Override
   public void beforeTextChanged(CharSequence s, int start, int count,int after) {       
   }
   
   @Override
   public void afterTextChanged(Editable s) {
      if (TextUtils.isEmpty(s)) {
         return;
      }
      String content = s.toString();
      if (isNumeric(content)) {
         int num = Integer.parseInt(content);
         if (num > maxValue || num < minValue) {
            s.delete(editStart, editStart+editCount);
            mEditTextPreference.getEditText().setText(s);
            Toast.makeText(mContext, "超出有效值范围", Toast.LENGTH_SHORT).show();
         }
      }else {
         s.delete(editStart, editStart+editCount);
         mEditTextPreference.getEditText().setText(s);
         Toast.makeText(mContext, "只能输入数字哦", Toast.LENGTH_SHORT).show();
      }
   }
   
   /**
    * 正则表达式-判断是否为数字
    */
   public static boolean isNumeric(String str){ 
       Pattern pattern = Pattern.compile("[0-9]*"); 
       return pattern.matcher(str).matches();    
    } 

};
package com.voice.android;

import android.app.Application;
import com.iflytek.cloud.Setting;
import com.iflytek.cloud.SpeechUtility;

public class SpeechApp extends Application {

   @Override
   public void onCreate() {
      // 应用程序入口处调用,避免手机内存过小,杀死后台进程后通过历史intent进入Activity造成SpeechUtility对象为null
      // 如在Application中调用初始化,需要在Mainifest中注册该Applicaiton
      // 注意:此接口在非主进程调用会返回null对象,如需在非主进程使用语音功能,请增加参数:SpeechConstant.FORCE_LOGIN+"=true"
      // 参数间使用半角“,”分隔。
      // 设置你申请的应用appid,请勿在'='appid之间添加空格及空转义符
      // 注意: appid 必须和下载的SDK保持一致,否则会出现10407错误
      SpeechUtility.createUtility(SpeechApp.this, "appid=5a4ae664");
      // 以下语句用于设置日志开关(默认开启),设置成false时关闭语音云SDK日志打印
      super.onCreate();
   }
   
}



2018-10-09 00:29:00 chengwei545112 阅读数 117
  • Android 实战开发 三方SDK 讯飞语音SDK

    Android 第三方SDK开发视频教程,给课程结合讯飞语音这个第三方SDK进行实战教学,实现在线语音合成,将文字信息转化为声音信息,给应用配上“嘴巴;语音听写,将连续语音识别为文字,给应用配上“耳朵”。

    4707 人正在学习 去看看 Frank Lee

微软语音识别SDK总结

代码

CComPtr m_pSREngine;// 语音识别引擎(recognition)的接口。 
CComPtr m_pSRContext;// 识别引擎上下文(context)的接口。  
CComPtr m_pSRGrammar;// 识别文法(grammar)的接口。 
CComPtr m_pInputStream;// 流()的接口。  
CComPtr m_pToken;// 语音特征的(token)接口。 
CComPtr m_pAudio;// 音频(Audio)的接口。(用来保存原来默认的输入流)  
ULONGLONG ullGrammerID ;

CoInitialize(NULL);  
m_pSREngine.CoCreateInstance ( CLSID_SpInprocRecognizer );  
m_pSREngine->CreateRecoContext ( &m_pSRContext );//建立上下文

//这里是设置事件  
HWND hwnd = GetSafeHwnd();  
hr = m_pSRContext->SetNotifyWindowMessage(hwnd,WM_RECORD,0,0);

hr=m_pSRContext->SetInterest(SPFEI(SPEI_RECOGNITION),SPFEI(SPEI_RECOGNITION));

//这里是设置默认的音频输入  
hr = SpCreateDefaultObjectFromCategoryId(SPCAT_AUDIOIN, &m_pAudio);  
m_pSREngine->SetInput(m_pAudio,true);

//这里是加载默认的语法规则  
ullGrammerID = 1000;  
hr=m_pSRContext->CreateGrammar(ullGrammerID,&m_pSRGrammar);

WCHAR wszXMLFile[20]=L"";  
MultiByteToWideChar(CP_ACP, 0,(LPCSTR)"cmd.xml" , -1, wszXMLFile, 256); //这里修改XML的目录  
hr=m_pSRGrammar->LoadCmdFromFile(wszXMLFile,SPLO_DYNAMIC);

//开启语音识别  
m_pSRGrammar->SetRuleState( NULL,NULL,SPRS_ACTIVE );  
hr=m_pSREngine->SetRecoState(SPRST_ACTIVE);


简单介绍

ISpRecognizer

There are two implementations of the ISpRecognizer and ISpRecoContext in SAPI. One is for recognition "in-process" (InProc), where the SR engine is created in the same process as the application. Only this application can connect to this recognizer. The other implementation is the "shared-recognizer," where the SR engine is created in a separate process. There will only be one shared engine running on a system, and all applications using the shared engine connect to the same recognizer. This allows several speech applications to work simultaneously, and allows the user to speak to any application, as recognition is done from the grammars of all applications. For desktop-based speech applications it is recommended to use the shared recognizer because of the way it allows multiple SAPI applications to work at once. For other types of application, such as recognizing from wave files or a telephony server application where multiple SR engines will be required, the InProc recognizer should be used.

  • When to Use
    Call methods of the ISpRecognizer interface to configure or retrieve the attributes of the SR engine.

  • How Created
    There are two objects that implement this interface. These are created by applications by creating a COM object with either of the following CLSIDs:
    SpInprocRecognizer (CLSID_SpInprocRecognizer)
    SpSharedRecognizer (CLSID_SpSharedRecognizer)
    Alternatively, the shared recognizer can be created by creating a SpSharedRecoContext (CLSID_SpSharedRecoContext), and then calling ISpRecoContext::GetRecognizer on this object to get a reference to the SpSharedRecognizer object.

Methods in Vtable Order

ISpRecognizer Methods Description SetRecognizer Specifies the SR engine to be used.
GetRecognizer Retrieves which SR engine is currently being used.
SetInput Specifies which input stream the SR engine should use.
GetInputObjectToken Retrieves the input token object for the stream.
GetInputStream Retrieves the input stream.
CreateRecoContext Creates a recognition context for this instance of an SR engine.
GetRecoProfile Retrieves the current recognition profile token.
SetRecoProfile Sets the recognition profile to be used by the recognizer.
IsSharedInstance Determines if the recognizer is the shared or InProc implementation.
GetRecoState Retrieves the state of the recognition engine.
SetRecoState Sets the state of the recognition engine.
GetStatus Retrieves current status information for the engine.
GetFormat Retrieves the format of the current audio input.
IsUISupported Checks if the SR engine supports a particular user interface component.
DisplayUI Displays a user interface component.
EmulateRecognition Emulates a recognition from a text phrase rather than from spoken audio.

context

ISpRecognizer::CreateRecoContext creates a recognition context for this instance of an SR engine. The recognition context is used to load recognition grammars, start and stop recognition, and receive events and recognition results.

SetNotifyWindowMessage

ISpNotifySource::SetNotifyWindowMessage
ISpNotifySource::SetNotifyWindowMessage sets up the instance to send window messages to a specified window.

HRESULT SetNotifyWindowMessage(  
HWND hWnd,  
UINT Msg,  
WPARAM wParam,  
LPARAM lParam  
);

input

SpCreateDefaultObjectFromCategoryId
SpCreateDefaultObjectFromCategoryId creates the object instance from the default object token of a specified category.

Found in: sphelper.h

SpCreateDefaultObjectFromCategoryId(  
const WCHAR *pszCategoryId,  
T **ppObject,  
IUnknown *pUnkOuter = NULL,  
DWORD dwClsCtxt = CLSCTX_ALL  
);

转载于:https://my.oschina.net/u/2598470/blog/2231638

没有更多推荐了,返回首页