2017-09-09 13:14:54 update_sh 阅读数 5291
  • C++语音识别开篇

    本篇mark老师将教大家使用第三方库的调用来简单的实现语音识别。随着机器学习和人工智能的热闹,国内语音行业也可谓是百花齐放。 语音识别一个伟大的时代已在我们身边悄悄走来。

    5921 人正在学习 去看看 杨波

百度语音识别通过REST API的方式给开发者提供一个通用的HTTP接口,基于该接口,开发者可以轻松的获取语音识别能力,本文档演示了如何在VS2017下使用语音识别服务REST API。

  1. https://ai.baidu.com/sdk#asr下载《识别、合成 REST API 开发文档、示例代码》,解压后里面有目录 example\linux c\
  2. 创建一个空的工程,example\linux c\复制过来,可以改一下目录名,我改成了baidu_voice,把此目录下的base64.cpp、base64.h、sample.cpp添加到工程里面来。还要把那个语音测试文件test.pcm也复制过来,如果你自己有pcm文件也可以。
  3. 此目录下的 curl和json-cpp都是linux版本的,我们需要换成windows版的,
    3.1. 网上下载的libcurl一般不支持https,所以需要我们自己编译,
    3.2. jsoncpp的源码我们直接从 https://github.com/open-source-parsers/jsoncpp ,执行 python.exe amalgamate.py(前提是要安装python)可以在dist目录生成所需要的文件,把dist下的json目录和jsoncpp.cpp复制到json-cpp目录下,并把jsoncpp.cpp添加进工程即可,不要添加lib
  4. 因为最新的jsoncpp的接口有所改变,所以对sample.cpp做如下改变:
    4.1. #include “json-cpp/include/json.h”改成#include “json-cpp/json/json.h”
    4.2. 若遇到错误:error C4996: ‘Json::Reader::Char’: Use CharReader and CharReaderBuilder instead,可以采取这两种办法:
    4.2.1. 把#include “json-cpp/json/json.h”改成下面:

    #pragma warning (push)
    #pragma warning (disable: 4996)
    #include "json-cpp/json/json.h"
    #pragma warning (pop)

    4.2.2. 在”json-cpp/json/json.h”里把 define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))注释掉。
    4.3. 把popen改成_popen,pclose改成_pclose
    4.4. fp = fopen(argv[1], “r”)改成fopen_s(&fp, argv[1], “r”)
    4.5. strcpy改成strcpy_s,strcat改成strcat_s
    4.6. Json处理部分改成如下:

    if (result != NULL)
    {
    Json::CharReaderBuilder b;
    Json::CharReader* reader(b.newCharReader());
    JSONCPP_STRING errs;
    Json::Value root;
    bool ok = reader->parse(result, result + std::strlen(result), &root, &errs);
    if (ok&&errs.size() == 0)
    {
    token = root.get("access_token","").asString();
    }
    delete reader;
    free(result);
    }
  5. 加入两个宏

    #define _METHOD_1_
    //#define _METHOD_2_

    表示采用哪一种方式上传语音数据。
  6. 把curl\lib添加到库目录,\curl\bin添加到可执行文件目录,在 配置属性->链接器->输入->附加依赖项添加libcurl.lib
  7. 在程序退出前添加代码:

    if (resultBuf != NULL) {
    free(resultBuf);
    }
  8. 在 配置属性->调试->命令参数 里面填写 test.pcm,就是上传的那个音频文件。
  9. 在调试之前,还要把cuid、apiKey、secretKey信息加上,这个去百度http://ai.baidu.com/注册账号,然后创建一个应用就可以看到了。
  10. 在调试的时候,发现调用 _popen打开curl.exe命令行的方式,总是得不到返回结果,所以用了libcurl的函数改写了一下。

    CURLcode getUrl(char* url, char** result)
    {
        CURL *curl;
        CURLcode res = CURL_LAST;
        curl = curl_easy_init();    // 初始化
        if (curl)
        {
            curl_easy_setopt(curl, CURLOPT_URL, url);
            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
            curl_easy_setopt(curl, CURLOPT_WRITEDATA, result);
    
            if (strncmp(url, "https://", 8) == 0)
            {
    
    #if 1     
    
                // 方法1, 设定为不验证证书和HOST  
                curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
                curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
    
    #else  
    
                // 方法2, 设定一个SSL判别证书, 未测试  
                curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1L)
                    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
                curl_easy_setopt(curl, CURLOPT_CAINFO, "ca-cert.pem");    // TODO: 设置一个证书文件  
    
    #endif
    
            }
            res = curl_easy_perform(curl);   // 执行
            if (res != CURLE_OK) {
                const char* strerr = curl_easy_strerror(res);
                *result = (char *)realloc(*result, strlen(strerr));
                strcpy_s(*result, strlen(strerr), strerr);
            }
            curl_easy_cleanup(curl);
        }
        return res;
    }
  11. 因为返回的是UTF8字符,所以最后又转了一次码。

