├── README.md ├── a.out ├── bin ├── a.out └── test ├── close_light.py ├── include └── voice │ ├── msp_cmn.h │ ├── msp_errors.h │ ├── msp_types.h │ ├── qisr.h │ ├── qtts.h │ └── voice.h ├── msc ├── c5055263abe6fbd16bfd416c72e48391 │ ├── u.data │ └── urec.data └── user.perf ├── obj ├── libmsc.so ├── libmsc.so1 └── voice.o ├── open_light.py ├── src ├── main.c └── voice.c ├── test ├── test.wav ├── wav ├── close_light.mp3 ├── cmd_voice_temp │ └── voice_cmd.wav ├── compose_voice_temp │ ├── compose_voice.wav │ └── compose_voice_all.wav ├── open_light.mp3 └── sys_voice │ ├── closed_voice_recongnition.wav │ └── opened_voice_recongnition.wav ├── 树莓派管脚.png ├── 流程图.png ├── 目录.png └── 说明.txt /README.md: -------------------------------------------------------------------------------- 1 | # 该项目将进行重构,底层基于c\c++,上层封装出python,欢迎关注新项目主页。 2 | 3 | https://github.com/1158114251/VoiceAssistantOs 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | # -Intelligent-speech-robot 19 | 基于百度语音 讯飞语音 图灵机器人,贝壳物联 的智能语音机器人,硬件使用了树莓派和arduino,树莓派和arduino的通信主要是网络和串口。 20 | 实现了家电控制,和语音联网交流问答,后期添加语音播报新闻等 21 | 22 | ## 基本实现原理是基于讯飞语音的识别和图灵机器人的具体智能反馈,百度语音的播放,原因是讯飞语音的free版似乎播放做了限制 23 | 24 | 25 | # 视频地址 http://www.365yg.com/item/6432161703055589890/ 26 | 27 | 28 | -------------------------------------------------------------------------------- /a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1158114251/-Intelligent-speech-robot/ebcd036427c8a50098deff50c93eebefa057adaa/a.out -------------------------------------------------------------------------------- /bin/a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1158114251/-Intelligent-speech-robot/ebcd036427c8a50098deff50c93eebefa057adaa/bin/a.out -------------------------------------------------------------------------------- /bin/test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1158114251/-Intelligent-speech-robot/ebcd036427c8a50098deff50c93eebefa057adaa/bin/test -------------------------------------------------------------------------------- /close_light.py: -------------------------------------------------------------------------------- 1 | # telnet program example 2 | import socket, select, string, sys 3 | import time 4 | import os 5 | def prompt() : 6 | print("333") 7 | sys.stdout.write(' ') 8 | sys.stdout.flush() 9 | 10 | #main function 11 | if __name__ == "__main__": 12 | 13 | # if(len(sys.argv) < 3) : 14 | # print ('Usage : python telnet.py hostname port') 15 | # sys.exit() 16 | 17 | host = "www.bigiot.net" 18 | port = 8181 19 | 20 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 21 | s.settimeout(2) 22 | 23 | # connect to remote host 24 | try : 25 | s.connect((host, port)) 26 | except : 27 | print ('Unable to connect') 28 | sys.exit() 29 | 30 | print ('Connected to remote host. Start sending messages') 31 | checkinBytes=bytes('{\"M\":\"checkin\",\"ID\":\"2068\",\"K\":\"7b0361f93\"}\n') 32 | s.sendall(checkinBytes) 33 | time.sleep(1) 34 | checkinBytes=bytes('{\"M\":\"say\",\"ID\":\"D2315\",\"C\":\"play\"}\n') 35 | s.sendall(checkinBytes) 36 | time.sleep(1) 37 | # os.system("mplayer wav/close_light.mp3") 38 | prompt() 39 | s.close() 40 | -------------------------------------------------------------------------------- /include/voice/msp_cmn.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file msp_cmn.h 3 | * @brief Mobile Speech Platform Common Interface Header File 4 | * 5 | * This file contains the quick common programming interface (API) declarations 6 | * of MSP. Developer can include this file in your project to build applications. 7 | * For more information, please read the developer guide. 8 | 9 | * Use of this software is subject to certain restrictions and limitations set 10 | * forth in a license agreement entered into between iFLYTEK, Co,LTD. 11 | * and the licensee of this software. Please refer to the license 12 | * agreement for license use rights and restrictions. 13 | * 14 | * Copyright (C) 1999 - 2015 by iFLYTEK, Co,LTD. 15 | * All rights reserved. 16 | * 17 | * @author MSC 18 | * @version 5.0 19 | * @date 2015/03/19 20 | * 21 | * @see 22 | * 23 | * History:
24 | * 25 | * 26 | * 27 | *
Version Date Author Notes
5.0 2015/03/19 MSC Create this file
28 | */ 29 | 30 | #ifndef __MSP_CMN_H__ 31 | #define __MSP_CMN_H__ 32 | 33 | #include "msp_types.h" 34 | 35 | #ifdef __cplusplus 36 | extern "C" { 37 | #endif /* C++ */ 38 | 39 | /** 40 | * @fn MSPLogin 41 | * @brief user login interface 42 | * 43 | * User login. 44 | * 45 | * @return int MSPAPI - Return 0 in success, otherwise return error code. 46 | * @param const char* usr - [in] user name. 47 | * @param const char* pwd - [in] password. 48 | * @param const char* params - [in] parameters when user login. 49 | * @see 50 | */ 51 | int MSPAPI MSPLogin(const char* usr, const char* pwd, const char* params); 52 | typedef int (MSPAPI *Proc_MSPLogin)(const char* usr, const char* pwd, const char* params); 53 | 54 | /** 55 | * @fn MSPLogout 56 | * @brief user logout interface 57 | * 58 | * User logout 59 | * 60 | * @return int MSPAPI - Return 0 in success, otherwise return error code. 61 | * @see 62 | */ 63 | int MSPAPI MSPLogout(); 64 | typedef int (MSPAPI *Proc_MSPLogout)(); 65 | 66 | /** 67 | * @fn MSPGetResult 68 | * @brief Get Result 69 | * 70 | * Get result of uploading, downloading or searching, etc. 71 | * 72 | * @return const char* MSPAPI - Return result of uploading, downloading or searching, etc. 73 | * @param int* rsltLen - [out] Length of result returned. 74 | * @param int* rsltStatus - [out] Status of result returned. 75 | * @param int* errorCode - [out] Return 0 in success, otherwise return error code. 76 | * @see 77 | */ 78 | const char* MSPAPI MSPGetResult(unsigned int* rsltLen, int* rsltStatus, int *errorCode); 79 | typedef const char * (MSPAPI *Proc_MSPGetResult)(unsigned int* rsltLen, int* rsltStatus, int *errorCode); 80 | 81 | /** 82 | * @fn MSPSetParam 83 | * @brief set params of msc 84 | * 85 | * set param of msc 86 | * 87 | * @return int - Return 0 if success, otherwise return errcode. 88 | * @param const char* paramName - [in] param name. 89 | * @param const char* paramValue - [in] param value 90 | * @see 91 | */ 92 | int MSPAPI MSPSetParam( const char* paramName, const char* paramValue ); 93 | typedef int (MSPAPI *Proc_MSPSetParam)(const char* paramName, const char* paramValue); 94 | 95 | /** 96 | * @fn MSPGetParam 97 | * @brief get params of msc 98 | * 99 | * get param of msc 100 | * 101 | * @return int - Return 0 if success, otherwise return errcode. 102 | * @param const char* paramName - [in] param name. 103 | * @param const char* paramValue - [out] param value 104 | * @param const char* valueLen - [in/out] param value (buffer) length 105 | * @see 106 | */ 107 | int MSPAPI MSPGetParam( const char *paramName, char *paramValue, unsigned int *valueLen ); 108 | typedef int (MSPAPI *Proc_MSPGetParam)( const char *paramName, char *paramValue, unsigned int *valueLen ); 109 | 110 | /** 111 | * @fn MSPUploadData 112 | * @brief Upload User Specific Data 113 | * 114 | * Upload data such as user config, custom grammar, etc. 115 | * 116 | * @return const char* MSPAPI - data id returned by Server, used for special command. 117 | * @param const char* dataName - [in] data name, should be unique to diff other data. 118 | * @param void* data - [in] the data buffer pointer, data could be binary. 119 | * @param unsigned int dataLen - [in] length of data. 120 | * @param const char* params - [in] parameters about uploading data. 121 | * @param int* errorCode - [out] Return 0 in success, otherwise return error code. 122 | * @see 123 | */ 124 | const char* MSPAPI MSPUploadData(const char* dataName, void* data, unsigned int dataLen, const char* params, int* errorCode); 125 | typedef const char* (MSPAPI* Proc_MSPUploadData)(const char* dataName, void* data, unsigned int dataLen, const char* params, int* errorCode); 126 | 127 | /** 128 | * @fn MSPDownloadData 129 | * @brief Download User Specific Data 130 | * 131 | * Download data such as user config, etc. 132 | * 133 | * @return const void* MSPAPI - received data buffer pointer, data could be binary, NULL if failed or data does not exsit. 134 | * @param const char* params - [in] parameters about data to be downloaded. 135 | * @param unsigned int* dataLen - [out] length of received data. 136 | * @param int* errorCode - [out] Return 0 in success, otherwise return error code. 137 | * @see 138 | */ 139 | const void* MSPAPI MSPDownloadData(const char* params, unsigned int* dataLen, int* errorCode); 140 | typedef const void* (MSPAPI* Proc_MSPDownloadData)(const char* params, unsigned int* dataLen, int* errorCode); 141 | 142 | /** 143 | * @fn MSPSearch 144 | * @brief Search text for result 145 | * 146 | * Search text content, and got text result 147 | * 148 | * @return const void* MSPAPI - received data buffer pointer, data could be binary, NULL if failed or data does not exsit. 149 | * @param const char* params - [in] parameters about data to be downloaded. 150 | * @param unsigned int* dataLen - [out] length of received data. 151 | * @param int* errorCode - [out] Return 0 in success, otherwise return error code. 152 | * @see 153 | */ 154 | const char* MSPAPI MSPSearch(const char* params, const char* text, unsigned int* dataLen, int* errorCode); 155 | typedef const char* (MSPAPI* Proc_MSPSearch)(const char* params, const char* text, unsigned int* dataLen, int* errorCode); 156 | 157 | typedef int (*NLPSearchCB)(const char *sessionID, int errorCode, int status, const void* result, long rsltLen, void *userData); 158 | const char* MSPAPI MSPNlpSearch(const char* params, const char* text, unsigned int textLen, int *errorCode, NLPSearchCB callback, void *userData); 159 | typedef const char* (MSPAPI* Proc_MSPNlpSearch)(const char* params, const char* text, unsigned int textLen, int *errorCode, NLPSearchCB callback, void *userData); 160 | int MSPAPI MSPNlpSchCancel(const char *sessionID, const char *hints); 161 | 162 | /** 163 | * @fn MSPRegisterNotify 164 | * @brief Register a Callback 165 | * 166 | * Register a Callback 167 | * 168 | * @return int - 169 | * @param msp_status_ntf_handler statusCb - [in] notify handler 170 | * @param void *userData - [in] userData 171 | * @see 172 | */ 173 | typedef void ( *msp_status_ntf_handler)( int type, int status, int param1, const void *param2, void *userData ); 174 | int MSPAPI MSPRegisterNotify( msp_status_ntf_handler statusCb, void *userData ); 175 | typedef const char* (MSPAPI* Proc_MSPRegisterNotify)( msp_status_ntf_handler statusCb, void *userData ); 176 | 177 | #ifdef __cplusplus 178 | } /* extern "C" */ 179 | #endif /* C++ */ 180 | 181 | #endif /* __MSP_CMN_H__ */ 182 | -------------------------------------------------------------------------------- /include/voice/msp_errors.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1158114251/-Intelligent-speech-robot/ebcd036427c8a50098deff50c93eebefa057adaa/include/voice/msp_errors.h -------------------------------------------------------------------------------- /include/voice/msp_types.h: -------------------------------------------------------------------------------- 1 | #ifndef __MSP_TYPES_H__ 2 | #define __MSP_TYPES_H__ 3 | 4 | #if !defined(MSPAPI) 5 | #if defined(WIN32) 6 | #define MSPAPI __stdcall 7 | #else 8 | #define MSPAPI 9 | #endif /* WIN32 */ 10 | #endif /* MSPAPI */ 11 | 12 | 13 | /** 14 | * MSPSampleStatus indicates how the sample buffer should be handled 15 | * MSP_AUDIO_SAMPLE_FIRST - The sample buffer is the start of audio 16 | * If recognizer was already recognizing, it will discard 17 | * audio received to date and re-start the recognition 18 | * MSP_AUDIO_SAMPLE_CONTINUE - The sample buffer is continuing audio 19 | * MSP_AUDIO_SAMPLE_LAST - The sample buffer is the end of audio 20 | * The recognizer will cease processing audio and 21 | * return results 22 | * Note that sample statii can be combined; for example, for file-based input 23 | * the entire file can be written with SAMPLE_FIRST | SAMPLE_LAST as the 24 | * status. 25 | * Other flags may be added in future to indicate other special audio 26 | * conditions such as the presence of AGC 27 | */ 28 | enum 29 | { 30 | MSP_AUDIO_SAMPLE_INIT = 0x00, 31 | MSP_AUDIO_SAMPLE_FIRST = 0x01, 32 | MSP_AUDIO_SAMPLE_CONTINUE = 0x02, 33 | MSP_AUDIO_SAMPLE_LAST = 0x04, 34 | }; 35 | 36 | /* 37 | * The enumeration MSPRecognizerStatus contains the recognition status 38 | * MSP_REC_STATUS_SUCCESS - successful recognition with partial results 39 | * MSP_REC_STATUS_NO_MATCH - recognition rejected 40 | * MSP_REC_STATUS_INCOMPLETE - recognizer needs more time to compute results 41 | * MSP_REC_STATUS_NON_SPEECH_DETECTED - discard status, no more in use 42 | * MSP_REC_STATUS_SPEECH_DETECTED - recognizer has detected audio, this is delayed status 43 | * MSP_REC_STATUS_COMPLETE - recognizer has return all result 44 | * MSP_REC_STATUS_MAX_CPU_TIME - CPU time limit exceeded 45 | * MSP_REC_STATUS_MAX_SPEECH - maximum speech length exceeded, partial results may be returned 46 | * MSP_REC_STATUS_STOPPED - recognition was stopped 47 | * MSP_REC_STATUS_REJECTED - recognizer rejected due to low confidence 48 | * MSP_REC_STATUS_NO_SPEECH_FOUND - recognizer still found no audio, this is delayed status 49 | */ 50 | enum 51 | { 52 | MSP_REC_STATUS_SUCCESS = 0, 53 | MSP_REC_STATUS_NO_MATCH = 1, 54 | MSP_REC_STATUS_INCOMPLETE = 2, 55 | MSP_REC_STATUS_NON_SPEECH_DETECTED = 3, 56 | MSP_REC_STATUS_SPEECH_DETECTED = 4, 57 | MSP_REC_STATUS_COMPLETE = 5, 58 | MSP_REC_STATUS_MAX_CPU_TIME = 6, 59 | MSP_REC_STATUS_MAX_SPEECH = 7, 60 | MSP_REC_STATUS_STOPPED = 8, 61 | MSP_REC_STATUS_REJECTED = 9, 62 | MSP_REC_STATUS_NO_SPEECH_FOUND = 10, 63 | MSP_REC_STATUS_FAILURE = MSP_REC_STATUS_NO_MATCH, 64 | }; 65 | 66 | /** 67 | * The enumeration MSPepState contains the current endpointer state 68 | * MSP_EP_LOOKING_FOR_SPEECH - Have not yet found the beginning of speech 69 | * MSP_EP_IN_SPEECH - Have found the beginning, but not the end of speech 70 | * MSP_EP_AFTER_SPEECH - Have found the beginning and end of speech 71 | * MSP_EP_TIMEOUT - Have not found any audio till timeout 72 | * MSP_EP_ERROR - The endpointer has encountered a serious error 73 | * MSP_EP_MAX_SPEECH - Have arrive the max size of speech 74 | */ 75 | enum 76 | { 77 | MSP_EP_LOOKING_FOR_SPEECH = 0, 78 | MSP_EP_IN_SPEECH = 1, 79 | MSP_EP_AFTER_SPEECH = 3, 80 | MSP_EP_TIMEOUT = 4, 81 | MSP_EP_ERROR = 5, 82 | MSP_EP_MAX_SPEECH = 6, 83 | MSP_EP_IDLE = 7 // internal state after stop and before start 84 | }; 85 | 86 | /* Synthesizing process flags */ 87 | enum 88 | { 89 | MSP_TTS_FLAG_STILL_HAVE_DATA = 1, 90 | MSP_TTS_FLAG_DATA_END = 2, 91 | MSP_TTS_FLAG_CMD_CANCELED = 4, 92 | }; 93 | 94 | /* Handwriting process flags */ 95 | enum 96 | { 97 | MSP_HCR_DATA_FIRST = 1, 98 | MSP_HCR_DATA_CONTINUE = 2, 99 | MSP_HCR_DATA_END = 4, 100 | }; 101 | 102 | /*ivw message type */ 103 | enum 104 | { 105 | MSP_IVW_MSG_WAKEUP = 1, 106 | MSP_IVW_MSG_ERROR = 2, 107 | MSP_IVW_MSG_ISR_RESULT = 3, 108 | MSP_IVW_MSG_ISR_EPS = 4, 109 | MSP_IVW_MSG_VOLUME = 5, 110 | MSP_IVW_MSG_ENROLL = 6 111 | }; 112 | 113 | /* Upload data process flags */ 114 | enum 115 | { 116 | MSP_DATA_SAMPLE_INIT = 0x00, 117 | MSP_DATA_SAMPLE_FIRST = 0x01, 118 | MSP_DATA_SAMPLE_CONTINUE = 0x02, 119 | MSP_DATA_SAMPLE_LAST = 0x04, 120 | }; 121 | 122 | #endif /* __MSP_TYPES_H__ */ 123 | -------------------------------------------------------------------------------- /include/voice/qisr.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file qisr.h 3 | * @brief iFLY Speech Recognizer Header File 4 | * 5 | * This file contains the quick application programming interface (API) declarations 6 | * of ISR. Developer can include this file in your project to build applications. 7 | * For more information, please read the developer guide. 8 | 9 | * Use of this software is subject to certain restrictions and limitations set 10 | * forth in a license agreement entered into between iFLYTEK, Co,LTD. 11 | * and the licensee of this software. Please refer to the license 12 | * agreement for license use rights and restrictions. 13 | * 14 | * Copyright (C) 1999 - 2015 by iFLYTEK, Co,LTD. 15 | * All rights reserved. 16 | * 17 | * @author MSC 18 | * @version 5.0 19 | * @date 2015/03/19 20 | * 21 | * @see 22 | * 23 | * History:
24 | * 25 | * 26 | * 27 | *
Version Date Author Notes
5.0 2015/03/19 MSC Create this file
28 | */ 29 | 30 | #ifndef __QISR_H__ 31 | #define __QISR_H__ 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif /* C++ */ 36 | 37 | #include "msp_types.h" 38 | 39 | /** 40 | * @fn QISRSessionBegin 41 | * @brief Begin a Recognizer Session 42 | * 43 | * Create a recognizer session to recognize audio data 44 | * 45 | * @return return sessionID of current session, NULL is failed. 46 | * @param const char* grammarList - [in] grammars list, inline grammar support only one. 47 | * @param const char* params - [in] parameters when the session created. 48 | * @param int *errorCode - [out] return 0 on success, otherwise return error code. 49 | * @see 50 | */ 51 | const char* MSPAPI QISRSessionBegin(const char* grammarList, const char* params, int* errorCode); 52 | typedef const char* (MSPAPI *Proc_QISRSessionBegin)(const char* grammarList, const char* params, int *result); 53 | 54 | /** 55 | * @fn QISRAudioWrite 56 | * @brief Write Audio Data to Recognizer Session 57 | * 58 | * Writing binary audio data to recognizer. 59 | * 60 | * @return int MSPAPI - Return 0 in success, otherwise return error code. 61 | * @param const char* sessionID - [in] The session id returned by recog_begin 62 | * @param const void* waveData - [in] Binary data of waveform 63 | * @param unsigned int waveLen - [in] Waveform data size in bytes 64 | * @param int audioStatus - [in] Audio status, can be 65 | * @param int *epStatus - [out] ISRepState 66 | * @param int *recogStatus - [out] ISRrecRecognizerStatus, see isr_rec.h 67 | * @see 68 | */ 69 | int MSPAPI QISRAudioWrite(const char* sessionID, const void* waveData, unsigned int waveLen, int audioStatus, int *epStatus, int *recogStatus); 70 | typedef int (MSPAPI *Proc_QISRAudioWrite)(const char* sessionID, const void* waveData, unsigned int waveLen, int audioStatus, int *epStatus, int *recogStatus); 71 | 72 | /** 73 | * @fn QISRGetResult 74 | * @brief Get Recognize Result in Specified Format 75 | * 76 | * Get recognize result in Specified format. 77 | * 78 | * @return int MSPAPI - Return 0 in success, otherwise return error code. 79 | * @param const char* sessionID - [in] session id returned by session begin 80 | * @param int* rsltStatus - [out] status of recognition result, 0: success, 1: no match, 2: incomplete, 5:speech complete 81 | * @param int *errorCode - [out] return 0 on success, otherwise return error code. 82 | * @see 83 | */ 84 | const char * MSPAPI QISRGetResult(const char* sessionID, int* rsltStatus, int waitTime, int *errorCode); 85 | typedef const char * (MSPAPI *Proc_QISRGetResult)(const char* sessionID, int* rsltStatus, int waitTime, int *errorCode); 86 | 87 | /** 88 | * @fn QISRSessionEnd 89 | * @brief End a Recognizer Session 90 | * 91 | * End the recognizer session, release all resource. 92 | * 93 | * @return int MSPAPI - Return 0 in success, otherwise return error code. 94 | * @param const char* sessionID - [in] session id string to end 95 | * @param const char* hints - [in] user hints to end session, hints will be logged to CallLog 96 | * @see 97 | */ 98 | int MSPAPI QISRSessionEnd(const char* sessionID, const char* hints); 99 | typedef int (MSPAPI *Proc_QISRSessionEnd)(const char* sessionID, const char* hints); 100 | 101 | /** 102 | * @fn QISRGetParam 103 | * @brief get params related with msc 104 | * 105 | * the params could be local or server param, we only support netflow params "upflow" & "downflow" now 106 | * 107 | * @return int - Return 0 if success, otherwise return errcode. 108 | * @param const char* sessionID - [in] session id of related param, set NULL to got global param 109 | * @param const char* paramName - [in] param name,could pass more than one param split by ','';'or'\n' 110 | * @param const char* paramValue - [in] param value buffer, malloced by user 111 | * @param int *valueLen - [in, out] pass in length of value buffer, and return length of value string 112 | * @see 113 | */ 114 | int MSPAPI QISRGetParam(const char* sessionID, const char* paramName, char* paramValue, unsigned int* valueLen); 115 | typedef int (MSPAPI *Proc_QISRGetParam)(const char* sessionID, const char* paramName, char* paramValue, unsigned int* valueLen); 116 | 117 | /** 118 | * @fn QISRSetParam 119 | * @brief get params related with msc 120 | * 121 | * the params could be local or server param, we only support netflow params "upflow" & "downflow" now 122 | * 123 | * @return int - Return 0 if success, otherwise return errcode. 124 | * @param const char* sessionID - [in] session id of related param, set NULL to got global param 125 | * @param const char* paramName - [in] param name,could pass more than one param split by ','';'or'\n' 126 | * @param const char* paramValue - [in] param value buffer, malloced by user 127 | * @param int *valueLen - [in, out] pass in length of value buffer, and return length of value string 128 | * @see 129 | */ 130 | int MSPAPI QISRSetParam(const char* sessionID, const char* paramName, const char* paramValue); 131 | typedef int (MSPAPI *Proc_QISRSetParam)(const char* sessionID, const char* paramName, const char* paramValue); 132 | 133 | typedef void ( *recog_result_ntf_handler)( const char *sessionID, const char *result, int resultLen, int resultStatus, void *userData ); 134 | typedef void ( *recog_status_ntf_handler)( const char *sessionID, int type, int status, int param1, const void *param2, void *userData); 135 | typedef void ( *recog_error_ntf_handler)(const char *sessionID, int errorCode, const char *detail, void *userData); 136 | int MSPAPI QISRRegisterNotify(const char *sessionID, recog_result_ntf_handler rsltCb, recog_status_ntf_handler statusCb, recog_error_ntf_handler errCb, void *userData); 137 | 138 | typedef int ( *UserCallBack)( int, const char*, void*); 139 | typedef int ( *GrammarCallBack)( int, const char*, void*); 140 | typedef int ( *LexiconCallBack)( int, const char*, void*); 141 | 142 | int MSPAPI QISRBuildGrammar(const char *grammarType, const char *grammarContent, unsigned int grammarLength, const char *params, GrammarCallBack callback, void *userData); 143 | typedef int (MSPAPI *Proc_QISRBuildGrammar)(const char *grammarType, const char *grammarContent, unsigned int grammarLength, const char *params, GrammarCallBack callback, void *userData); 144 | 145 | int MSPAPI QISRUpdateLexicon(const char *lexiconName, const char *lexiconContent, unsigned int lexiconLength, const char *params, LexiconCallBack callback, void *userData); 146 | typedef int (MSPAPI *Proc_QISRUpdataLexicon)(const char *lexiconName, const char *lexiconContent, unsigned int lexiconLength, const char *params, LexiconCallBack callback, void *userData); 147 | #ifdef __cplusplus 148 | } /* extern "C" */ 149 | #endif /* C++ */ 150 | 151 | #endif /* __QISR_H__ */ 152 | -------------------------------------------------------------------------------- /include/voice/qtts.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file qtts.h 3 | * @brief iFLY Speech Synthesizer Header File 4 | * 5 | * This file contains the quick application programming interface (API) declarations 6 | * of TTS. Developer can include this file in your project to build applications. 7 | * For more information, please read the developer guide. 8 | 9 | * Use of this software is subject to certain restrictions and limitations set 10 | * forth in a license agreement entered into between iFLYTEK, Co,LTD. 11 | * and the licensee of this software. Please refer to the license 12 | * agreement for license use rights and restrictions. 13 | * 14 | * Copyright (C) 1999 - 2015 by iFLYTEK, Co,LTD. 15 | * All rights reserved. 16 | * 17 | * @author MSC 18 | * @version 5.0 19 | * @date 2015/03/19 20 | * 21 | * @see 22 | * 23 | * History:
24 | * 25 | * 26 | * 27 | *
Version Date Author Notes
5.0 2015/03/19 MSC Create this file
28 | */ 29 | #ifndef __QTTS_H__ 30 | #define __QTTS_H__ 31 | 32 | #if !defined(MSPAPI) 33 | #if defined(WIN32) 34 | #define MSPAPI __stdcall 35 | #else 36 | #define MSPAPI 37 | #endif /* WIN32 */ 38 | #endif /* MSPAPI */ 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif /* C++ */ 43 | 44 | #include "msp_types.h" 45 | 46 | /** 47 | * @fn QTTSSessionBegin 48 | * @brief Begin a TTS Session 49 | * 50 | * Create a tts session to synthesize data. 51 | * 52 | * @return const char* - Return the new session id in success, otherwise return NULL, error code. 53 | * @param const char* params - [in] parameters when the session created. 54 | * @param const char** sessionID - [out] return a string to this session. 55 | * @see 56 | */ 57 | const char* MSPAPI QTTSSessionBegin(const char* params, int* errorCode); 58 | typedef const char* (MSPAPI *Proc_QTTSSessionBegin)(const char* params, int* errorCode); 59 | 60 | /** 61 | * @fn QTTSTextPut 62 | * @brief Put Text Buffer to TTS Session 63 | * 64 | * Writing text string to synthesizer. 65 | * 66 | * @return int MSPAPI - Return 0 in success, otherwise return error code. 67 | * @param const char* sessionID - [in] The session id returned by sesson begin 68 | * @param const char* textString - [in] text buffer 69 | * @param unsigned int textLen - [in] text size in bytes 70 | * @see 71 | */ 72 | int MSPAPI QTTSTextPut(const char* sessionID, const char* textString, unsigned int textLen, const char* params); 73 | typedef int (MSPAPI *Proc_QTTSTextPut)(const char* sessionID, const char* textString, unsigned int textLen, const char* params); 74 | 75 | /** 76 | * @fn QTTSAudioGet 77 | * @brief Synthesize text to audio 78 | * 79 | * Synthesize text to audio, and return audio information. 80 | * 81 | * @return const void* - Return current synthesized audio data buffer, size returned by QTTSTextSynth. 82 | * @param const char* sessionID - [in] session id returned by session begin 83 | * @param unsigned int* audioLen - [out] synthesized audio size in bytes 84 | * @param int* synthStatus - [out] synthesizing status 85 | * @param int* errorCode - [out] error code if failed, 0 to success. 86 | * @see 87 | */ 88 | const void* MSPAPI QTTSAudioGet(const char* sessionID, unsigned int* audioLen, int* synthStatus, int* errorCode); 89 | typedef const void* (MSPAPI *Proc_QTTSAudioGet)(const char* sessionID, unsigned int* audioLen, int* synthStatus, int* errorCode); 90 | 91 | /** 92 | * @fn QTTSAudioInfo 93 | * @brief Get Synthesized Audio information 94 | * 95 | * Get synthesized audio data information. 96 | * 97 | * @return const char * - Return audio info string. 98 | * @param const char* sessionID - [in] session id returned by session begin 99 | * @see 100 | */ 101 | const char* MSPAPI QTTSAudioInfo(const char* sessionID); 102 | typedef const char* (MSPAPI *Proc_QTTSAudioInfo)(const char* sessionID); 103 | 104 | /** 105 | * @fn QTTSSessionEnd 106 | * @brief End a Recognizer Session 107 | * 108 | * End the recognizer session, release all resource. 109 | * 110 | * @return int MSPAPI - Return 0 in success, otherwise return error code. 111 | * @param const char* session_id - [in] session id string to end 112 | * @param const char* hints - [in] user hints to end session, hints will be logged to CallLog 113 | * @see 114 | */ 115 | int MSPAPI QTTSSessionEnd(const char* sessionID, const char* hints); 116 | typedef int (MSPAPI *Proc_QTTSSessionEnd)(const char* sessionID, const char* hints); 117 | 118 | /** 119 | * @fn QTTSGetParam 120 | * @brief get params related with msc 121 | * 122 | * the params could be local or server param, we only support netflow params "upflow" & "downflow" now 123 | * 124 | * @return int - Return 0 if success, otherwise return errcode. 125 | * @param const char* sessionID - [in] session id of related param, set NULL to got global param 126 | * @param const char* paramName - [in] param name,could pass more than one param split by ','';'or'\n' 127 | * @param const char* paramValue - [in] param value buffer, malloced by user 128 | * @param int *valueLen - [in, out] pass in length of value buffer, and return length of value string 129 | * @see 130 | */ 131 | int MSPAPI QTTSGetParam(const char* sessionID, const char* paramName, char* paramValue, unsigned int* valueLen); 132 | typedef int (MSPAPI *Proc_QTTSGetParam)(const char* sessionID, const char* paramName, char* paramValue, unsigned int* valueLen); 133 | 134 | /** 135 | * @fn QTTSSetParam 136 | * @brief set params related with msc 137 | * 138 | * the params could be local or server param, we only support netflow params "upflow" & "downflow" now 139 | * 140 | * @return int - Return 0 if success, otherwise return errcode. 141 | * @param const char* sessionID - [in] session id of related param, set NULL to got global param 142 | * @param const char* paramName - [in] param name,could pass more than one param split by ','';'or'\n' 143 | * @param const char* paramValue - [in] param value buffer, malloced by user 144 | * @see 145 | */ 146 | int MSPAPI QTTSSetParam(const char *sessionID, const char *paramName, const char *paramValue); 147 | typedef int (MSPAPI *Proc_QTTSSetParam)(const char* sessionID, const char* paramName, char* paramValue); 148 | 149 | typedef void ( *tts_result_ntf_handler)( const char *sessionID, const char *audio, int audioLen, int synthStatus, int ced, const char *audioInfo, int audioInfoLen, void *userData ); 150 | typedef void ( *tts_status_ntf_handler)( const char *sessionID, int type, int status, int param1, const void *param2, void *userData); 151 | typedef void ( *tts_error_ntf_handler)(const char *sessionID, int errorCode, const char *detail, void *userData); 152 | int MSPAPI QTTSRegisterNotify(const char *sessionID, tts_result_ntf_handler rsltCb, tts_status_ntf_handler statusCb, tts_error_ntf_handler errCb, void *userData); 153 | 154 | #ifdef __cplusplus 155 | } /* extern "C" */ 156 | #endif /* C++ */ 157 | 158 | #endif /* __QTTS_H__ */ 159 | -------------------------------------------------------------------------------- /include/voice/voice.h: -------------------------------------------------------------------------------- 1 |  2 | 3 | #ifndef __VOICE_H_ 4 | #define __VOICE_H_ 5 | 6 | #include 7 | #include 8 | #include 9 | /* 10 | *声音模块 11 | */ 12 | 13 | #define VOICE_PIN 4 //蜂鸣器阵脚 14 | #define VOICE_LIGHT_PIN 1 //语音控制指示灯,表示说话时灯亮,可以识别时灯灭 15 | #define VOICE_DETECT_PIN 0 //检测有无声音发出的阵脚, 此针脚引发一个中断 16 | #define RECORD_CMD_LEN 150 17 | #define TRUE 1 18 | #define FALSE 0 19 | //#define TEMPERATURE_WARNNING 333 //温度报警标识 20 | //#define HUMIDITY_WARNNING 334 //湿度报警标识 21 | //#define AIR_QUALITY_WARNNING 335 //空气质量报警标识 22 | 23 | //科大讯飞语音读写需要 24 | #define BUFFER_SIZE 4096 25 | #define FRAME_LEN 640 26 | #define HINTS_SIZE 100 27 | 28 | typedef struct { 29 | char open_record_voice_cmd[RECORD_CMD_LEN]; //保存录制音频的进程cmd 30 | int voice_main_switch; //声音总开关(超高) 31 | int recongnition_switch; //标识当前是否打开中断进行语音识别 (高) 32 | int recongnition_ongoing; //标识当前正在进行语音识别控制 (中) 33 | int sound_box_ongoing; //标识当前音箱正在说话,不允许录音(低) 34 | char voice_recongnition_cmd[BUFFER_SIZE]; //音频转换成文字后保存到这里 35 | //pthread_mutex_t mutex_sound_box; //音箱互斥锁,避免多线程发出乱七八糟的声音 36 | pid_t omxplayer_pid; //播放声音的进程号 37 | }Voice; 38 | 39 | /* 语音识别后智能回复的产生的wav文件:wav音频头部格式 */ 40 | typedef struct _wave_pcm_hdr 41 | { 42 | char riff[4]; // = "RIFF" 43 | int size_8; // = FileSize - 8 44 | char wave[4]; // = "WAVE" 45 | char fmt[4]; // = "fmt " 46 | int fmt_size; // = 下一个结构体的大小 : 16 47 | 48 | short int format_tag; // = PCM : 1 49 | short int channels; // = 通道数 : 1 50 | int samples_per_sec; // = 采样率 : 8000 | 6000 | 11025 | 16000 51 | int avg_bytes_per_sec; // = 每秒字节数 : samples_per_sec * bits_per_sample / 8 52 | short int block_align; // = 每采样点字节数 : wBitsPerSample / 8 53 | short int bits_per_sample; // = 量化比特数: 8 | 16 54 | 55 | char data[4]; // = "data"; 56 | int data_size; // = 纯数据长度 : FileSize - 44 57 | } wave_pcm_hdr; 58 | 59 | 60 | extern void voice_init(void); 61 | 62 | extern void open_voice(void); 63 | 64 | extern void close_voice(void); 65 | 66 | //extern void speech_front_hinder(void); 67 | 68 | //extern void speech_back_hinder(void); 69 | 70 | //extern void speech_hinder(void); 71 | 72 | //extern void speech_warnning(int, float); //播音警告 73 | 74 | //extern void speech_robot_condition(void); 75 | 76 | extern int open_voice_recognition_control(void); 77 | 78 | extern int close_voice_recongnition_control(void); 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /msc/c5055263abe6fbd16bfd416c72e48391/u.data: -------------------------------------------------------------------------------- 1 | d5728344342 -------------------------------------------------------------------------------- /msc/c5055263abe6fbd16bfd416c72e48391/urec.data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1158114251/-Intelligent-speech-robot/ebcd036427c8a50098deff50c93eebefa057adaa/msc/c5055263abe6fbd16bfd416c72e48391/urec.data -------------------------------------------------------------------------------- /msc/user.perf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1158114251/-Intelligent-speech-robot/ebcd036427c8a50098deff50c93eebefa057adaa/msc/user.perf -------------------------------------------------------------------------------- /obj/libmsc.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1158114251/-Intelligent-speech-robot/ebcd036427c8a50098deff50c93eebefa057adaa/obj/libmsc.so -------------------------------------------------------------------------------- /obj/libmsc.so1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1158114251/-Intelligent-speech-robot/ebcd036427c8a50098deff50c93eebefa057adaa/obj/libmsc.so1 -------------------------------------------------------------------------------- /obj/voice.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1158114251/-Intelligent-speech-robot/ebcd036427c8a50098deff50c93eebefa057adaa/obj/voice.o -------------------------------------------------------------------------------- /open_light.py: -------------------------------------------------------------------------------- 1 | # telnet program example 2 | import socket, select, string, sys 3 | import time 4 | import os 5 | def prompt() : 6 | print("333") 7 | sys.stdout.write(' ') 8 | sys.stdout.flush() 9 | 10 | #main function 11 | if __name__ == "__main__": 12 | 13 | # if(len(sys.argv) < 3) : 14 | # print ('Usage : python telnet.py hostname port') 15 | # sys.exit() 16 | 17 | host = "www.bigiot.net" 18 | port = 8181 19 | 20 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 21 | s.settimeout(2) 22 | 23 | # connect to remote host 24 | try : 25 | s.connect((host, port)) 26 | except : 27 | print ('Unable to connect') 28 | sys.exit() 29 | 30 | print ('Connected to remote host. Start sending messages') 31 | checkinBytes=bytes('{\"M\":\"checkin\",\"ID\":\"2068\",\"K\":\"7b0361f93\"}\n') 32 | s.sendall(checkinBytes) 33 | time.sleep(1) 34 | checkinBytes=bytes('{\"M\":\"say\",\"ID\":\"D2315\",\"C\":\"stop\"}\n') 35 | s.sendall(checkinBytes) 36 | time.sleep(1) 37 | # os.system("mplayer wav/open_light.mp3") 38 | prompt() 39 | s.close() 40 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #include "voice/voice.h" 5 | #include 6 | #include 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | if (wiringPiSetup() < 0) 11 | { 12 | printf("wiringPi init error!\n"); 13 | return -1; 14 | } 15 | voice_init(); 16 | 17 | open_voice_recognition_control(); 18 | while (1) 19 | { 20 | sleep(1); 21 | } 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /src/voice.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "voice/voice.h" 4 | #include "voice/qisr.h" 5 | #include "voice/qtts.h" 6 | #include "voice/msp_cmn.h" 7 | #include "voice/msp_errors.h" 8 | //#include "sys.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #define URL_SIZE 2048 18 | static Voice voice; 19 | 20 | /*功能:日志写入*/ 21 | static void show_sys_info(char *src) 22 | { 23 | printf("%s", src); 24 | /*在这里添加写入到日志文件的部分!*/ 25 | } 26 | 27 | /* 合成的wav声音文件:默认wav音频头部数据 */ 28 | static wave_pcm_hdr default_wav_hdr = 29 | { 30 | { 'R', 'I', 'F', 'F' }, 31 | 0, 32 | {'W', 'A', 'V', 'E'}, 33 | {'f', 'm', 't', ' '}, 34 | 16, 35 | 1, 36 | 1, 37 | 16000, 38 | 32000, 39 | 2, 40 | 16, 41 | {'d', 'a', 't', 'a'}, 42 | 0 43 | }; 44 | 45 | static void open_voice_light() 46 | { 47 | digitalWrite(VOICE_LIGHT_PIN, HIGH); 48 | } 49 | 50 | static void close_voice_light() 51 | { 52 | digitalWrite(VOICE_LIGHT_PIN, LOW); 53 | } 54 | 55 | static int get_omxplayer_stat() 56 | { 57 | if (!voice.sound_box_ongoing || (kill(voice.omxplayer_pid, 0) == -1) ) //当尚未第一次打开ffserver或者ffserver进程已经不存在 58 | { 59 | return -1; 60 | } 61 | else 62 | return 0; 63 | } 64 | 65 | static void kill_omxplayer() 66 | { 67 | if (get_omxplayer_stat() == 0) 68 | { 69 | if ((kill(voice.omxplayer_pid, SIGKILL)) == -1) 70 | { 71 | return ; //杀死ffserver进程失败 72 | } 73 | else 74 | { 75 | while (get_omxplayer_stat() == 0) //杀死成功,等待释放资源 76 | { 77 | usleep(100); 78 | } 79 | } 80 | return ; //成功杀死ffmpeg进程 81 | } 82 | } 83 | 84 | /* 85 | void speech_front_hinder() 86 | { 87 | //kill_omxplayer(); //关掉正在播放的语音 88 | voice.sound_box_ongoing = TRUE; //不允许录音 89 | pid_t omxplayer_pid; 90 | if ((omxplayer_pid = fork()) < 0) 91 | { 92 | voice.sound_box_ongoing = FALSE; 93 | show_sys_info("创建播放音频进程失败!\n"); 94 | return ; 95 | } 96 | else if (omxplayer_pid == 0) 97 | { 98 | show_sys_info("语音输出:正在说话...\n"); 99 | if (execlp("/bin/bash", "/bin/bash", "-c", "omxplayer --no-osd -o local /home/pi/0_robot_client/wav/sys_voice/front_hinder.wav", NULL) < 0) 100 | { 101 | printf("播放声音进程执行失败!\n"); 102 | } 103 | } 104 | wait(0); //等待播放进程结束 105 | voice.sound_box_ongoing = FALSE; 106 | } 107 | */ 108 | 109 | /* 110 | void speech_back_hinder() 111 | { 112 | //kill_omxplayer(); //关掉正在播放的语音 113 | voice.sound_box_ongoing = TRUE; //不允许录音 114 | pid_t omxplayer_pid; 115 | if ((omxplayer_pid = fork()) < 0) 116 | { 117 | voice.sound_box_ongoing = FALSE; 118 | show_sys_info("创建播放音频进程失败!\n"); 119 | return ; 120 | } 121 | else if (omxplayer_pid == 0) 122 | { 123 | show_sys_info("语音输出:正在说话...\n"); 124 | if (execlp("/bin/bash", "/bin/bash", "-c", "omxplayer --no-osd -o local /home/pi/0_robot_client/wav/sys_voice/back_hinder.wav", NULL) < 0) 125 | { 126 | printf("播放声音进程执行失败!\n"); 127 | } 128 | } 129 | wait(0); //等待播放进程结束 130 | voice.sound_box_ongoing = FALSE; 131 | 132 | } 133 | 134 | void speech_hinder() 135 | { 136 | //kill_omxplayer(); //关掉正在播放的语音 137 | voice.sound_box_ongoing = TRUE; //不允许录音 138 | pid_t omxplayer_pid; 139 | if ((omxplayer_pid = fork()) < 0) 140 | { 141 | voice.sound_box_ongoing = FALSE; 142 | show_sys_info("创建播放音频进程失败!\n"); 143 | return ; 144 | } 145 | else if (omxplayer_pid == 0) 146 | { 147 | show_sys_info("语音输出:正在说话...\n"); 148 | if (execlp("/bin/bash", "/bin/bash", "-c", "omxplayer --no-osd -o local /home/pi/0_robot_client/wav/sys_voice/hinder.wav", NULL) < 0) 149 | { 150 | printf("播放声音进程执行失败!\n"); 151 | } 152 | } 153 | wait(0); //等待播放进程结束 154 | voice.sound_box_ongoing = FALSE; 155 | } 156 | 157 | */ 158 | 159 | /* 160 | *功能:打开蜂鸣器模块 161 | */ 162 | void open_voice() 163 | { 164 | digitalWrite(VOICE_PIN, LOW); 165 | } 166 | 167 | /* 168 | *功能:关闭蜂鸣器模块 169 | */ 170 | void close_voice() 171 | { 172 | digitalWrite(VOICE_PIN, HIGH); 173 | } 174 | 175 | 176 | /*科大讯飞:上传声音关键字 */ 177 | static int upload_userwords() 178 | { 179 | char* userwords = NULL; 180 | unsigned int len = 0; 181 | unsigned int read_len = 0; 182 | FILE* fp = NULL; 183 | int ret = -1; 184 | 185 | fp = fopen("voice_key_words.txt", "rb"); 186 | if (NULL == fp) 187 | { 188 | show_sys_info("\nvoice_recognition Error: open [voice_key_words.txt] failed! \n"); 189 | goto upload_exit; 190 | } 191 | 192 | fseek(fp, 0, SEEK_END); 193 | len = ftell(fp); //获取音频文件大小 194 | fseek(fp, 0, SEEK_SET); 195 | 196 | userwords = (char*)malloc(len + 1); 197 | if (NULL == userwords) 198 | { 199 | show_sys_info("\nvoice_recognition Error: out of memory! \n"); 200 | goto upload_exit; 201 | } 202 | 203 | read_len = fread((void*)userwords, 1, len, fp); //读取用户词表内容 204 | if (read_len != len) 205 | { 206 | show_sys_info("\nvoice_recognition Error: read [userwords.txt] failed!\n"); 207 | goto upload_exit; 208 | } 209 | userwords[len] = '\0'; 210 | 211 | MSPUploadData("userwords", userwords, len, "sub = uup, dtt = userword", &ret); //上传用户词表 212 | if (MSP_SUCCESS != ret) 213 | { 214 | printf("\nMSPUploadData failed ! errorCode: %d \n", ret); 215 | goto upload_exit; 216 | } 217 | 218 | upload_exit: 219 | if (NULL != fp) 220 | { 221 | fclose(fp); 222 | fp = NULL; 223 | } 224 | if (NULL != userwords) 225 | { 226 | free(userwords); 227 | userwords = NULL; 228 | } 229 | 230 | return ret; 231 | } 232 | 233 | /* 234 | *功能:科大讯飞的识别模块(语音听写) 235 | *说明:将音频文件转换为文字 236 | */ 237 | static void run_iat(const char* audio_file, const char* session_begin_params, char *ret) 238 | { 239 | const char* session_id = NULL; 240 | char rec_result[BUFFER_SIZE]; 241 | memset(rec_result, 0, sizeof(rec_result)); 242 | char hints[HINTS_SIZE]; //hints为结束本次会话的原因描述,由用户自定义 243 | memset(hints, 0, sizeof(hints)); 244 | unsigned int total_len = 0; 245 | int aud_stat = MSP_AUDIO_SAMPLE_CONTINUE ; //音频状态 246 | int ep_stat = MSP_EP_LOOKING_FOR_SPEECH; //端点检测 247 | int rec_stat = MSP_REC_STATUS_SUCCESS ; //识别状态 248 | int errcode = MSP_SUCCESS; 249 | 250 | FILE* f_pcm = NULL; 251 | char* p_pcm = NULL; 252 | long pcm_count = 0; 253 | long pcm_size = 0; 254 | long read_size = 0; 255 | 256 | 257 | if (NULL == audio_file) 258 | goto iat_exit; 259 | 260 | f_pcm = fopen(audio_file, "rb"); 261 | if (NULL == f_pcm) 262 | { 263 | //!!!!日志信息打印函数未封装!下面的函数需要重写!!!! 264 | printf("\nvoice_recognition Error: open [%s] failed! \n", audio_file); 265 | goto iat_exit; 266 | } 267 | 268 | fseek(f_pcm, 0, SEEK_END); 269 | pcm_size = ftell(f_pcm); //获取音频文件大小 270 | fseek(f_pcm, 0, SEEK_SET); 271 | 272 | p_pcm = (char *)malloc(pcm_size); 273 | if (NULL == p_pcm) 274 | { 275 | show_sys_info("\nvoice_recognition Error: out of memory! \n"); 276 | goto iat_exit; 277 | } 278 | 279 | read_size = fread((void *)p_pcm, 1, pcm_size, f_pcm); //读取音频文件内容 280 | if (read_size != pcm_size) 281 | { 282 | //!!!!日志信息打印函数未封装!下面的函数需要重写!!!! 283 | printf("\nread [%s] error!\n", audio_file); 284 | goto iat_exit; 285 | } 286 | 287 | session_id = QISRSessionBegin(NULL, session_begin_params, &errcode); //听写不需要语法,第一个参数为NULL 288 | if (MSP_SUCCESS != errcode) 289 | { 290 | //!!!!日志信息打印函数未封装!下面的函数需要重写!!!! 291 | printf("\nQISRSessionBegin failed! error code:%d\n", errcode); 292 | goto iat_exit; 293 | } 294 | 295 | while (1) 296 | { 297 | unsigned int len = 10 * FRAME_LEN; // 每次写入200ms音频(16k,16bit):1帧音频20ms,10帧=200ms。16k采样率的16位音频,一帧的大小为640Byte 298 | int ret = 0; 299 | 300 | if (pcm_size < 2 * len) 301 | len = pcm_size; 302 | if (len <= 0) 303 | break; 304 | 305 | aud_stat = MSP_AUDIO_SAMPLE_CONTINUE; 306 | if (0 == pcm_count) 307 | aud_stat = MSP_AUDIO_SAMPLE_FIRST; 308 | 309 | ret = QISRAudioWrite(session_id, (const void *)&p_pcm[pcm_count], len, aud_stat, &ep_stat, &rec_stat); 310 | if (MSP_SUCCESS != ret) 311 | { 312 | //!!!!日志信息打印函数未封装!下面的函数需要重写!!!! 313 | printf("\nQISRAudioWrite failed! error code:%d\n", ret); 314 | goto iat_exit; 315 | } 316 | 317 | pcm_count += (long)len; 318 | pcm_size -= (long)len; 319 | 320 | if (MSP_REC_STATUS_SUCCESS == rec_stat) //已经有部分听写结果 321 | { 322 | const char *rslt = QISRGetResult(session_id, &rec_stat, 0, &errcode); 323 | if (MSP_SUCCESS != errcode) 324 | { 325 | //!!!!日志信息打印函数未封装!下面的函数需要重写!!!! 326 | printf("\nQISRGetResult failed! error code: %d\n", errcode); 327 | goto iat_exit; 328 | } 329 | if (NULL != rslt) 330 | { 331 | unsigned int rslt_len = strlen(rslt); 332 | total_len += rslt_len; 333 | if (total_len >= BUFFER_SIZE) 334 | { 335 | show_sys_info("\nvoice_recognition Error: no enough buffer for rec_result !\n"); 336 | goto iat_exit; 337 | } 338 | strncat(rec_result, rslt, rslt_len); 339 | } 340 | } 341 | 342 | if (MSP_EP_AFTER_SPEECH == ep_stat) 343 | break; 344 | usleep(200*1000); //模拟人说话时间间隙。200ms对应10帧的音频 345 | } 346 | errcode = QISRAudioWrite(session_id, NULL, 0, MSP_AUDIO_SAMPLE_LAST, &ep_stat, &rec_stat); 347 | if (MSP_SUCCESS != errcode) 348 | { 349 | //!!!!日志信息打印函数未封装!下面的函数需要重写!!!! 350 | printf("\nQISRAudioWrite failed! error code:%d \n", errcode); 351 | goto iat_exit; 352 | } 353 | 354 | while (MSP_REC_STATUS_COMPLETE != rec_stat) 355 | { 356 | const char *rslt = QISRGetResult(session_id, &rec_stat, 0, &errcode); 357 | if (MSP_SUCCESS != errcode) 358 | { 359 | //!!!!日志信息打印函数未封装!下面的函数需要重写!!!! 360 | printf("\nQISRGetResult failed, error code: %d\n", errcode); 361 | goto iat_exit; 362 | } 363 | if (NULL != rslt) 364 | { 365 | unsigned int rslt_len = strlen(rslt); 366 | total_len += rslt_len; 367 | if (total_len >= BUFFER_SIZE) 368 | { 369 | show_sys_info("\nno enough buffer for rec_result !\n"); 370 | goto iat_exit; 371 | } 372 | strncat(rec_result, rslt, rslt_len); 373 | } 374 | usleep(150*1000); //防止频繁占用CPU 375 | } 376 | strcpy(ret, rec_result); //将语音转换的结果转出 377 | 378 | iat_exit: 379 | if (NULL != f_pcm) 380 | { 381 | fclose(f_pcm); 382 | f_pcm = NULL; 383 | } 384 | if (NULL != p_pcm) 385 | { free(p_pcm); 386 | p_pcm = NULL; 387 | } 388 | 389 | QISRSessionEnd(session_id, hints); 390 | } 391 | 392 | /* 393 | *功能:科大讯飞,语音合成,将文本转换为声音 394 | *参数:src_text:文本 395 | * des_path:生成的wav文件路径,例如:/home/pi/0_robot_client/wav/compose_voice_temp/compose_voice.wav 396 | *返回值:见科大讯飞手册,失败返回-1 397 | *注意:我修改了一下,把参数放到这个函数里面了 398 | */ 399 | int text_to_speech(const char* src_text, const char* des_path) 400 | { 401 | const char* params = "voice_name = xiaoyan, text_encoding = UTF8, sample_rate = 16000, speed = 50, volume = 50, pitch = 50, rdn = 2"; 402 | 403 | int ret = -1; 404 | FILE* fp = NULL; 405 | const char* sessionID = NULL; 406 | unsigned int audio_len = 0; 407 | wave_pcm_hdr wav_hdr = default_wav_hdr; 408 | int synth_status = MSP_TTS_FLAG_STILL_HAVE_DATA; 409 | 410 | if (NULL == src_text || NULL == des_path) 411 | { 412 | printf("params is error!\n"); 413 | return ret; 414 | } 415 | fp = fopen(des_path, "wb"); 416 | if (NULL == fp) 417 | { 418 | printf("open %s error.\n", des_path); 419 | return ret; 420 | } 421 | /* 开始合成 */ 422 | sessionID = QTTSSessionBegin(params, &ret); 423 | if (MSP_SUCCESS != ret) 424 | { 425 | printf("QTTSSessionBegin failed, error code: %d.\n", ret); 426 | fclose(fp); 427 | return ret; 428 | } 429 | ret = QTTSTextPut(sessionID, src_text, (unsigned int)strlen(src_text), NULL); 430 | if (MSP_SUCCESS != ret) 431 | { 432 | printf("QTTSTextPut failed, error code: %d.\n",ret); 433 | QTTSSessionEnd(sessionID, "TextPutError"); 434 | fclose(fp); 435 | return ret; 436 | } 437 | fwrite(&wav_hdr, sizeof(wav_hdr) ,1, fp); //添加wav音频头,使用采样率为16000 438 | while (1) 439 | { 440 | /* 获取合成音频 */ 441 | const void* data = QTTSAudioGet(sessionID, &audio_len, &synth_status, &ret); 442 | if (MSP_SUCCESS != ret) 443 | break; 444 | if (NULL != data) 445 | { 446 | fwrite(data, audio_len, 1, fp); 447 | wav_hdr.data_size += audio_len; //计算data_size大小 448 | } 449 | if (MSP_TTS_FLAG_DATA_END == synth_status) 450 | break; 451 | usleep(150*1000); //防止频繁占用CPU 452 | }//合成状态synth_status取值请参阅《讯飞语音云API文档》 453 | 454 | if (MSP_SUCCESS != ret) 455 | { 456 | printf("QTTSAudioGet failed, error code: %d.\n",ret); 457 | QTTSSessionEnd(sessionID, "AudioGetError"); 458 | fclose(fp); 459 | return ret; 460 | } 461 | /* 修正wav文件头数据的大小 */ 462 | wav_hdr.size_8 += wav_hdr.data_size + (sizeof(wav_hdr) - 8); 463 | 464 | /* 将修正过的数据写回文件头部,音频文件为wav格式 */ 465 | fseek(fp, 4, 0); 466 | fwrite(&wav_hdr.size_8,sizeof(wav_hdr.size_8), 1, fp); //写入size_8的值 467 | fseek(fp, 40, 0); //将文件指针偏移到存储data_size值的位置 468 | fwrite(&wav_hdr.data_size,sizeof(wav_hdr.data_size), 1, fp); //写入data_size的值 469 | fclose(fp); 470 | fp = NULL; 471 | /* 合成完毕 */ 472 | ret = QTTSSessionEnd(sessionID, "Normal"); 473 | if (MSP_SUCCESS != ret) 474 | { 475 | printf("QTTSSessionEnd failed, error code: %d.\n",ret); 476 | } 477 | 478 | return ret; 479 | } 480 | 481 | /* 482 | * 功能:speech_robot_condition中的线程处理函数 483 | * 缺陷:科大讯飞那边有问题,好像不能直接转换太长的文字,估计是试用账号,有限制 484 | */ 485 | /* 486 | static char condition_text_part1[200]; 487 | static char condition_text_part2[200]; 488 | void* th_speech_robot_condition(void *arg) 489 | { 490 | show_sys_info("自身状态信息:"); 491 | show_sys_info(condition_text_part1); 492 | show_sys_info(condition_text_part2); 493 | show_sys_info("\n正在合成音频文件...\n"); 494 | 495 | //2、合成语音 496 | int ret = MSP_SUCCESS; 497 | ret = text_to_speech(condition_text_part1, "/home/pi/0_robot_client/wav/compose_voice_temp/speech_condition_temp_part1.wav"); 498 | if (MSP_SUCCESS != ret) 499 | { 500 | printf("语音合成:合成失败,无法输出语音!text_to_speech failed, error code: %d.\n", ret); 501 | return (void*)0; 502 | } 503 | 504 | ret = text_to_speech(condition_text_part2, "/home/pi/0_robot_client/wav/compose_voice_temp/speech_condition_temp_part2.wav"); 505 | if (MSP_SUCCESS != ret) 506 | { 507 | printf("语音合成:合成失败,无法输出语音!text_to_speech failed, error code: %d.\n", ret); 508 | return (void*)0; 509 | } 510 | 511 | show_sys_info("音频文件合成完毕,正在准备播放...\n"); 512 | 513 | //3、播放语音 514 | //kill_omxplayer(); //关掉正在播放的语音 515 | voice.sound_box_ongoing = TRUE; //不允许录音 516 | // 第一段语音 517 | pid_t omxplayer_pid; 518 | if ((omxplayer_pid = fork()) < 0) 519 | { 520 | voice.sound_box_ongoing = FALSE; 521 | show_sys_info("创建播放音频进程失败!\n"); 522 | return (void*)0; 523 | } 524 | else if (omxplayer_pid == 0) 525 | { 526 | show_sys_info("语音输出:正在说话...\n"); 527 | if (execlp("/bin/bash", "/bin/bash", "-c", "omxplayer --no-osd -o local /home/pi/0_robot_client/wav/compose_voice_temp/speech_condition_temp_part1.wav", NULL) < 0) 528 | { 529 | printf("播放声音进程执行失败!\n"); 530 | } 531 | } 532 | wait(0); 533 | voice.sound_box_ongoing = TRUE; //不允许录音 534 | if ((omxplayer_pid = fork()) < 0) 535 | { 536 | voice.sound_box_ongoing = FALSE; 537 | show_sys_info("创建播放音频进程失败!\n"); 538 | return (void*)0; 539 | } 540 | else if (omxplayer_pid == 0) 541 | { 542 | show_sys_info("语音输出:正在说话...\n"); 543 | if (execlp("/bin/bash", "/bin/bash", "-c", "omxplayer --no-osd -o local /home/pi/0_robot_client/wav/compose_voice_temp/speech_condition_temp_part2.wav", NULL) < 0) 544 | { 545 | printf("播放声音进程执行失败!\n"); 546 | } 547 | } 548 | 549 | wait(0); //等待播放进程结束 550 | voice.sound_box_ongoing = FALSE; 551 | 552 | return (void*)0; 553 | } 554 | */ 555 | 556 | /* 557 | * 功能:调用图灵机器人接口,发送Post请求,获取返回的智能回复消息 558 | * 参数:send_text:你说的话;recv_text:机器人回复的话放到recv_text中;code:保存recv_text的类型,具体看图灵机器人官网的API文档 559 | * recv_text_size:保存recv_text的空间大小;recv_code_size: 保存code空间的大小 560 | * 返回值:成功返回0, 失败返回-1 561 | * 说明:下面的图灵接口key值(key=44ee05352ba9459aaca3205c421f5e4c)是我自己账户的,每天智能回复的次数有限,请去图灵机器人官网获取更多支持 562 | */ 563 | static int smart_chat(char* send_text, char *recv_text, int recv_text_size, char *code, int recv_code_size) 564 | { 565 | /*步骤1:创建socket*/ 566 | int sockfd = socket(AF_INET, SOCK_STREAM, 0); 567 | if (sockfd < 0) 568 | { 569 | show_sys_info("智能聊天服务异常:socket创建失败!\n"); 570 | return -1; 571 | } 572 | 573 | //往serveraddr中填入ip、port和地址族类型(IPv4),为连接connect做准备 574 | struct sockaddr_in serveraddr; //专用地址结构体保存要连接的服务器的地址信息 575 | memset(&serveraddr, 0, sizeof(serveraddr)); //清零操作 576 | serveraddr.sin_family = AF_INET; //Internet地址族:IPv4 577 | serveraddr.sin_port = htons(80); //端口:第二个参数(转换为网络 578 | //字节序) 579 | 580 | //将IP地址转换为网络字节序 581 | inet_pton(AF_INET, "182.92.110.58", &serveraddr.sin_addr.s_addr); 582 | 583 | /*步骤2;客户端调用connect函数连接到服务器端,注意需要把专用地址强转为通用地址*/ 584 | if (connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0) 585 | { 586 | show_sys_info("智能聊天服务异常:connect() Error!\n"); 587 | return -1; 588 | } 589 | /*步骤3:调用I/O函数(read和write)和服务器端进行双向通信*/ 590 | 591 | int params_len = strlen("key=35ff2856b55e4a7f9eeb86e3437e23fe&info=") + strlen(send_text); 592 | 593 | char buff[1000]; //先暂且定义这么多,可能不够用,如果发送过来天气,新闻等数据的话 594 | memset(buff, 0, sizeof(buff)); 595 | snprintf(buff, sizeof(buff)-1, 596 | "POST /openapi/api HTTP/1.1\r\n" 597 | "Host: www.tuling123.com\r\n" 598 | "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n" 599 | "Content-Length: %d\r\n" 600 | "\r\n" 601 | "key=%s&info=%s", 602 | params_len, 603 | "35ff2856b55e4a7f9eeb86e3437e23fe", 604 | send_text 605 | ); 606 | 607 | if (write(sockfd, buff, strlen(buff)) != strlen(buff)) 608 | { 609 | return -1; //发送出错返回-1 610 | } 611 | memset(buff, 0, sizeof(buff)); 612 | size_t size; 613 | if ((size = read(sockfd, buff, sizeof(buff))) < 0)//从服务器端读取 614 | { 615 | return -1; 616 | } 617 | /*步骤4:关闭socket*/ 618 | close(sockfd); 619 | 620 | /* 621 | * 服务器返回的数据格式: 622 | *--------------------------------------------------------- 623 | * HTTP/1.1 200 OK 624 | * Server: nginx/1.10.1 625 | * Date: Thu, 16 Mar 2017 06:06:13 GMT 626 | * Content-Type: text/json; charset=UTF-8 627 | * Transfer-Encoding: chunked 628 | * Connection: keep-alive 629 | * Access-Control-Allow-Origin: * 630 | * 631 | * 4c 632 | * {"code":100000,"text":"我不会说英语的啦,你还是说中文吧。"} 633 | * 0 634 | * 635 | * 636 | *--------------------------------------------------------- 637 | *需要提取的内容为code和text冒号后面的内容 638 | *code和text的含义请去图灵官网查看,还有好多的类型。。。 639 | */ 640 | 641 | char *p = strstr(buff+150, "code"); //如果此时p不为null,则指向‘c’,从第150个开始查找,应该能提高速度吧~ 642 | if (p == NULL) 643 | { 644 | return -1; 645 | } 646 | p += 6; 647 | 648 | memset(code, 0, recv_code_size); 649 | int i = 0; 650 | while(*p != ',' && i < recv_code_size) 651 | { 652 | code[i] = *p; 653 | p++; 654 | i++; 655 | } 656 | p += 9; 657 | 658 | 659 | memset(recv_text, 0, recv_text_size); 660 | i = 0; 661 | while (*p != '"' && i < recv_text_size) 662 | { 663 | recv_text[i] = *p; 664 | p++; 665 | i++; 666 | } 667 | 668 | 669 | /*步骤5:将接受的数据显示出来*/ 670 | //printf("%s\n", buff); //服务器响应的数据 671 | //printf("code: %s\n", code); 672 | //printf("text: %s\n", recv_text); 673 | 674 | return 0; 675 | } 676 | 677 | 678 | /* 679 | *功能:中断处理函数,在这个函数中进行语音识别控制、智能聊天 680 | *说明: 681 | * 这个注册的中断处理函数会和main函数并发执行(同时执行,谁也不耽误谁) 682 | * 当本次中断函数还未执行完毕,这个时候树莓派又触发了一个中断,那么这个后来的中断不会被丢弃,它仍然可以被执行。 683 | * 但是wiringPi最多可以跟踪并记录后来的仅仅1个中断,如果不止1个,则他们会被忽略,得不到执行。 684 | */ 685 | int flag = 1; //这个voice.recongnition_ongoing标识好像不能关掉在中断处理函数过程中的另一个中断的发生. 686 | //所以,定义一个flag好了 687 | static void voice_recognition_control() 688 | { 689 | if (voice.voice_main_switch == FALSE) //语音识别未初始化成功,总开关未打开,直接退出! 690 | { 691 | usleep(100000); 692 | return ; 693 | } 694 | 695 | if (voice.recongnition_switch == FALSE) 696 | { 697 | //printf("中断未打开,无法开启语音识别!~\n"); 698 | usleep(100000); 699 | return ; //如果中断未打开,直接退出 700 | } 701 | if (!voice.recongnition_ongoing) 702 | { 703 | usleep(100000); 704 | return ; 705 | } 706 | if (voice.sound_box_ongoing) //如果当前音箱正在说话,不允许语音识别 707 | { 708 | usleep(100000); 709 | return ; 710 | } 711 | 712 | if (flag == 2) //如果当前是第二个中断,则标识下一个中断为第一个中断后退出 713 | { 714 | flag--; 715 | usleep(100000); 716 | return ; 717 | } 718 | flag++; //如果是第一个中断则标识下一个中断为第二个中断。 719 | voice.recongnition_ongoing = FALSE; 720 | /* 721 | * sub: 请求业务类型 722 | * domain: 领域 723 | * language: 语言 724 | * accent: 方言 725 | * sample_rate: 音频采样率 726 | * result_type: 识别结果格式 727 | * result_encoding: 结果编码格式 728 | * 729 | * 详细参数说明请参阅《iFlytek MSC Reference Manual》 730 | */ 731 | char* session_begin_params = "sub = iat, domain = iat, language = zh_ch, accent = mandarin, sample_rate = 16000, result_type = plain, result_encoding = utf8"; 732 | 733 | 734 | char voice_recongnition_cmd[BUFFER_SIZE]; 735 | pid_t arecord_pid; //录制音频进程标识 736 | 737 | memset(voice_recongnition_cmd, 0, sizeof(voice_recongnition_cmd)); 738 | if ((arecord_pid = fork()) < 0) 739 | { 740 | show_sys_info("创建录制音频进程失败!\n"); 741 | goto exit_; 742 | } 743 | else if (arecord_pid == 0) //子进程执行录制音频 744 | { 745 | //kill_omxplayer(); //关掉正在播放的语音 746 | open_voice_light(); //打开说话的灯,表示可以说话了 747 | show_sys_info("语音控制:正在录音,请说话...\n"); 748 | if (execlp("/bin/bash", "/bin/bash", "-c", "arecord -d 4 -r 16000 -c 1 -t wav -f S16_LE -D plughw:1,0 /home/pi/VoiceRecognitionControlRobot/wav/cmd_voice_temp/voice_cmd.wav", NULL) < 0) 749 | { 750 | show_sys_info("录制音频进程执行失败!\n"); 751 | } 752 | } 753 | else if (arecord_pid > 0) //父进程执行 754 | { 755 | wait(0); //等待子进程录制完毕! 756 | close_voice_light(); //不能说话了,表明此时正在进行识别! 757 | show_sys_info("语音控制:正在识别,请等待...\n"); 758 | //这个地方应该还要加上判断该文件是否存在的代码,以后再加~ 759 | run_iat("/home/pi/VoiceRecognitionControlRobot/wav/cmd_voice_temp/voice_cmd.wav", session_begin_params, voice_recongnition_cmd); 760 | if ((strlen(voice_recongnition_cmd)) <= 0) 761 | { 762 | show_sys_info("语音识别出错:您没有说话!\n"); 763 | goto exit_; 764 | } 765 | if (strstr(voice_recongnition_cmd, "开")) 766 | { 767 | show_sys_info("语音控制:正在开灯...\n"); 768 | system("python open_light.py&"); 769 | //这个地方添加控制函数 770 | system("mplayer wav/open_light.mp3"); 771 | } 772 | else if (strstr(voice_recongnition_cmd, "关")) 773 | { 774 | show_sys_info("语音控制:正在关灯...\n"); 775 | system("python close_light.py&"); 776 | system("mplayer wav/close_light.mp3"); 777 | 778 | //cam_turn_point(0, 0); 779 | //这个地方添加控制函数 780 | } 781 | else if (strstr(voice_recongnition_cmd, "舞")) 782 | { 783 | show_sys_info("语音控制:跳舞..."); 784 | //cam_turn_point(-90, 0); 785 | system("./a.out"); 786 | } 787 | else if (strstr(voice_recongnition_cmd, "抬头")) 788 | { 789 | show_sys_info("语音控制:抬头"); 790 | //cam_turn_point(0, -90); 791 | } 792 | else if (strstr(voice_recongnition_cmd, "低头")) 793 | { 794 | show_sys_info("语音控制:低头"); 795 | //cam_turn_point(0, 90); 796 | } 797 | else if (strstr(voice_recongnition_cmd, "前走")) 798 | { 799 | show_sys_info("语音控制:往【前】走...\n"); 800 | //voice_control_motion(VOICE_CONTROL_STRAIGHT); 801 | } 802 | else if (strstr(voice_recongnition_cmd, "后")) 803 | { 804 | show_sys_info("语音控制:往【后】走...\n"); 805 | //voice_control_motion(VOICE_CONTROL_BACK); 806 | } 807 | else if (strstr(voice_recongnition_cmd, "左转")) 808 | { 809 | show_sys_info("语音控制:往【左】走...\n"); 810 | //voice_control_motion(VOICE_CONTROL_LEFT); 811 | } 812 | else if (strstr(voice_recongnition_cmd, "左拐")) 813 | { 814 | show_sys_info("语音控制:往【左】走...\n"); 815 | //voice_control_motion(VOICE_CONTROL_LEFT); 816 | } 817 | else if (strstr(voice_recongnition_cmd, "右拐")) 818 | { 819 | show_sys_info("语音控制:往【右】走...\n"); 820 | //voice_control_motion(VOICE_CONTROL_RIGHT); 821 | } 822 | else if (strstr(voice_recongnition_cmd, "右转")) 823 | { 824 | show_sys_info("语音控制:往【右】走...\n"); 825 | //voice_control_motion(VOICE_CONTROL_RIGHT); 826 | } 827 | else if (strstr(voice_recongnition_cmd, "停")) 828 | { 829 | show_sys_info("语音控制:停止\n"); 830 | //voice_control_motion(VOICE_CONTROL_STOP); 831 | } 832 | else if (strstr(voice_recongnition_cmd, "开")) 833 | { 834 | show_sys_info("语音控制:开灯\n"); 835 | //open_cam_light(); 836 | } 837 | else if (strstr(voice_recongnition_cmd, "关")) 838 | { 839 | show_sys_info("语音控制:关灯\n"); 840 | //close_cam_light(); 841 | } 842 | else if (strstr(voice_recongnition_cmd, "状态") || strstr(voice_recongnition_cmd, "环境")) 843 | { 844 | show_sys_info("语音控制:播放当前机器人状态\n"); 845 | //speech_robot_condition(); 846 | } 847 | else 848 | { 849 | printf("你说了这些话:‘%s’, 不过这不能控制我哦,但我可以跟你讲话~\n", voice_recongnition_cmd); 850 | 851 | /* 852 | * 当听不懂控制指令的时候,进行语音输出,智能聊天 853 | */ 854 | 855 | //1、智能回复(仅文字) 856 | char recv_text[1024]; 857 | memset(recv_text, 0, sizeof(recv_text)); 858 | char recv_code[10]; 859 | memset(recv_code, 0, sizeof(recv_code)); 860 | if ((smart_chat(voice_recongnition_cmd, recv_text, sizeof(recv_text), recv_code, sizeof(recv_code))) < 0) 861 | { 862 | show_sys_info("智能回复错误:获取图灵机器人接口失败!\n"); 863 | goto exit_; 864 | } 865 | show_sys_info("智能聊天文字内容:"); show_sys_info(recv_text); show_sys_info("\n"); 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | //因为科大讯飞账号是试用版,长度应该有限制,把它分开播放 874 | // if (strlen(recv_text) < 1024) 875 | { 876 | //2、合成语音 877 | /* int ret = MSP_SUCCESS; 878 | ret = text_to_speech(recv_text, "/home/pi/VoiceRecognitionControlRobot/wav/compose_voice_temp/compose_voice_all.wav"); 879 | if (MSP_SUCCESS != ret) 880 | { 881 | printf("语音合成:合成失败,无法输出语音!text_to_speech failed, error code: %d.\n", ret); 882 | goto exit_; 883 | } 884 | */ 885 | //3、语音输出 886 | //system("omxplayer -o local /home/pi/0_robot_client/wav/compose_voice_temp/compose_voice.wav"); 887 | //kill_omxplayer(); 888 | voice.sound_box_ongoing = TRUE; 889 | pid_t omxplayer_pid; 890 | /* if ((omxplayer_pid = fork()) < 0) 891 | { 892 | voice.sound_box_ongoing = FALSE; 893 | show_sys_info("创建播放音频进程失败!\n"); 894 | goto exit_; 895 | } 896 | */ 897 | // else if (omxplayer_pid == 0) 898 | { 899 | 900 | //char * url =(char *)malloc(sizeof(char) * URL_SIZE ); 901 | char te[2048]={0}; 902 | char * url=te; 903 | 904 | sprintf(url,"mpg123 \"http://tsn.baidu.com/text2audio?tex=%s&lan=zh&per=0&pit=1&spd=7&cui\ 905 | d=7519663&ctp=1&tok=25.41bf315625c68b3e947c49b90788532d.315360000.179\ 906 | 8261651.282335-9120612\"",recv_text); 907 | 908 | //printf("%s",url); 909 | system(url); 910 | // free(url); 911 | show_sys_info("语音输出:正在说话...\n"); 912 | /* if (execlp("/bin/bash", "/bin/bash", "-c", "omxplayer --no-osd -o local /home/pi/VoiceRecognitionControlRobot/wav/compose_voice_temp/compose_voice_all.wav", NULL) < 0) 913 | { 914 | show_sys_info("播放声音进程执行失败!\n"); 915 | } 916 | */ 917 | } 918 | // wait(0); //等待播放进程结束 919 | voice.sound_box_ongoing = FALSE; 920 | 921 | } 922 | 923 | show_sys_info("语音聊天:一次语音聊天结束!\n"); 924 | } 925 | } 926 | exit_: show_sys_info("语音控制:一次语音识别结束!\n"); 927 | voice.recongnition_ongoing = TRUE; 928 | return ; 929 | } 930 | 931 | 932 | 933 | /* 934 | *功能:初始化语音模块 935 | */ 936 | void voice_init(void) 937 | { 938 | pinMode(VOICE_PIN, OUTPUT); 939 | digitalWrite(VOICE_PIN, HIGH); 940 | 941 | pinMode(VOICE_LIGHT_PIN, OUTPUT); 942 | digitalWrite(VOICE_LIGHT_PIN, LOW); 943 | 944 | memset(voice.open_record_voice_cmd, 0, sizeof(voice.open_record_voice_cmd)); 945 | memset(voice.voice_recongnition_cmd, 0, sizeof(voice.voice_recongnition_cmd)); 946 | voice.voice_main_switch = FALSE; 947 | voice.recongnition_ongoing = FALSE; 948 | voice.recongnition_switch = FALSE; 949 | voice.sound_box_ongoing = FALSE; 950 | //voice.omxplayer_pid = -1; 951 | wiringPiISR(VOICE_DETECT_PIN, INT_EDGE_FALLING, &voice_recognition_control); 952 | 953 | //if (mode == REMOTE_CONNECT_MODE) //可以联网的模式 954 | //{ 955 | int ret = MSP_SUCCESS; 956 | char* login_params = "appid = 56ee43d0, work_dir = ."; // 登录参数,appid与msc库绑定,请勿随意改动 957 | /* 用户登录 */ 958 | ret = MSPLogin(NULL, NULL, login_params); //第一个参数是用户名,第二个参数是密码,均传NULL即可,第三个参数是登录参数 959 | if (MSP_SUCCESS != ret) 960 | { 961 | printf("MSPLogin failed (科大讯飞账号登陆失败!) , Error code %d.\n", ret); 962 | show_sys_info("语音识别初始化失败!\n"); 963 | MSPLogout(); //退出登录 964 | return ; 965 | } 966 | 967 | int upload_on = 0; //是否上传用户词表,默认为关掉上传用户此表 968 | if (upload_on) 969 | { 970 | show_sys_info("voice_recongnition: 上传用户词表 ...\n"); 971 | ret = upload_userwords(); 972 | if (MSP_SUCCESS != ret) 973 | { 974 | MSPLogout(); //退出登录 975 | return ; 976 | } 977 | show_sys_info("voice_recongnition: 上传用户词表成功\n"); 978 | } 979 | voice.voice_main_switch = TRUE; 980 | show_sys_info("voice初始化:语音识别系统启动.\n"); 981 | //} 982 | //else 983 | //{ 984 | // show_sys_info("voice初始化:当前连接模式不支持语音识别!\n"); 985 | //} 986 | } 987 | 988 | 989 | /* 990 | *功能:线程处理函数,在线程中开启语音识别,降低延时 991 | *参数:无 992 | *返回值:无 993 | */ 994 | void* open_voice_recognition_control_th(void *arg) 995 | { 996 | //创建子进程输出语音提示“语音识别已经开启” 997 | //kill_omxplayer(); //关掉正在播放的语音 998 | voice.sound_box_ongoing = TRUE; 999 | pid_t omxplayer_pid; 1000 | if ((omxplayer_pid = fork()) < 0) 1001 | { 1002 | voice.sound_box_ongoing = FALSE; 1003 | show_sys_info("创建播放音频进程失败!\n"); 1004 | return (void*)0; 1005 | } 1006 | else if (omxplayer_pid == 0) //子进程执行录制音频 1007 | { 1008 | show_sys_info("语音输出:正在说话...\n"); 1009 | if (execlp("/bin/bash", "/bin/bash", "-c", "omxplayer --no-osd -o local /home/pi/VoiceRecognitionControlRobot/wav/sys_voice/opened_voice_recongnition.wav", NULL) < 0) 1010 | { 1011 | show_sys_info("播放声音进程执行失败!\n"); 1012 | } 1013 | } 1014 | wait(0); 1015 | 1016 | voice.sound_box_ongoing = FALSE; 1017 | voice.recongnition_ongoing = TRUE; //设置语音识别状态为正在进行 1018 | 1019 | show_sys_info("语音识别控制已经开启...\n"); 1020 | voice.recongnition_switch = TRUE; 1021 | 1022 | return (void*)0; 1023 | } 1024 | 1025 | 1026 | /* 1027 | *功能:开启语音识别控制 1028 | *返回值:成功返回0,失败返回-1 1029 | *说明:这个函数只是打开语音中断开关(recongnition_switch),打开后在检测到声音后才进行录音,识别。 1030 | */ 1031 | int open_voice_recognition_control() 1032 | { 1033 | if (voice.voice_main_switch == FALSE) //如果语音总开关没有打开,即语音初始化失败,禁止一切! 1034 | { 1035 | return 0; 1036 | } 1037 | if (voice.recongnition_switch) //如果语音中断中断开关已经打开,直接退出 1038 | { 1039 | return 0; 1040 | } 1041 | 1042 | //设置线程分离属性,以分离状态启动线程,在线程结束后会自动释放所占用的系统资源 1043 | pthread_attr_t attr; 1044 | pthread_attr_init(&attr); 1045 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 1046 | 1047 | pthread_t th; //线程标识符 1048 | int err; 1049 | if ((err = pthread_create(&th, &attr, open_voice_recognition_control_th, (void*)0)) != 0) 1050 | { 1051 | perror("servo_pulse_v_down pthread create error"); 1052 | } 1053 | pthread_attr_destroy(&attr); //销毁线程属性结构体 1054 | 1055 | } 1056 | 1057 | 1058 | /* 1059 | * 功能:线程处理函数,在线程中关闭语音识别,降低延时 1060 | * 参数:无 1061 | * 返回值:无 1062 | */ 1063 | void* close_voice_recongnition_control_th(void *arg) 1064 | { 1065 | if (voice.recongnition_switch == TRUE) 1066 | { 1067 | voice.recongnition_switch = FALSE; 1068 | close_voice_light(); 1069 | 1070 | //创建子进程输出语音提示“语音识别已经开启” 1071 | //kill_omxplayer(); //关掉正在播放的语音 1072 | voice.sound_box_ongoing = TRUE; 1073 | pid_t omxplayer_pid; 1074 | if ((omxplayer_pid = fork()) < 0) 1075 | { 1076 | voice.sound_box_ongoing = FALSE; 1077 | show_sys_info("创建播放音频进程失败!\n"); 1078 | show_sys_info("语音识别控制已经关闭...\n"); 1079 | return (void*)0; 1080 | } 1081 | else if (omxplayer_pid == 0) //子进程执行录制音频 1082 | { 1083 | show_sys_info("语音输出:正在说话...\n"); 1084 | if (execlp("/bin/bash", "/bin/bash", "-c", "omxplayer --no-osd -o local /home/pi/VoiceRecognitionControlRobot/wav/sys_voice/closed_voice_recongnition.wav", NULL) < 0) 1085 | { 1086 | show_sys_info("播放声音进程执行失败!\n"); 1087 | } 1088 | } 1089 | wait(0); 1090 | voice.sound_box_ongoing = FALSE; 1091 | show_sys_info("语音识别控制已经关闭...\n"); 1092 | return (void*)0; 1093 | } 1094 | 1095 | return (void*)0; 1096 | } 1097 | 1098 | /* 1099 | * 1100 | * 在关闭信号中使用该函数 1101 | */ 1102 | void sys_close_voice_recongnition_control() 1103 | { 1104 | if (voice.voice_main_switch == TRUE) 1105 | { 1106 | voice.recongnition_switch = FALSE; 1107 | voice.voice_main_switch = FALSE; 1108 | close_voice_light(); 1109 | MSPLogout(); //退出登录 1110 | 1111 | /* 1112 | //创建子进程输出语音提示“语音识别已经开启” 1113 | pid_t omxplayer_pid; 1114 | if ((omxplayer_pid = fork()) < 0) 1115 | { 1116 | show_sys_info("创建播放音频进程失败!\n"); 1117 | show_sys_info("语音识别控制已经关闭...\n"); 1118 | return ; 1119 | } 1120 | else if (omxplayer_pid == 0) //子进程执行录制音频 1121 | { 1122 | show_sys_info("语音输出:正在说话...\n"); 1123 | if (execlp("/bin/bash", "/bin/bash", "-c", "omxplayer --no-osd -o local /home/pi/0_robot_client/wav/sys_voice/closed_voice_recongnition.wav", NULL) < 0) 1124 | { 1125 | show_sys_info("播放声音进程执行失败!\n"); 1126 | } 1127 | } 1128 | wait(0); 1129 | show_sys_info("语音识别控制已经关闭...\n"); 1130 | */ 1131 | show_sys_info("语音功能已经关闭!\n"); 1132 | return ; 1133 | } 1134 | 1135 | return ; 1136 | } 1137 | 1138 | 1139 | /* 1140 | *功能:关闭语音识别控制 1141 | */ 1142 | int close_voice_recongnition_control() 1143 | { 1144 | if (voice.voice_main_switch == FALSE) //语音没有初始化成功,直接退出! 1145 | { 1146 | return 0; 1147 | } 1148 | 1149 | if (voice.recongnition_switch == FALSE) //语音中断开关已经关闭,直接退出! 1150 | { 1151 | return 0; 1152 | } 1153 | 1154 | sys_close_voice_recongnition_control(); //先在这里关闭吧,其实应该在信号中使用,因为sys.c文件还没移植过来,暂时放这里 1155 | /* 1156 | * 开启线程关闭语音识别 1157 | */ 1158 | 1159 | //设置线程分离属性,以分离状态启动线程,在线程结束后会自动释放所占用的系统资源 1160 | pthread_attr_t attr; 1161 | pthread_attr_init(&attr); 1162 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 1163 | 1164 | pthread_t th; //线程标识符 1165 | int err; 1166 | if ((err = pthread_create(&th, &attr, close_voice_recongnition_control_th, (void*)0)) != 0) 1167 | { 1168 | perror("servo_pulse_v_down pthread create error"); 1169 | } 1170 | pthread_attr_destroy(&attr); //销毁线程属性结构体 1171 | } 1172 | -------------------------------------------------------------------------------- /test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1158114251/-Intelligent-speech-robot/ebcd036427c8a50098deff50c93eebefa057adaa/test -------------------------------------------------------------------------------- /test.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1158114251/-Intelligent-speech-robot/ebcd036427c8a50098deff50c93eebefa057adaa/test.wav -------------------------------------------------------------------------------- /wav/close_light.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1158114251/-Intelligent-speech-robot/ebcd036427c8a50098deff50c93eebefa057adaa/wav/close_light.mp3 -------------------------------------------------------------------------------- /wav/cmd_voice_temp/voice_cmd.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1158114251/-Intelligent-speech-robot/ebcd036427c8a50098deff50c93eebefa057adaa/wav/cmd_voice_temp/voice_cmd.wav -------------------------------------------------------------------------------- /wav/compose_voice_temp/compose_voice.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1158114251/-Intelligent-speech-robot/ebcd036427c8a50098deff50c93eebefa057adaa/wav/compose_voice_temp/compose_voice.wav -------------------------------------------------------------------------------- /wav/compose_voice_temp/compose_voice_all.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1158114251/-Intelligent-speech-robot/ebcd036427c8a50098deff50c93eebefa057adaa/wav/compose_voice_temp/compose_voice_all.wav -------------------------------------------------------------------------------- /wav/open_light.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1158114251/-Intelligent-speech-robot/ebcd036427c8a50098deff50c93eebefa057adaa/wav/open_light.mp3 -------------------------------------------------------------------------------- /wav/sys_voice/closed_voice_recongnition.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1158114251/-Intelligent-speech-robot/ebcd036427c8a50098deff50c93eebefa057adaa/wav/sys_voice/closed_voice_recongnition.wav -------------------------------------------------------------------------------- /wav/sys_voice/opened_voice_recongnition.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1158114251/-Intelligent-speech-robot/ebcd036427c8a50098deff50c93eebefa057adaa/wav/sys_voice/opened_voice_recongnition.wav -------------------------------------------------------------------------------- /树莓派管脚.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1158114251/-Intelligent-speech-robot/ebcd036427c8a50098deff50c93eebefa057adaa/树莓派管脚.png -------------------------------------------------------------------------------- /流程图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1158114251/-Intelligent-speech-robot/ebcd036427c8a50098deff50c93eebefa057adaa/流程图.png -------------------------------------------------------------------------------- /目录.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1158114251/-Intelligent-speech-robot/ebcd036427c8a50098deff50c93eebefa057adaa/目录.png -------------------------------------------------------------------------------- /说明.txt: -------------------------------------------------------------------------------- 1 | 文件夹不要改名字,打开VoiceRecognitionControlRobot 输入如下命令编译 2 | 3 | gcc -o obj/voice.o -Iinclude -c src/voice.c 4 | 5 | gcc -o bin/test -Iinclude obj/libmsc.so obj/voice.o src/main.c -lpthread -lwiringPi -lrt -ldl -lpthread 6 | 7 | 8 | 运行 sudo ./bin/test 9 | 10 | 这个语音的识别触发是依靠树莓派的中断,百度搜索树莓派管脚图 ,当前文件夹有图片说明,这个管脚为高,开始识别 11 | 可以在这个管脚加一个声音检测模块 (淘宝有),每次说话,输出高电平 就会触发中断,开启录音。 12 | 13 | 14 | --------------------------------------------------------------------------------