<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>https://jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>https://jackxiang.com/post/7637/</link>
<title><![CDATA[手把手教你做树莓派语音识别，文本变语音。]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[WEB2.0]]></category>
<pubDate>Fri, 21 Nov 2014 02:42:34 +0000</pubDate> 
<guid>https://jackxiang.com/post/7637/</guid> 
<description>
<![CDATA[ 
	背景：想做智能硬件，语音识别成文字，再解析做相关操作是一个重要的点功能，国内就没有一个厂商像google一样提供一个web的协议进行翻译么？能不能更开放点，把这点能力给开放出来，毕竟如果哪家小公司去做这一块成本相当的高，有讯飞一家，还有没有更勇于开放的呢？呵呵,;webchat，只能在微信里用。<br/><br/><br/>前一段写了一个语音识别的帖子， 当时还不成熟<br/>现在比以前懂得多了一些， 跟大家来分享<br/><br/>所需设备： 带麦克风的usb摄像头，树莓派一个，互联网<br/>首先安装软件<br/>apt-get install arecord ffmpeg omxplayer<br/>语音识别大致分成3各部分，<br/><br/>第一步录音<br/>arecord -D &quot;plughw:1,0&quot; -d 5 file.wav<br/>解释一下 -D这个参数的意思就选择设备， 外部设备就是plughw:1,0&nbsp;&nbsp;内部设备就是plughw:0,0， 树莓派本身并没有录音模块，故没有内部设备。 -d 5 的意思就是录制时间为5秒， 如果不加这个参数就是一直录音直到ctrol+C停止， 最后生成的文件名字叫做file.wav<br/>检验方式， 我们戴上耳机听一下我们录制的声音 omxplayer -o local file.wav<br/>解释omxplayer是播放器， 无图形界面<br/>-o 是选择从哪里播放，是通过hdmi输出， 还是本地的耳机口放出来， 我们插得是树莓派自带的耳机口， 故选择local<br/>最后是跟上声音文件， 就能听到我们的录音了<br/><br/>第二步 转换格式<br/>我们打算上传到google做翻译， google只认flac格式， 所以我们要做转化， 把wav转换为flac格式<br/>ffmpeg -i file.wav -ar 16000 -acodec flac file.flac<br/>解释一下：-i 是指定输入的语音文件 -ar是指定波特率 为16000 -acodec是指定输出格式为flac, 最后接上输出文件的文件名即可， 当然是以flac为后缀的文件名， 最好是 file.flac<br/>检验方式， 我们戴上耳机听一下我们录制的声音 omxplayer -o local file.flac<br/>同样我们可以再次听到我们录制好的转过格式的声音文件<br/><br/>第三步上传网站获取翻译<br/>wget -q -U &quot;Mozilla/5.0&quot; --post-file file.flac --header &quot;Content-Type: audio/x-flac; rate=16000&quot; -O - &quot;[color=blue !important]http://www.google.com/speech-api/v1/recognize?lang=zh-cn&amp;client=chromium&quot;<br/>对于这句简单的解释下<br/>wget命令上传file.flac文件到google,并下载回对应的解释文件， 这个是中文的语音识别，如果是英文的语音识别改成en-us即可<br/><br/>最后预祝大家语音翻译玩的愉快<br/><br/>—————————————————————————google被墙，看下国内的—————————————————————————————<br/>树莓派之会说话的机器人-科大讯飞语音SDK ：<br/>本人一直想做一种可以和人对话的智能机器人，这样小孩子一定会非常的喜欢，树莓派的小巧和可任意扩展的Linux系统可以满足这种需求。<br/>首先是让梅莓派说话，也就是把一段文本转换成语音，然后再进行播放。方案有很多，也有很多的开源软件，考虑到之后还要做语音识别方面的功能，最终选择科大讯飞的语音SDK,虽然官方未公开提供树莓派版本的SDK,但通过咨询公司开发人员了，他们内部已经有了一个基于树莓派的Beta版本，然后就发给了我，顺便我也可以帮助进行测试，这里再次对科大讯飞表示感谢。<br/>讯飞官方提供了一个基本的测试代码，我在基础上做了一些修改，功能是：输入一段文本，指定发音人（普通话，粤语，儿童。。。），保存为.wav文件<br/>程序命令行是:&nbsp;&nbsp;&nbsp;&nbsp;./tts [text] [wave filename] [voice name]<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;示例：&nbsp;&nbsp; ./tts 你好 hello.wav xiaoyu<br/>好了，上代码:<br/><textarea name="code" class="c" rows="15" cols="100">
// ttsdemo.cpp : Defines the entry point for the console application.
//
#include 
#include 
#include 
#include 
#include &quot;qtts.h&quot;
#define TRUE 1
#define FALSE 0
typedef int SR_DWORD;
typedef short int SR_WORD ;
//音频头部格式
struct wave_pcm_hdr
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;riff[4];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// = &quot;RIFF&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SR_DWORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size_8;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // = FileSize - 8
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wave[4];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// = &quot;WAVE&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fmt[4];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // = &quot;fmt &quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SR_DWORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwFmtSize;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// = 下一个结构体的大小 : 16
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SR_WORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; format_tag;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// = PCM : 1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SR_WORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; channels;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // = 通道数 : 1
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SR_DWORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;samples_per_sec;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// = 采样率 : 8000 &#124; 6000 &#124; 11025 &#124; 16000
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SR_DWORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;avg_bytes_per_sec;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// = 每秒字节数 : dwSamplesPerSec * wBitsPerSample / 8
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SR_WORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; block_align;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// = 每采样点字节数 : wBitsPerSample / 8
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SR_WORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bits_per_sample;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// = 量化比特数: 8 &#124; 16
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data[4];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// = &quot;data&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SR_DWORD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data_size;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// = 纯数据长度 : FileSize - 44 
&#125; ;
//默认音频头部数据
struct wave_pcm_hdr default_pcmwavhdr = 
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123; &#039;R&#039;, &#039;I&#039;, &#039;F&#039;, &#039;F&#039; &#125;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;&#039;W&#039;, &#039;A&#039;, &#039;V&#039;, &#039;E&#039;&#125;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;&#039;f&#039;, &#039;m&#039;, &#039;t&#039;, &#039; &#039;&#125;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;16,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;16000,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;32000,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;16,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;&#039;d&#039;, &#039;a&#039;, &#039;t&#039;, &#039;a&#039;&#125;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;
&#125;;
int text_to_speech(const char* src_text ,const char* des_path ,const char* params)
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct wave_pcm_hdr pcmwavhdr = default_pcmwavhdr;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const char* sess_id = NULL;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int ret = 0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned int text_len = 0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char* audio_data;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsigned int audio_len = 0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int synth_status = MSP_TTS_FLAG_STILL_HAVE_DATA;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FILE* fp = NULL;
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;begin to synth...&#92;n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (NULL == src_text &#124;&#124; NULL == des_path)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;params is null!&#92;n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;text_len = (unsigned int)strlen(src_text);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fp = fopen(des_path,&quot;wb&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (NULL == fp)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;open file %s error&#92;n&quot;,des_path);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sess_id = QTTSSessionBegin(params, &amp;ret);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( ret != MSP_SUCCESS )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;QTTSSessionBegin: qtts begin session failed Error code %d.&#92;n&quot;,ret);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ret;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret = QTTSTextPut(sess_id, src_text, text_len, NULL );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( ret != MSP_SUCCESS )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;QTTSTextPut: qtts put text failed Error code %d.&#92;n&quot;,ret);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QTTSSessionEnd(sess_id, &quot;TextPutError&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ret;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fwrite(&amp;pcmwavhdr, 1, sizeof(pcmwavhdr), fp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while ( true )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;audio_data = (char*)QTTSAudioGet( sess_id ,&amp;audio_len , &amp;synth_status , &amp;ret );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( ret != MSP_SUCCESS )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;QTTSAudioGet: qtts get audio failed Error code %d.&#92;n&quot;,ret);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fwrite(audio_data, 1, audio_len, fp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pcmwavhdr.data_size += audio_len;//修正pcm数据的大小
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( MSP_TTS_FLAG_DATA_END == synth_status )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;QTTSAudioGet: get end of data.&#92;n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//修正pcm文件头数据的大小
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pcmwavhdr.size_8 += pcmwavhdr.data_size + 36;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//将修正过的数据写回文件头部
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fseek(fp, 4, 0);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fwrite(&amp;pcmwavhdr.size_8,sizeof(pcmwavhdr.size_8), 1, fp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fseek(fp, 40, 0);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fwrite(&amp;pcmwavhdr.data_size,sizeof(pcmwavhdr.data_size), 1, fp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fclose(fp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret = QTTSSessionEnd(sess_id, &quot;Normal&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( ret != MSP_SUCCESS )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;QTTSSessionEnd: qtts end failed Error code %d.&#92;n&quot;,ret);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ret;
&#125;
int main(int argc, char* argv[])
&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///APPID请勿随意改动
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const char* m_configs&nbsp;&nbsp;&nbsp;&nbsp;= &quot;appid=xxxxxx&quot;; // 你的appid
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const char* text&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = &quot;你好&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const char* filename&nbsp;&nbsp;&nbsp;&nbsp; = &quot;tts.wav&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const char* voice_name&nbsp;&nbsp; = &quot;xiaoyan&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const char* param_format = &quot;ssm=1,auf=audio/L16;rate=16000,vcn=%s,tte=UTF8&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char param[128];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int ret = 0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((argc == 2) &amp;&amp; ((strcmp(argv[1], &quot;--help&quot;) == 0) &#124;&#124; (strcmp(argv[1], &quot;-h&quot;) == 0)))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;USAGE:&nbsp;&nbsp; ./tts [text你好)] [wave filenametts.wav)] [voice namexiaoyan)] &#92;n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;Example: ./tts 你好 hello.wav xiaoyu&#92;n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;&#92;n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(argc &gt;= 2)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;text = argv[1];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(argc &gt;= 3)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filename = argv[2];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(argc &gt;= 4)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;voice_name = argv[3];
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memset(param, 0, sizeof(param));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sprintf(param, param_format, voice_name);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//引擎初始化
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret = QTTSInit(m_configs);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( ret != MSP_SUCCESS )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;QTTSInit: failed, Error code %d.&#92;n&quot;, ret);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ret;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//合成文本
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret = text_to_speech(text, filename, param);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( ret != MSP_SUCCESS )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;tts : failed.&#92;n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;tts : ok.&#92;n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//引擎关闭
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QTTSFini();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ret;
&#125;
</textarea><br/>编译命令行：<br/>g++ -D_DEBUG -D_GNU_SOURCE -w -pthread -pipe -ldl -lrt -Iinclude -fPIC -o tts tts.cpp msc.a<br/>这里要先说明一下，讯飞SDK要先从官方获得，并且申请你的appid.<br/>将文本转换成语音的程序就完成了，下面就是如何让树莓派播放这个.wav文件。<br/>大家都知道 树莓派声音有两种输出模式： HDMI和Analog模拟，因为我接了一个小音箱给树莓派，所以要选择Analog输出，这里就需要做一些配置:安装声卡服务:<br/>sudo apt-get install alsa-utils<br/>加载驱动:<br/>sudo modprobe snd_bcm2835<br/>设置Analog输出模式:<br/>sudo amixer cset numid=3 1<br/>插上小音箱，然后进行测试（aplay是音频播放的程序，如果缺省没有就使用apt-get instal安装吧）:<br/>sudo aplay test.wav<br/>正常情况下音箱发出声音了。<br/>最后把两个命令连接在一起，接收一段文本然后立马播放(主要是通过外部的程序发送命令，比如HTTP GET/POST, SSH, ...)：<br/>sudo ./tts&nbsp;&nbsp;&quot;说话的文本&quot; tmp.wav vinn &amp;&amp; aplay tmp.wav<br/>本文完，欢迎讨论。<br/>DownLoad: http://www.52pi.net/forum.php?mod=attachment&amp;aid=ODYxfGI0M2FiNTIwfDE0MTY1MzgyODB8MHw2Njg%3D<br/><br/>http://www.52pi.net/portal.php?mod=view&amp;aid=12<br/><br/>科大讯飞：http://www.xue5.com/Mobile/Mobile/604186.html<br/>文字变语音：<br/>http://shumeipai.nxez.com/2013/10/05/three-methods-developed-in-text-to-voice-services.html?variant=zh-cn<br/>Flash 实现 的：http://bbs.9ria.com/thread-175431-1-1.html<br/>webchat来自：<br/>http://blog.social-touch.com/2014/06/%E7%8E%A9%E8%BD%AC%E5%BE%AE%E4%BF%A1%E8%90%A5%E9%94%80%EF%BC%9A%E8%AF%A6%E8%A7%A3%E8%AF%AD%E9%9F%B3%E8%AF%86%E5%88%AB%E6%8E%A5%E5%8F%A3%E3%80%81oauth2-0%E7%BD%91%E9%A1%B5%E6%8E%A5%E5%8F%A3/
]]>
</description>
</item><item>
<link>https://jackxiang.com/post/7637/#blogcomment63967</link>
<title><![CDATA[[评论] 手把手教你做树莓派语音识别，文本变语音。]]></title> 
<author>tets &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Fri, 24 Apr 2015 05:45:28 +0000</pubDate> 
<guid>https://jackxiang.com/post/7637/#blogcomment63967</guid> 
<description>
<![CDATA[ 
	讯飞貌似有web解析协议，貌似还有h5，就看讯飞愿不愿意给你用了
]]>
</description>
</item><item>
<link>https://jackxiang.com/post/7637/#blogcomment63988</link>
<title><![CDATA[[评论] 手把手教你做树莓派语音识别，文本变语音。]]></title> 
<author>ffxxi &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Sun, 31 Jul 2016 23:01:49 +0000</pubDate> 
<guid>https://jackxiang.com/post/7637/#blogcomment63988</guid> 
<description>
<![CDATA[ 
	楼主 能留个联系方式不。。。。。有问题想问问吖0.0
]]>
</description>
</item>
</channel>
</rss>