需要源码的可以去这里下载 http://download.csdn.net/download/update_sh/9971150

2006-12-20 17:37:00 artlife 阅读数 4805
  • C++语音识别开篇

    本篇mark老师将教大家使用第三方库的调用来简单的实现语音识别。随着机器学习和人工智能的热闹,国内语音行业也可谓是百花齐放。 语音识别一个伟大的时代已在我们身边悄悄走来。

    5921 人正在学习 去看看 杨波
 
使用C++实现语音识别
语音识别,还记得星球大战里的那个总陪在主人身边听话的智能机器人么?拥有了听和说的技能,在那个时候这还是人们的想象,但是今天我们就可以来实现它!
微软的语音识别,在这里我们简称它为SR(speech recognition),SR分为两种模式的监听:第一种模式:任意监听,即随意输入语音,监听对象将最为接近的字或者词,句反馈出来;第二种模式:划定范围监听,制定一组被选项做为监听的,用户的语音输入被反馈成最为接近的一个选项。说得通俗一些:第一种是填空题,第二种是选择题目。
 
今天我们就一起来学习如何用C++ 来完成一道语音识别的填空题:
 
代码如下

 

 

#include <windows.h>
#include 
<sapi.h>
#include 
<stdio.h>
#include 
<string.h>
#include 
<atlbase.h>
#include 
"sphelper.h"
//Copyright (c) Microsoft Corporation. All rights reserved.

inline HRESULT BlockForResult(ISpRecoContext 
* pRecoCtxt, ISpRecoResult ** ppResult)
{
    HRESULT hr 
= S_OK;
    CSpEvent 
event;

    
while (SUCCEEDED(hr) &&
           SUCCEEDED(hr 
= event.GetFrom(pRecoCtxt)) &&
           hr 
== S_FALSE)
    
{
        hr 
= pRecoCtxt->WaitForNotifyEvent(INFINITE);
    }


    
*ppResult = event.RecoResult();
    
if (*ppResult)
    
{
        (
*ppResult)->AddRef();
    }


    
return hr;
}


const WCHAR * StopWord()
{
    
const WCHAR * pchStop;
    
    LANGID LangId 
= ::SpGetUserDefaultUILanguage();

    
switch (LangId)
    
{
        
case MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT):
            pchStop 
= L"}42N86/0b70e50fc0ea0e70fc/05708504608a087046";;
            
break;

        
default:
            pchStop 
= L"Stop";
            
break;
    }


    
return pchStop;
}

            
int main(int argc, char* argv[])
{
    HRESULT hr 
= E_FAIL;
    
bool fUseTTS = true;            // turn TTS play back on or off
    bool fReplay = true;            // turn Audio replay on or off

    
// Process optional arguments
    if (argc > 1)
    
{
        
int i;

        
for (i = 1; i < argc; i++)
        
{
            
if (_stricmp(argv[i], "-noTTS"== 0)
            
{
                fUseTTS 
= false;
                
continue;
            }

            
if (_stricmp(argv[i], "-noReplay"== 0)
            
{
                fReplay 
= false;
                
continue;
            }
       
            printf (
"Usage: %s [-noTTS] [-noReplay]  ", argv[0]);
            
return hr;
        }

    }


    
if (SUCCEEDED(hr = ::CoInitialize(NULL)))
    
{
        
{
            CComPtr
<ISpRecoContext> cpRecoCtxt;
            CComPtr
<ISpRecoGrammar> cpGrammar;
            CComPtr
<ISpVoice> cpVoice;
            hr 
= cpRecoCtxt.CoCreateInstance(CLSID_SpSharedRecoContext);
            
if(SUCCEEDED(hr))
            
{
                hr 
= cpRecoCtxt->GetVoice(&cpVoice);
            }

           
            
if (cpRecoCtxt && cpVoice &&
                SUCCEEDED(hr 
= cpRecoCtxt->SetNotifyWin32Event()) &&
                SUCCEEDED(hr 
= cpRecoCtxt->SetInterest(SPFEI(SPEI_RECOGNITION), SPFEI(SPEI_RECOGNITION))) &&
                SUCCEEDED(hr 
= cpRecoCtxt->SetAudioOptions(SPAO_RETAIN_AUDIO, NULL, NULL)) &&
                SUCCEEDED(hr 
= cpRecoCtxt->CreateGrammar(0&cpGrammar)) &&
                SUCCEEDED(hr 
= cpGrammar->LoadDictation(NULL, SPLO_STATIC)) &&
                SUCCEEDED(hr 
= cpGrammar->SetDictationState(SPRS_ACTIVE)))
            
{
                USES_CONVERSION;
                            
                
const WCHAR * const pchStop = StopWord();
                CComPtr
<ISpRecoResult> cpResult;

                printf( 
"I will repeat everything you say. Say "%s" to exit. ", W2A(pchStop) );

                
while (SUCCEEDED(hr = BlockForResult(cpRecoCtxt, &cpResult)))
                
{
                    cpGrammar
->SetDictationState( SPRS_INACTIVE );

                    CSpDynamicString dstrText;

                    
if (SUCCEEDED(cpResult->GetText(SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE, 
                                                    TRUE, 
&dstrText, NULL)))
                    
{
                        printf(
"I heard:  %s ", W2A(dstrText));

                        
if (fUseTTS)
                        
{
                            cpVoice
->Speak( L"I heard", SPF_ASYNC, NULL);
                            cpVoice
->Speak( dstrText, SPF_ASYNC, NULL );
                        }


                        
if (fReplay)
                        
{
                            
if (fUseTTS)
                                cpVoice
->Speak( L"when you said", SPF_ASYNC, NULL);
                            
else
                                printf (
" when you said... ");
                            cpResult
->SpeakAudio(NULL, 0, NULL, NULL);
                       }


                       cpResult.Release();
                    }

                    
if (_wcsicmp(dstrText, pchStop) == 0)
                    
{
                        
break;
                    }

                    
                    cpGrammar
->SetDictationState( SPRS_ACTIVE );
                }
 
            }

        }

        ::CoUninitialize();
    }

    
return hr;
}

2016-11-28 23:25:39 qq_34369618 阅读数 5950
  • C++语音识别开篇

    本篇mark老师将教大家使用第三方库的调用来简单的实现语音识别。随着机器学习和人工智能的热闹,国内语音行业也可谓是百花齐放。 语音识别一个伟大的时代已在我们身边悄悄走来。

    5921 人正在学习 去看看 杨波

C++语音识别接口快速入门(Microsoft Speech SDK)
尤其注意其中的宽字符串转化

#include <iostream>
#include <sapi.h> //导入语音头文件
#include <string>
#pragma comment(lib,"sapi.lib") //导入语音头文件库

void  MSSSpeak(LPCTSTR speakContent)// speakContent为LPCTSTR型的字符串,调用此函数即可将文字转为语音
{
    ISpVoice *pVoice = NULL;

    //初始化COM接口

    if (FAILED(::CoInitialize(NULL)))
        MessageBox(NULL, (LPCWSTR)L"COM接口初始化失败!", (LPCWSTR)L"提示", MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2);

    //获取SpVoice接口

    HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void**)&pVoice);


    if (SUCCEEDED(hr))
    {
        pVoice->SetVolume((USHORT)100); //设置音量,范围是 0 -100
        pVoice->SetRate(0); //设置速度,范围是 -10 - 10
        hr = pVoice->Speak(speakContent, 0, NULL);

        pVoice->Release();

        pVoice = NULL;
    }

    //释放com资源
    ::CoUninitialize();
}
int main()
{
    std::wstring a = L"我爱谢贤";
    LPCWSTR str = a.c_str();
    /*不知道为什么Cstr不行*/
    MSSSpeak(str);
    return 0;
}
2019-03-21 13:26:18 active2489595970 阅读数 133
  • C++语音识别开篇

    本篇mark老师将教大家使用第三方库的调用来简单的实现语音识别。随着机器学习和人工智能的热闹,国内语音行业也可谓是百花齐放。 语音识别一个伟大的时代已在我们身边悄悄走来。

    5921 人正在学习 去看看 杨波

https://blog.csdn.net/michaelliang12/article/details/51317531#c语音识别接口快速入门microsoft-speech-sdk

 

C++语音识别接口快速入门(Microsoft Speech SDK)
最近毕业设计用到了微软的C++语音识别接口,查找了很多资料,也碰到了很多问题,走了很多弯路。现在把我自己的经验写下来,一是提升自己,二是回报社会。希望大家看了这篇blog之后,5min就学会C++语音识别接口的实现。(采用的平台为win8+VS2013)

目录
C语音识别接口快速入门Microsoft Speech SDK
目录
一安装SDK
二新建工程配置环境
三语音识别代码
1文字转语音
2语音转文字
源代码下载
参考网站
一、安装SDK
安装MicrosoftSpeechPlatformSDK.msi,默认路径安装即可。 
下载路径: 
http://download.csdn.net/detail/michaelliang12/9510691

二、新建工程,配置环境
设置: 
1,属性–配置属性–C/C++–常规–附加包含目录:C:\Program Files\Microsoft SDKs\Speech\v11.0\Include(具体路径与安装路径有关) 
2,属性–配置属性–链接器–输入–附加依赖项:sapi.lib;

三、语音识别代码
语音识别接口可分为文字转语音和语音转文字

1、文字转语音
需要添加的头文件:

#include <sapi.h> //导入语音头文件
#pragma comment(lib,"sapi.lib") //导入语音头文件库
1
2
3
函数:

void  CBodyBasics::MSSSpeak(LPCTSTR speakContent)// speakContent为LPCTSTR型的字符串,调用此函数即可将文字转为语音
{
    ISpVoice *pVoice = NULL;

    //初始化COM接口

    if (FAILED(::CoInitialize(NULL)))
        MessageBox(NULL, (LPCWSTR)L"COM接口初始化失败!", (LPCWSTR)L"提示", MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2);

    //获取SpVoice接口

    HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void**)&pVoice);


    if (SUCCEEDED(hr))
    {
        pVoice->SetVolume((USHORT)100); //设置音量,范围是 0 -100
        pVoice->SetRate(2); //设置速度,范围是 -10 - 10
        hr = pVoice->Speak(speakContent, 0, NULL);

        pVoice->Release();

        pVoice = NULL;
    }

    //释放com资源
    ::CoUninitialize();
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2、语音转文字
这个稍微麻烦一点,因为需要实时监控麦克风,涉及到windows的消息机制。 
(1)首先设置工程属性: 
属性–配置属性–C/C++–预处理器–预处理器定义:_WIN32_DCOM;

(2)需要添加的头文件:

#include <sapi.h> //导入语音头文件
#pragma comment(lib,"sapi.lib") //导入语音头文件库
#include <sphelper.h>//语音识别头文件
#include <atlstr.h>//要用到CString

#pragma once
const int WM_RECORD = WM_USER + 100;//定义消息
1
2
3
4
5
6
7
(3)在程序的.h头文件中定义变量

//定义变量
CComPtr<ISpRecognizer>m_cpRecoEngine;// 语音识别引擎(recognition)的接口。
CComPtr<ISpRecoContext>m_cpRecoCtxt;// 识别引擎上下文(context)的接口。
CComPtr<ISpRecoGrammar>m_cpCmdGrammar;// 识别文法(grammar)的接口。
CComPtr<ISpStream>m_cpInputStream;// 流()的接口。
CComPtr<ISpObjectToken>m_cpToken;// 语音特征的(token)接口。
CComPtr<ISpAudio>m_cpAudio;// 音频(Audio)的接口。(用来保存原来默认的输入流)
ULONGLONG  ullGrammerID;
1
2
3
4
5
6
7
8
9
(4)创建语音识别初始化函数(程序刚开始执行的时候调用,例如文末示例代码中,将此初始化函数放在对话框初始化消息WM_INITDIALOG的响应代码里)

//语音识别初始化函数
void  CBodyBasics::MSSListen()
{

    //初始化COM接口

    if (FAILED(::CoInitialize(NULL)))
        MessageBox(NULL, (LPCWSTR)L"COM接口初始化失败!", (LPCWSTR)L"提示", MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2);


    HRESULT hr = m_cpRecoEngine.CoCreateInstance(CLSID_SpSharedRecognizer);//创建Share型识别引擎
    if (SUCCEEDED(hr))
    {


        hr = m_cpRecoEngine->CreateRecoContext(&m_cpRecoCtxt);//创建识别上下文接口

        hr = m_cpRecoCtxt->SetNotifyWindowMessage(m_hWnd, WM_RECORD, 0, 0);//设置识别消息

        const ULONGLONG ullInterest = SPFEI(SPEI_SOUND_START) | SPFEI(SPEI_SOUND_END) | SPFEI(SPEI_RECOGNITION);//设置我们感兴趣的事件
        hr = m_cpRecoCtxt->SetInterest(ullInterest, ullInterest);

        hr = SpCreateDefaultObjectFromCategoryId(SPCAT_AUDIOIN, &m_cpAudio);
        m_cpRecoEngine->SetInput(m_cpAudio, true);

        //创建语法规则
        //dictation听说式
        //hr = m_cpRecoCtxt->CreateGrammar(GIDDICTATION, &m_cpDictationGrammar);
        //if (SUCCEEDED(hr))
        //{
        //  hr = m_cpDictationGrammar->LoadDictation(NULL, SPLO_STATIC);//加载词典
        //}

        //C&C命令式,此时语法文件使用xml格式
        ullGrammerID = 1000;
        hr = m_cpRecoCtxt->CreateGrammar(ullGrammerID, &m_cpCmdGrammar);

        WCHAR wszXMLFile[20] = L"";//加载语法
        MultiByteToWideChar(CP_ACP, 0, (LPCSTR)"CmdCtrl.xml", -1, wszXMLFile, 256);//ANSI转UNINCODE
        hr = m_cpCmdGrammar->LoadCmdFromFile(wszXMLFile, SPLO_DYNAMIC);


        //MessageBox(NULL, (LPCWSTR)L"语音识别已启动!", (LPCWSTR)L"提示", MB_CANCELTRYCONTINUE );
        //激活语法进行识别
        //hr = m_cpDictationGrammar->SetDictationState(SPRS_ACTIVE);//dictation
        hr = m_cpCmdGrammar->SetRuleState(NULL, NULL, SPRS_ACTIVE);//C&C
        hr = m_cpRecoEngine->SetRecoState(SPRST_ACTIVE);

    }

    else
    {
        MessageBox(NULL, (LPCWSTR)L"语音识别引擎启动出错!", (LPCWSTR)L"警告", MB_OK);
        exit(0);
    }


    //释放com资源
    ::CoUninitialize();
    //hr = m_cpCmdGrammar->SetRuleState(NULL, NULL, SPRS_INACTIVE);//C&C


}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
(5)定义消息处理函数 
需要和其他的消息处理代码放在一起,如本文代码中,放在文末示例代码的DlgProc()函数尾部。本文整个其他的代码块都可以直接照搬,只需要更改如下的消息反应模块即可

//消息处理函数
USES_CONVERSION;
    CSpEvent event;

    if (m_cpRecoCtxt)
    {
        while (event.GetFrom(m_cpRecoCtxt) == S_OK){

            switch (event.eEventId)
            {
            case SPEI_RECOGNITION:
            {
                                     //识别出了语音
                                     m_bGotReco = TRUE; 

                                     static const WCHAR wszUnrecognized[] = L"<Unrecognized>";

                                     CSpDynamicString dstrText;

                                     ////取得识别结果 
                                     if (FAILED(event.RecoResult()->GetText(SP_GETWHOLEPHRASE, SP_GETWHOLEPHRASE, TRUE, &dstrText, NULL)))
                                     {
                                         dstrText = wszUnrecognized;
                                     }

                                     BSTR SRout;
                                     dstrText.CopyToBSTR(&SRout);
                                     CString Recstring;
                                     Recstring.Empty();
                                     Recstring = SRout;

                                    //做出反应(*****消息反应模块*****)
                                    if (Recstring == "发短信")
                                     {
                                         //MessageBox(NULL, (LPCWSTR)L"好的", (LPCWSTR)L"提示", MB_OK);
                                         MSSSpeak(LPCTSTR(_T("好,马上发短信!")));

                                     }

                                     else if (Recstring == "李雷")
                                     {
                                         MSSSpeak(LPCTSTR(_T("好久没看见他了,真是 long time no see")));
                                     }   

            }
                break;
            }
        }
    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
(6)修改语法文件 
修改CmdCtrl.xml文件,可以提高某些词汇的识别度,对里面的词识别效果会很好多,如人名等。(此外,单独运行exe时也需要将此文件和exe放在同一文件夹内,不放也不会报错,只是语法文件里的词汇识别效果变差)

<?xml version="1.0" encoding="utf-8"?>
<GRAMMAR LANGID="804">
  <DEFINE>
    <ID NAME="VID_SubName1" VAL="4001"/>
    <ID NAME="VID_SubName2" VAL="4002"/>
    <ID NAME="VID_SubName3" VAL="4003"/>
    <ID NAME="VID_SubName4" VAL="4004"/>
    <ID NAME="VID_SubName5" VAL="4005"/>
    <ID NAME="VID_SubName6" VAL="4006"/>
    <ID NAME="VID_SubName7" VAL="4007"/>
    <ID NAME="VID_SubName8" VAL="4008"/>
    <ID NAME="VID_SubName9" VAL="4009"/>
    <ID NAME="VID_SubNameRule" VAL="3001"/>
    <ID NAME="VID_TopLevelRule" VAL="3000"/>
  </DEFINE>
  <RULE ID="VID_TopLevelRule" TOPLEVEL="ACTIVE">
    <O>
      <L>
        <P>我要</P>
        <P>运行</P>
        <P>执行</P>
      </L>
    </O>
    <RULEREF REFID="VID_SubNameRule" />
  </RULE>
  <RULE ID="VID_SubNameRule" >
    <L PROPID="VID_SubNameRule">
      <P VAL="VID_SubName1">发短信</P>
      <P VAL="VID_SubName2">是的</P>
      <P VAL="VID_SubName3">好的</P>
      <P VAL="VID_SubName4">不用</P>
      <P VAL="VID_SubName5">李雷</P>
      <P VAL="VID_SubName6">韩梅梅</P>
      <P VAL="VID_SubName7">中文界面</P>
      <P VAL="VID_SubName8">英文界面</P>
      <P VAL="VID_SubName9">English</P>

    </L>
  </RULE>
</GRAMMAR>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
源代码下载
注意,本代码是在原来的项目中截取出来的,但可以独立运行。 
Microsoft Speech SDK 安装包下载: 
http://download.csdn.net/detail/michaelliang12/9510691 
文中示例程序下载(之前下载分数太高,我已经重新上传了新版本,也解决了kincect20.lib报错的问题。由于自己经常在csdn上下东西,也需要积分,需要还是需要各位捧场,2积分。。): 
http://download.csdn.net/detail/michaelliang12/9766783

存在的bug:每次运行完程序,Windows的语音识别助手不会自动关闭,需要自己手动关闭。若不关闭,则下次启动程序可能会出错。大家如果有好的解决办法,请联系我,谢了!

参考网站
1,http://www.cnblogs.com/eping/archive/2010/05/23/1742201.html 
2,http://blog.csdn.net/pamchen/article/details/7856207 
3,http://blog.csdn.net/jmxiaocai/article/details/7036033 
4,http://blog.csdn.net/buaalei/article/details/5372544(主要参考) 
5,http://blog.csdn.net/itcastcpp/article/details/5313204 
6,http://blog.csdn.net/artemisrj/article/details/8723095(MFC的消息处理响应版本)
--------------------- 
作者:Michael__CSDN 
来源:CSDN 
原文:https://blog.csdn.net/michaelliang12/article/details/51317531 
版权声明:本文为博主原创文章,转载请附上博文链接!

2014-06-25 20:03:31 zpf8861 阅读数 5575
  • C++语音识别开篇

    本篇mark老师将教大家使用第三方库的调用来简单的实现语音识别。随着机器学习和人工智能的热闹,国内语音行业也可谓是百花齐放。 语音识别一个伟大的时代已在我们身边悄悄走来。

    5921 人正在学习 去看看 杨波

上一篇文章http://blog.csdn.net/zpf8861/article/details/32322089已经介绍了百度语音识别REST API的使用步骤和功能介绍,这篇文章主要通过一个实例代码来展示如何使用该API。

本文代码为C++版,可以用于C环境的应用开发中,下面介绍其中重要的代码。

下面代码是一个可以使用该方式进行语音识别功能的实例代码

#include <stdio.h>
#include <stdlib.h>
#include "curl/include/curl/curl.h"
#include "curl/include/curl/easy.h"
#include "json-cpp/include/json.h"
#include "base64.h"

#define MAX_BUFFER_SIZE 512
#define MAX_BODY_SIZE 1000000


static size_t writefunc(void *ptr, size_t size, size_t nmemb, char **result)
{
    size_t result_len = size * nmemb;
    *result = (char *)realloc(*result, result_len + 1);
    if (*result == NULL)
    {
        printf("realloc failure!\n");
        return 1;
    }
    memcpy(*result, ptr, result_len);
    (*result)[result_len] = '\0';
    printf("%s\n", *result);
    return result_len;
}


int main (int argc,char* argv[])
{
    if (argc != 2)
    {
        printf("Usage: %s audiofile\n", argv[0]);
        return -1;
    }

    FILE *fp = NULL;
    fp = fopen(argv[1], "r");
    if (NULL == fp)
    {
        return -1;
    }
    fseek(fp, 0, SEEK_END);
    int content_len = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    char *audiodata = (char *)malloc(content_len);
    fread(audiodata, content_len, sizeof(char), fp);

    //put your own params here
    char *cuid = "";
    char *apiKey = "";
    char *secretKey = "";

    std::string token;
    char host[MAX_BUFFER_SIZE];
    snprintf(host, sizeof(host), 
            "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s", 
            apiKey, secretKey);
    FILE* fpp = NULL;
    char cmd[MAX_BUFFER_SIZE];
    char* result = (char*)malloc(MAX_BUFFER_SIZE);
    char* curl_cmd = "curl -s ";
    char* yinhao = "\"";
    strcpy(cmd, curl_cmd);
    strcat(cmd, yinhao);
    strcat(cmd, host);
    strcat(cmd, yinhao);
    fpp = popen(cmd, "r");
    fgets(result, MAX_BUFFER_SIZE, fpp);
    pclose(fpp);

    if (result != NULL) 
    {
        Json::Reader reader;
        Json::Value root;
        if (reader.parse(result, root, false)) 
        {
            token = root.get("access_token","").asString();
        }
    }

    memset(host, 0, sizeof(host));
    snprintf(host, sizeof(host), "%s", "http://vop.baidu.com/server_api");

#ifdef _METHOD_1_
    //method 1
    char tmp[MAX_BUFFER_SIZE];
    memset(tmp, 0, sizeof(tmp));
    char body[MAX_BODY_SIZE];
    memset(body, 0, sizeof(body));
    std::string decode_data = base64_encode((const unsigned char *)audiodata, content_len);
    if (0 == decode_data.length())
    {
        printf("base64 encoded data is empty.\n");
        return 1;
    }
    
    Json::Value buffer;
    Json::FastWriter trans;
    buffer["format"]  = "pcm";
    buffer["rate"]    = 8000;
    buffer["channel"] = 1;
    buffer["token"]   = token.c_str();
    buffer["cuid"]    = cuid;
    buffer["speech"]  = decode_data;
    buffer["len"]     = content_len;
//    buffer["url"]  = url;
//    buffer["callback"]     = callback;

    content_len = trans.write(buffer).length();
    memcpy(body, trans.write(buffer).c_str(), content_len);

    CURL *curl;
    CURLcode res;
    char *resultBuf = NULL;
    struct curl_slist *headerlist = NULL;
    snprintf(tmp, sizeof(tmp), "%s", "Content-Type: application/json; charset=utf-8");
    headerlist = curl_slist_append(headerlist, tmp);
    snprintf(tmp, sizeof(tmp), "Content-Length: %d", content_len);
    headerlist = curl_slist_append(headerlist, tmp);

    curl = curl_easy_init();
    curl_easy_setopt(curl, CURLOPT_URL, host);
    curl_easy_setopt(curl, CURLOPT_POST, 1);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30);
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, content_len);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resultBuf);
    res = curl_easy_perform(curl);
    if (res != CURLE_OK)
    {
        printf("perform curl error:%d.\n", res);
        return 1;
    }
    curl_slist_free_all(headerlist);
    curl_easy_cleanup(curl);

#endif

#ifdef _METHOD_2_
    //second way, post raw data
    char tmp[MAX_BUFFER_SIZE];
    memset(tmp, 0, sizeof(tmp));
    snprintf(tmp, sizeof(tmp), "?cuid=%s&token=%s", cuid, token.c_str());
    strcat(host, tmp);

    CURL *curl;
    CURLcode res;
    char *resultBuf = NULL;
    struct curl_slist *headerlist = NULL;
    snprintf(tmp, sizeof(tmp), "%s","Content-Type: audio/pcm; rate=8000");
    headerlist = curl_slist_append(headerlist, tmp);
    snprintf(tmp, sizeof(tmp), "Content-Length: %d", content_len);
    headerlist = curl_slist_append(headerlist, tmp);

    curl = curl_easy_init();
    curl_easy_setopt(curl, CURLOPT_URL, host);
    curl_easy_setopt(curl, CURLOPT_POST, 1);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30); 
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, audiodata);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, content_len);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resultBuf);
    res = curl_easy_perform(curl);
    if (res != CURLE_OK)
    {
        printf("perform curl error:%d.\n", res);
        return 1;
    }
    curl_slist_free_all(headerlist);
    curl_easy_cleanup(curl);

#endif
    fclose(fp);
    free(audiodata);
    return 0;
}


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